Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

933 lines
26 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_MCSNC);
  3. /*
  4. * omcscode.cpp
  5. *
  6. * Copyright (c) 1993 - 1996 by DataBeam Corporation, Lexington, KY
  7. *
  8. * Abstract:
  9. * This is the implementation file for the CMCSCoder class. This class
  10. * is responsible for encoding and decoding T.125 PDU's using ASN.1
  11. * encoding rules via the ASN.1 toolkit. This class is also capable
  12. * of determining the size of both the encoded and decoded PDU's and is
  13. * capable of making copies of each of the PDU's.
  14. *
  15. * Private Instance Variables:
  16. * Encoding_Rules_Type
  17. * This variable holds the type of encoding rules which are currently
  18. * being utilized.
  19. *
  20. * Private Member Functions:
  21. *
  22. * Copy***
  23. * Private member functions exist which are capable of making complete
  24. * copies of the decoded "Send Data" PDU data structures. These
  25. * routines copy not only the data contained within the structure but
  26. * also any data which is referenced by the pointers held within the
  27. * structure.
  28. *
  29. * SetEncodingRules
  30. * This routine is used to switch between using Basic Encoding Rules
  31. * (BER) and Packed Encoding Rules (PER). This routine also updates
  32. * the private instance variables used to hold values for the minimum
  33. * and maximum amount of overhead associated with the "send data" PDUs.
  34. *
  35. * Caveats:
  36. * None.
  37. *
  38. * Author:
  39. * John B. O'Nan
  40. */
  41. #include "omcscode.h"
  42. /*
  43. * Macros.
  44. */
  45. #define BOOLEAN_TAG 0x01
  46. #define INTEGER_TAG 0x02
  47. #define BIT_STRING_TAG 0x03
  48. #define OCTET_STRING_TAG 0x04
  49. #define ENUMERATED_TAG 0x0a
  50. #define SEQUENCE 0x30
  51. #define SETOF 0x31
  52. #define INDEFINITE_LENGTH 0x80
  53. #define ONE_BYTE_LENGTH 0x81
  54. #define TWO_BYTE_LENGTH 0x82
  55. #define THREE_BYTE_LENGTH 0x83
  56. #define FOUR_BYTE_LENGTH 0x84
  57. #define END_OF_CONTENTS 0x00
  58. #define CONSTRUCTED_TAG_ZERO 0xa0
  59. #define CONSTRUCTED_TAG_ONE 0xa1
  60. #define CONSTRUCTED_TAG_TWO 0xa2
  61. #define CONSTRUCTED_TAG_THREE 0xa3
  62. #define CONSTRUCTED_TAG_FOUR 0xa4
  63. /*
  64. * This is a global variable that has a pointer to the one MCS coder that
  65. * is instantiated by the MCS Controller. Most objects know in advance
  66. * whether they need to use the MCS or the GCC coder, so, they do not need
  67. * this pointer in their constructors.
  68. */
  69. CMCSCoder *g_MCSCoder;
  70. /*
  71. * The following array contains a template for the X.224 data header.
  72. * The 5 of the 7 bytes that it initializes are actually sent to the
  73. * wire. Bytes 3 and 4 will be set to contain the size of the PDU.
  74. * The array is only used when we encode a data PDU.
  75. */
  76. UChar g_X224Header[] = { 3, 0, 0, 0, 2, DATA_PACKET, EOT_BIT };
  77. /*
  78. * CMCSCoder ()
  79. *
  80. * Public
  81. *
  82. * Functional Description:
  83. * This is the constructor for the CMCSCoder class. It initializes
  84. * the ASN.1 encoder/decoder, saves the current encoding rules type,
  85. * and sets values for the highest and lowest overhead in the "send data"
  86. * PDU's.
  87. */
  88. CMCSCoder::CMCSCoder ()
  89. :m_pEncInfo(NULL),
  90. m_pDecInfo(NULL)
  91. {
  92. Encoding_Rules_Type = BASIC_ENCODING_RULES;
  93. // lonchanc: We should move Init out of constructor. However,
  94. // to minimize the changes in the GCC/MCS code, we put it here for now.
  95. // Otherwise, we need to change MCS and Packet interfaces.
  96. // We will move it out and call Init() separately.
  97. Init();
  98. }
  99. BOOL CMCSCoder::Init ( void )
  100. {
  101. BOOL fRet = FALSE;
  102. MCSPDU_Module_Startup();
  103. if (MCSPDU_Module != NULL)
  104. {
  105. if (ASN1_CreateEncoder(
  106. MCSPDU_Module, // ptr to mdule
  107. &m_pEncInfo, // ptr to encoder info
  108. NULL, // buffer ptr
  109. 0, // buffer size
  110. NULL) // parent ptr
  111. == ASN1_SUCCESS)
  112. {
  113. ASSERT(m_pEncInfo != NULL);
  114. m_pEncInfo->cbExtraHeader = PROTOCOL_OVERHEAD_X224;
  115. fRet = (ASN1_CreateDecoder(
  116. MCSPDU_Module, // ptr to mdule
  117. &m_pDecInfo, // ptr to decoder info
  118. NULL, // buffer ptr
  119. 0, // buffer size
  120. NULL) // parent ptr
  121. == ASN1_SUCCESS);
  122. ASSERT(fRet && m_pDecInfo != NULL);
  123. }
  124. }
  125. ASSERT(fRet);
  126. return fRet;
  127. }
  128. /*
  129. * ~CMCSCoder ()
  130. *
  131. * Public
  132. *
  133. * Functional Description:
  134. * This is a virtual destructor. It is used to clean up after ASN.1.
  135. */
  136. CMCSCoder::~CMCSCoder ()
  137. {
  138. if (MCSPDU_Module != NULL)
  139. {
  140. ASN1_CloseEncoder(m_pEncInfo);
  141. ASN1_CloseDecoder(m_pDecInfo);
  142. MCSPDU_Module_Cleanup();
  143. }
  144. }
  145. /*
  146. * void Encode ()
  147. *
  148. * Public
  149. *
  150. * Functional Description:
  151. * This function encodes MCS protocol data units (PDU's) into ASN.1
  152. * compliant byte streams using the ASN.1 toolkit.
  153. * The encode happens in a coder-allocated buffer.
  154. */
  155. BOOL CMCSCoder::Encode(LPVOID pdu_structure,
  156. int pdu_type,
  157. UINT rules_type,
  158. LPBYTE *encoding_buffer,
  159. UINT *encoding_buffer_length)
  160. {
  161. BOOL fRet = TRUE;
  162. BOOL send_data_pdu = FALSE;
  163. int return_value;
  164. //UINT encoding_length;
  165. UShort initiator;
  166. LPBYTE buffer_pointer;
  167. PSendDataRequestPDU send_data;
  168. UINT PDUChoice;
  169. BOOL bBufferAllocated;
  170. PMemory memory;
  171. /*
  172. * Check to make sure the encoding rules type is properly set.
  173. */
  174. ASSERT(rules_type == PACKED_ENCODING_RULES || pdu_type == CONNECT_MCS_PDU);
  175. if (pdu_type == DOMAIN_MCS_PDU)
  176. {
  177. /*
  178. * Set PDUChoice to the type of MCS PDU we need to encode.
  179. * Also, determine if this is a data PDU.
  180. */
  181. PDUChoice = (unsigned int) ((PDomainMCSPDU) pdu_structure)->choice;
  182. if ((PDUChoice == SEND_DATA_REQUEST_CHOSEN) ||
  183. (PDUChoice == SEND_DATA_INDICATION_CHOSEN) ||
  184. (PDUChoice == UNIFORM_SEND_DATA_REQUEST_CHOSEN) ||
  185. (PDUChoice == UNIFORM_SEND_DATA_INDICATION_CHOSEN)) {
  186. send_data_pdu = TRUE;
  187. send_data = &((PDomainMCSPDU) pdu_structure)->u.send_data_request;
  188. bBufferAllocated = (*encoding_buffer == NULL);
  189. if (bBufferAllocated) {
  190. // We have to allocate the encoded buffer.
  191. DBG_SAVE_FILE_LINE
  192. memory = AllocateMemory (NULL,
  193. send_data->user_data.length + MAXIMUM_PROTOCOL_OVERHEAD,
  194. SEND_PRIORITY);
  195. if (memory != NULL) {
  196. buffer_pointer = *encoding_buffer = (LPBYTE) memory->GetPointer();
  197. }
  198. else {
  199. WARNING_OUT (("CMCSCoder::Encode: Failed to allocate space for "
  200. "encoded data PDU for send."));
  201. fRet = FALSE;
  202. ASSERT (*encoding_buffer == NULL);
  203. goto MyExit;
  204. }
  205. }
  206. else {
  207. // All the space needed here has been pre-allocated
  208. buffer_pointer = *encoding_buffer;
  209. }
  210. }
  211. /*
  212. * Check if this is a data PDU
  213. */
  214. if (send_data_pdu)
  215. {
  216. #ifdef ENABLE_BER
  217. /*
  218. * If we are currently using Basic Encoding Rules.
  219. */
  220. if (Encoding_Rules_Type == BASIC_ENCODING_RULES)
  221. {
  222. /*
  223. * The long variant of length must be used if the octet string
  224. * is longer than 127 bytes. The upper bit of the length byte
  225. * is set and the lower bits indicate the number of length bytes
  226. * which will follow.
  227. */
  228. *(buffer_pointer--) = (UChar)send_data->user_data.length;
  229. if (send_data->user_data.length > 127)
  230. {
  231. *(buffer_pointer--) = (UChar)(send_data->user_data.length >> 8);
  232. *(buffer_pointer--) = TWO_BYTE_LENGTH;
  233. encoding_length = 3;
  234. }
  235. else
  236. {
  237. encoding_length = 1;
  238. }
  239. /*
  240. * Encode the "user data" octet string.
  241. */
  242. *(buffer_pointer--) = OCTET_STRING_TAG;
  243. /*
  244. * Encode the "segmentation" bit string field. The identifier
  245. * is followed by a length of 2 and a byte indicating that 6
  246. * bits are unused in the actual bit string byte.
  247. */
  248. *(buffer_pointer--) = (UChar) send_data->segmentation;
  249. *(buffer_pointer--) = 0x06;
  250. *(buffer_pointer--) = 0x02;
  251. *(buffer_pointer--) = BIT_STRING_TAG;
  252. /*
  253. * Encode the enumerated "data priority" field.
  254. */
  255. *(buffer_pointer--) = (UChar)send_data->data_priority;
  256. *(buffer_pointer--) = 0x01;
  257. *(buffer_pointer--) = ENUMERATED_TAG;
  258. /*
  259. * Encode the integer "channel ID" field.
  260. */
  261. *(buffer_pointer--) = (UChar)send_data->channel_id;
  262. if (send_data->channel_id < 128)
  263. {
  264. *(buffer_pointer--) = 0x01;
  265. encoding_length += 10;
  266. }
  267. else if (send_data->channel_id < 32768L)
  268. {
  269. *(buffer_pointer--) = (UChar)(send_data->channel_id >> 8);
  270. *(buffer_pointer--) = 0x02;
  271. encoding_length += 11;
  272. }
  273. else
  274. {
  275. *(buffer_pointer--) = (UChar)(send_data->channel_id >> 8);
  276. *(buffer_pointer--) = (UChar)(send_data->channel_id >> 16);
  277. *(buffer_pointer--) = 0x03;
  278. encoding_length += 12;
  279. }
  280. *(buffer_pointer--) = INTEGER_TAG;
  281. /*
  282. * Encode the integer "initiator" field.
  283. */
  284. *(buffer_pointer--) = (UChar)send_data->initiator;
  285. *(buffer_pointer--) = (UChar)(send_data->initiator >> 8);
  286. if (send_data->initiator < 32768L)
  287. {
  288. *(buffer_pointer--) = 0x02;
  289. encoding_length += 4;
  290. }
  291. else
  292. {
  293. *(buffer_pointer--) = (UChar)(send_data->initiator >> 16);
  294. *(buffer_pointer--) = 0x03;
  295. encoding_length += 5;
  296. }
  297. *(buffer_pointer--) = INTEGER_TAG;
  298. *(buffer_pointer--) = INDEFINITE_LENGTH;
  299. switch (PDUChoice)
  300. {
  301. case SEND_DATA_REQUEST_CHOSEN:
  302. *buffer_pointer = SEND_DATA_REQUEST;
  303. break;
  304. case SEND_DATA_INDICATION_CHOSEN:
  305. *buffer_pointer = SEND_DATA_INDICATION;
  306. break;
  307. case UNIFORM_SEND_DATA_REQUEST_CHOSEN:
  308. *buffer_pointer = UNIFORM_SEND_DATA_REQUEST;
  309. break;
  310. case UNIFORM_SEND_DATA_INDICATION_CHOSEN:
  311. *buffer_pointer = UNIFORM_SEND_DATA_INDICATION;
  312. break;
  313. }
  314. // Set the returned pointer to the beginning of the encoded packet
  315. PUChar temp = *encoding_buffer;
  316. *encoding_buffer = buffer_pointer;
  317. /*
  318. * Encode the end-of-contents marker for the "Send Data" PDU.
  319. * This goes after the data, at the end of the PDU.
  320. */
  321. buffer_pointer = temp + (send_data->user_data.length +
  322. (MAXIMUM_PROTOCOL_OVERHEAD_FRONT + 1));
  323. *(buffer_pointer++) = END_OF_CONTENTS;
  324. *buffer_pointer = END_OF_CONTENTS;
  325. // Set the returned length of the encoded packet
  326. *encoding_buffer_length =
  327. encoding_length + send_data->user_data.length + 5;
  328. }
  329. /*
  330. * If we are currently using Packed Encoding Rules.
  331. */
  332. else
  333. #endif // ENABLE_BER
  334. {
  335. // Move the ptr past the X.224 header.
  336. buffer_pointer += sizeof(X224_DATA_PACKET);
  337. switch (PDUChoice)
  338. {
  339. case SEND_DATA_REQUEST_CHOSEN:
  340. *buffer_pointer = PER_SEND_DATA_REQUEST;
  341. break;
  342. case SEND_DATA_INDICATION_CHOSEN:
  343. *buffer_pointer = PER_SEND_DATA_INDICATION;
  344. break;
  345. case UNIFORM_SEND_DATA_REQUEST_CHOSEN:
  346. *buffer_pointer = PER_UNIFORM_SEND_DATA_REQUEST;
  347. break;
  348. case UNIFORM_SEND_DATA_INDICATION_CHOSEN:
  349. *buffer_pointer = PER_UNIFORM_SEND_DATA_INDICATION;
  350. break;
  351. }
  352. buffer_pointer++;
  353. /*
  354. * Encode the integer "initiator" field. The lower bound must
  355. * first be subtracted from the value to encode.
  356. */
  357. initiator = send_data->initiator - INITIATOR_LOWER_BOUND;
  358. *(buffer_pointer++) = (UChar) (initiator >> 8);
  359. *(buffer_pointer++) = (UChar) initiator;
  360. /*
  361. * Encode the integer "channel ID" field.
  362. */
  363. *(buffer_pointer++) = (UChar)(send_data->channel_id >> 8);
  364. *(buffer_pointer++) = (UChar)(send_data->channel_id);
  365. /*
  366. * Encode the "priority" and "segmentation" fields.
  367. */
  368. *(buffer_pointer++) = (UChar)((send_data->data_priority << 6) |
  369. (send_data->segmentation >> 2));
  370. /*
  371. * Encode the "user data" octet string. The octet strings are
  372. * encoded differently depending upon their length.
  373. */
  374. ASSERT (send_data->user_data.length < 16384);
  375. if (send_data->user_data.length <= 127)
  376. {
  377. *encoding_buffer_length = MAXIMUM_PROTOCOL_OVERHEAD - 1;
  378. }
  379. else
  380. {
  381. *(buffer_pointer++) = (UChar)(send_data->user_data.length >> 8) |
  382. INDEFINITE_LENGTH;
  383. *encoding_buffer_length = MAXIMUM_PROTOCOL_OVERHEAD;
  384. }
  385. *buffer_pointer++ = (UChar)send_data->user_data.length;
  386. initiator = (UShort) (*encoding_buffer_length + send_data->user_data.length);
  387. // Set the returned length of the encoded PDU.
  388. if (bBufferAllocated || (send_data->segmentation & SEGMENTATION_BEGIN)) {
  389. /*
  390. * If the Encode operation allocates the space needed, or the space
  391. * was allocated by MCSGetBufferRequest (by a client) and this is
  392. * the 1st segment of the data in the buffer, the whole encoded PDU
  393. * is in contiguous space. The total PDU size is returned in this
  394. * case.
  395. * However, in the case where the space was allocated by MCSGetBufferRequest,
  396. * the PDUs after the 1st one, will put the X.224 and MCS headers in
  397. * a separate piece of memory (whose length is returned here), and the
  398. * data is still in the pre-allocated space.
  399. */
  400. *encoding_buffer_length = (UINT) initiator;
  401. }
  402. /*
  403. * If the space was not preallocated, we need to copy the data
  404. * into the space allocated by the encoder.
  405. */
  406. if (bBufferAllocated) {
  407. // We now need to copy the data into the encoded data PDU.
  408. memcpy (buffer_pointer, send_data->user_data.value,
  409. send_data->user_data.length);
  410. // Update the data ptr in the data packet
  411. send_data->user_data.value = (ASN1octet_t *) buffer_pointer;
  412. }
  413. }
  414. }
  415. }
  416. if (send_data_pdu == FALSE)
  417. {
  418. SetEncodingRules (rules_type);
  419. return_value = ASN1_Encode(m_pEncInfo, // ptr to encoder info
  420. pdu_structure, // pdu data structure
  421. pdu_type, // pdu id
  422. ASN1ENCODE_ALLOCATEBUFFER, // flags
  423. NULL, // do not provide buffer
  424. 0); // buffer size if provided
  425. if (ASN1_FAILED(return_value))
  426. {
  427. ERROR_OUT(("CMCSCoder::Encode: ASN1_Encode failed, err=%d", return_value));
  428. ASSERT(FALSE);
  429. fRet = FALSE;
  430. goto MyExit;
  431. }
  432. ASSERT(return_value == ASN1_SUCCESS);
  433. /*
  434. * The encoded buffers returned by ASN.1 have preallocated the space
  435. * needed for the X.224 header.
  436. */
  437. // len of encoded data in buffer
  438. *encoding_buffer_length = m_pEncInfo->len;
  439. initiator = (UShort) *encoding_buffer_length;
  440. // buffer to encode into
  441. *encoding_buffer = m_pEncInfo->buf;
  442. }
  443. // Now, add the X.224 header
  444. buffer_pointer = *encoding_buffer;
  445. memcpy (buffer_pointer, g_X224Header, PROTOCOL_OVERHEAD_X224);
  446. AddRFCSize (buffer_pointer, initiator);
  447. MyExit:
  448. return fRet;
  449. }
  450. /*
  451. * void Decode ()
  452. *
  453. * Public
  454. *
  455. * Functional Description:
  456. * This function decodes ASN.1 compliant byte streams into the
  457. * appropriate MCS PDU structures using the ASN.1 toolkit.
  458. *
  459. * NOTE: For data PDUs, do NOT access pdecoding_buffer_length. It's set
  460. * to NULL.
  461. */
  462. BOOL CMCSCoder::Decode(LPBYTE encoded_buffer,
  463. UINT encoded_buffer_length,
  464. int pdu_type,
  465. UINT rules_type,
  466. LPVOID *pdecoding_buffer,
  467. UINT *pdecoding_buffer_length)
  468. {
  469. BOOL fRet = TRUE;
  470. BOOL send_data_pdu = FALSE;
  471. ASN1optionparam_s OptParam;
  472. /*
  473. * Check to make sure the encoding rules type is properly set.
  474. */
  475. ASSERT(rules_type == PACKED_ENCODING_RULES || pdu_type == CONNECT_MCS_PDU);
  476. if (pdu_type == DOMAIN_MCS_PDU)
  477. {
  478. UChar length;
  479. unsigned int short_data;
  480. PUChar buffer_pointer;
  481. PSendDataRequestPDU send_data;
  482. PDomainMCSPDU decoding_pdu;
  483. ASN1choice_t choice;
  484. buffer_pointer = encoded_buffer;
  485. #ifdef ENABLE_BER
  486. /*
  487. * If we are currently using Basic Encoding Rules.
  488. */
  489. if (Encoding_Rules_Type == BASIC_ENCODING_RULES)
  490. {
  491. switch (*(buffer_pointer++))
  492. {
  493. case SEND_DATA_REQUEST:
  494. ((PDomainMCSPDU) decoding_buffer)->choice =
  495. SEND_DATA_REQUEST_CHOSEN;
  496. send_data_pdu = TRUE;
  497. break;
  498. case SEND_DATA_INDICATION:
  499. ((PDomainMCSPDU) decoding_buffer)->choice =
  500. SEND_DATA_INDICATION_CHOSEN;
  501. send_data_pdu = TRUE;
  502. break;
  503. case UNIFORM_SEND_DATA_REQUEST:
  504. ((PDomainMCSPDU) decoding_buffer)->choice =
  505. UNIFORM_SEND_DATA_REQUEST_CHOSEN;
  506. send_data_pdu = TRUE;
  507. break;
  508. case UNIFORM_SEND_DATA_INDICATION:
  509. ((PDomainMCSPDU) decoding_buffer)->choice =
  510. UNIFORM_SEND_DATA_INDICATION_CHOSEN;
  511. send_data_pdu = TRUE;
  512. break;
  513. }
  514. if (send_data_pdu )
  515. {
  516. /*
  517. * Get the pointer to the "Send Data" PDU.
  518. */
  519. send_data = &((PDomainMCSPDU) decoding_buffer)->
  520. u.send_data_request;
  521. /*
  522. * Retrieve one byte for the length and check to see which
  523. * length variant is being used. If the long variant is being
  524. * used, move the buffer pointer past the length and set the
  525. * flag indicating that the indefinite length is not being used.
  526. */
  527. length = *buffer_pointer;
  528. switch (length)
  529. {
  530. case ONE_BYTE_LENGTH:
  531. buffer_pointer += 3;
  532. break;
  533. case TWO_BYTE_LENGTH:
  534. buffer_pointer += 4;
  535. break;
  536. case THREE_BYTE_LENGTH:
  537. buffer_pointer += 5;
  538. break;
  539. case FOUR_BYTE_LENGTH:
  540. buffer_pointer += 6;
  541. break;
  542. default:
  543. buffer_pointer += 2;
  544. }
  545. /*
  546. * Decode the integer "initiator" field. Increment the data
  547. * pointer past the integer identifier and retrieve the length
  548. * of the integer.
  549. */
  550. length = *(buffer_pointer++);
  551. ASSERT ((length == 1) || (length == 2));
  552. if (length == 1)
  553. send_data->initiator = (UserID) *(buffer_pointer++);
  554. else if (length == 2)
  555. {
  556. send_data->initiator = ((UserID) *(buffer_pointer++)) << 8;
  557. send_data->initiator |= (UserID) *(buffer_pointer++);
  558. }
  559. else
  560. {
  561. TRACE_OUT(("CMCSCoder::Decode: initiator field is longer than 2 bytes (%d bytes) in MCS Data packet.", (UINT) length));
  562. }
  563. /*
  564. * Decode the integer "channel ID" field. Increment the data
  565. * pointer past the integer identifier and retrieve the length
  566. * of the integer.
  567. */
  568. buffer_pointer++;
  569. length = *(buffer_pointer++);
  570. ASSERT ((length == 1) || (length == 2));
  571. if (length == 1)
  572. send_data->channel_id = (ChannelID) *(buffer_pointer++);
  573. else if (length == 2)
  574. {
  575. send_data->channel_id = ((ChannelID) *buffer_pointer++) << 8;
  576. send_data->channel_id |= (ChannelID) *(buffer_pointer++);
  577. }
  578. else
  579. {
  580. TRACE_OUT(("CMCSCoder::Decode: channel_id field is longer than 2 bytes (%d bytes) in MCS Data packet.", (UINT) length));
  581. }
  582. /*
  583. * Decode the enumerated "data priority" field. Increment the
  584. * data pointer past the identifier and length.
  585. */
  586. buffer_pointer+=2;
  587. send_data->data_priority =(PDUPriority)*buffer_pointer;
  588. /*
  589. * Decode the bit string "segmentation" field. Increment the
  590. * data pointer past the bit string identifier, length, and the
  591. * "unused bits" byte and retrieve the "segmentation" flag.
  592. */
  593. buffer_pointer += 4;
  594. send_data->segmentation = *buffer_pointer;
  595. /*
  596. * Decode the "user data" octet string. Increment the data
  597. * pointer past the identifier.
  598. */
  599. buffer_pointer += 2;
  600. /*
  601. * Check to see which variant of the length is being used and
  602. * then retrieve the length.
  603. */
  604. length = *(buffer_pointer++);
  605. if (length & INDEFINITE_LENGTH)
  606. {
  607. if (length == ONE_BYTE_LENGTH)
  608. send_data->user_data.length = (unsigned int) *(buffer_pointer++);
  609. /*
  610. * A length identifier of 0x82 indicates that two bytes are
  611. * being used to hold the actual length so retrieve the two
  612. * bytes to form the length.
  613. */
  614. else if (length == TWO_BYTE_LENGTH)
  615. {
  616. send_data->user_data.length =
  617. ((unsigned int) *(buffer_pointer++)) << 8;
  618. send_data->user_data.length |=
  619. (unsigned int) *(buffer_pointer++);
  620. }
  621. }
  622. else
  623. send_data->user_data.length = (unsigned int) length;
  624. // buffer_pointer now points to the 1st data byte
  625. send_data->user_data.value = buffer_pointer;
  626. *pulDataOffset = buffer_pointer - encoded_buffer;
  627. }
  628. }
  629. /*
  630. * If we are currently using Packed Encoding Rules.
  631. */
  632. else
  633. #endif // ENABLE_BER
  634. {
  635. switch (*(buffer_pointer++))
  636. {
  637. case PER_SEND_DATA_REQUEST:
  638. choice = SEND_DATA_REQUEST_CHOSEN;
  639. send_data_pdu = TRUE;
  640. break;
  641. case PER_SEND_DATA_INDICATION:
  642. choice = SEND_DATA_INDICATION_CHOSEN;
  643. send_data_pdu = TRUE;
  644. break;
  645. case PER_UNIFORM_SEND_DATA_REQUEST:
  646. choice = UNIFORM_SEND_DATA_REQUEST_CHOSEN;
  647. send_data_pdu = TRUE;
  648. break;
  649. case PER_UNIFORM_SEND_DATA_INDICATION:
  650. choice = UNIFORM_SEND_DATA_INDICATION_CHOSEN;
  651. send_data_pdu = TRUE;
  652. break;
  653. }
  654. if (send_data_pdu)
  655. {
  656. decoding_pdu = (PDomainMCSPDU) pdecoding_buffer;
  657. // Store the choice field
  658. decoding_pdu->choice = choice;
  659. /*
  660. * Get the pointer to the "Send Data" PDU.
  661. */
  662. send_data = &decoding_pdu->u.send_data_request;
  663. /*
  664. * Decode the integer "initiator" field.
  665. */
  666. short_data = ((unsigned int) *(buffer_pointer++)) << 8;
  667. short_data |= (unsigned int) *(buffer_pointer++);
  668. send_data->initiator = (UserID) short_data + INITIATOR_LOWER_BOUND;
  669. /*
  670. * Decode the integer "channel ID" field.
  671. */
  672. send_data->channel_id = ((ChannelID) *(buffer_pointer++)) << 8;
  673. send_data->channel_id |= (ChannelID) *(buffer_pointer++);
  674. /*
  675. * Decode the enumerated "data priority" field and the
  676. * "segmentation" field.
  677. */
  678. send_data->data_priority =
  679. (PDUPriority)((*buffer_pointer >> 6) & 0x03);
  680. send_data->segmentation = (*(buffer_pointer++) << 2) & 0xc0;
  681. /*
  682. * Decode the "user data" octet string. Check to see which
  683. * variant of the length is being used and then retrieve the
  684. * length.
  685. */
  686. length = *(buffer_pointer++);
  687. if (length & INDEFINITE_LENGTH)
  688. {
  689. ASSERT ((length & 0x40) == 0);
  690. /*
  691. * If bit 7 is set the length is greater than 127 but
  692. * less than 16K.
  693. *
  694. * ChristTs: We no longer handle the case where the data length
  695. * was higher than 16K. Our Max PDU size is 4K.
  696. */
  697. short_data = (unsigned int) ((length & 0x3f) << 8);
  698. send_data->user_data.length =
  699. short_data | ((unsigned int) *(buffer_pointer++));
  700. }
  701. /*
  702. * If bit 7 is not set then the length is less than 128 and is
  703. * contained in the retrieved byte.
  704. */
  705. else
  706. {
  707. send_data->user_data.length = (UShort) length;
  708. }
  709. // buffer_pointer now points to the 1st data byte
  710. send_data->user_data.value = buffer_pointer;
  711. }
  712. }
  713. }
  714. if (send_data_pdu == FALSE)
  715. {
  716. int return_value;
  717. //void *pDecodedData;
  718. SetEncodingRules (rules_type);
  719. return_value = ASN1_Decode(m_pDecInfo,// ptr to decoder info
  720. pdecoding_buffer, // destination buffer
  721. pdu_type, // pdu type
  722. ASN1DECODE_SETBUFFER, // flags
  723. encoded_buffer, // source buffer
  724. encoded_buffer_length); // source buffer size
  725. if (ASN1_FAILED(return_value))
  726. {
  727. ERROR_OUT(("CMCSCoder::Decode: ASN1_Decode failed, err=%d", return_value));
  728. ASSERT(FALSE);
  729. fRet = FALSE;
  730. goto MyExit;
  731. }
  732. OptParam.eOption = ASN1OPT_GET_DECODED_BUFFER_SIZE;
  733. return_value = ASN1_GetDecoderOption(m_pDecInfo, &OptParam);
  734. if (ASN1_FAILED(return_value))
  735. {
  736. ERROR_OUT(("CMCSCoder::Decode: ASN1_GetDecoderOption failed, err=%d", return_value));
  737. ASSERT(FALSE);
  738. fRet = FALSE;
  739. goto MyExit;
  740. }
  741. *pdecoding_buffer_length = OptParam.cbRequiredDecodedBufSize;
  742. ASSERT((return_value == ASN1_SUCCESS) && (*pdecoding_buffer_length > 0));
  743. }
  744. MyExit:
  745. return fRet;
  746. }
  747. /*
  748. * PacketCoderError ReverseDirection ()
  749. *
  750. * Private
  751. *
  752. * Functional Description:
  753. * This routine is used to convert data request PDU's into data indication
  754. * PDU's and vice versa.
  755. */
  756. Void CMCSCoder::ReverseDirection (LPBYTE encoded_buffer)
  757. {
  758. encoded_buffer += PROTOCOL_OVERHEAD_X224;
  759. switch (*encoded_buffer)
  760. {
  761. case PER_SEND_DATA_REQUEST:
  762. *encoded_buffer = PER_SEND_DATA_INDICATION;
  763. break;
  764. case PER_SEND_DATA_INDICATION:
  765. *encoded_buffer = PER_SEND_DATA_REQUEST;
  766. break;
  767. case PER_UNIFORM_SEND_DATA_REQUEST:
  768. *encoded_buffer = PER_UNIFORM_SEND_DATA_INDICATION;
  769. break;
  770. case PER_UNIFORM_SEND_DATA_INDICATION:
  771. *encoded_buffer = PER_UNIFORM_SEND_DATA_REQUEST;
  772. break;
  773. default:
  774. ASSERT (FALSE);
  775. break;
  776. }
  777. }
  778. /*
  779. * void SetEncodingRules ()
  780. *
  781. * Private
  782. *
  783. * Functional Description:
  784. * This function is used to set the type (basic or packed) of encoding
  785. * rules to be used.
  786. */
  787. void CMCSCoder::SetEncodingRules (UINT rules_type)
  788. {
  789. /*
  790. * If the rules type is changing, set our rules instance variable and reset
  791. * the variables which hold the amount of overhead associated with the
  792. * "SendData" PDU's.
  793. */
  794. Encoding_Rules_Type = rules_type;
  795. }
  796. /*
  797. * BOOL IsMCSDataPacket ()
  798. *
  799. * Public
  800. *
  801. * Functional Description:
  802. * This function determines whether the encoded packet is an MCS Data packet
  803. * or not.
  804. *
  805. * Return value:
  806. * TRUE, if the packet is an MCS Data packet. FALSE, otherwise.
  807. */
  808. BOOL CMCSCoder::IsMCSDataPacket(LPBYTE encoded_buffer, UINT rules_type)
  809. {
  810. UChar identifier;
  811. /*
  812. * Retrieve the identifier from the encoded data.
  813. */
  814. identifier = *encoded_buffer;
  815. if (rules_type == BASIC_ENCODING_RULES)
  816. {
  817. if ( (identifier == SEND_DATA_REQUEST) ||
  818. (identifier == SEND_DATA_INDICATION) ||
  819. (identifier == UNIFORM_SEND_DATA_REQUEST) ||
  820. (identifier == UNIFORM_SEND_DATA_INDICATION))
  821. {
  822. return TRUE;
  823. }
  824. }
  825. else
  826. {
  827. if ( (identifier == PER_SEND_DATA_REQUEST) ||
  828. (identifier == PER_SEND_DATA_INDICATION) ||
  829. (identifier == PER_UNIFORM_SEND_DATA_REQUEST) ||
  830. (identifier == PER_UNIFORM_SEND_DATA_INDICATION))
  831. {
  832. return TRUE;
  833. }
  834. }
  835. return FALSE;
  836. }
  837. void CMCSCoder::FreeEncoded(LPBYTE encoded_buffer)
  838. {
  839. ASN1_FreeEncoded(m_pEncInfo, encoded_buffer);
  840. }
  841. void CMCSCoder::FreeDecoded (int pdu_type, LPVOID decoded_buffer)
  842. {
  843. ASN1_FreeDecoded(m_pDecInfo, decoded_buffer, pdu_type);
  844. }