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.

789 lines
27 KiB

  1. #include <irda.h>
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. #include <tchar.h>
  5. #include <string.h>
  6. #include <decdirda.h>
  7. #if DBG
  8. UINT BaudBitField = 0;
  9. #ifdef UNDER_CE
  10. // WARNING, this really doesn't work with UNICODE
  11. #define isprint(c) (((c) >= TEXT(' ')) && ((c) <= 0x7f))
  12. #else
  13. #define wsprintf sprintf
  14. #endif
  15. int vDispMode;
  16. UINT vDecodeLayer;
  17. int vSlotTable[] = { 1, 6, 8, 16 };
  18. int IasRequest;
  19. TCHAR *vLM_PDU_DscReason[] =
  20. {
  21. TEXT(""),
  22. TEXT("User Request"),
  23. TEXT("Unexpected IrLAP Disconnect"),
  24. TEXT("Failed to establish IrLAP connection"),
  25. TEXT("IrLAP reset"),
  26. TEXT("Link management initiated disconnect"),
  27. TEXT("data sent to disconnected LSAP"),
  28. TEXT("Non responsive LM-MUX client"),
  29. TEXT("No available LM-MUX client"),
  30. TEXT("Unspecified")
  31. };
  32. /*
  33. ** Negotiation Parameter Value (PV) tables
  34. */
  35. TCHAR *vBaud[] =
  36. {
  37. TEXT("2400"), TEXT("9600"), TEXT("19200"), TEXT("38400"), TEXT("57600"),
  38. TEXT("115200"), TEXT("576000"), TEXT("1152000"), TEXT("4000000")
  39. };
  40. TCHAR *vMaxTAT[] = /* Turn Around Time */
  41. {
  42. TEXT("500"), TEXT("250"), TEXT("100"), TEXT("50"), TEXT("25"), TEXT("10"),
  43. TEXT("5"), TEXT("reserved")
  44. };
  45. TCHAR *vMinTAT[] =
  46. {
  47. TEXT("10"), TEXT("5"), TEXT("1"), TEXT("0.5"), TEXT("0.1"), TEXT("0.05"),
  48. TEXT("0.01"), TEXT("0")
  49. };
  50. TCHAR *vDataSize[] =
  51. {
  52. TEXT("64"), TEXT("128"), TEXT("256"), TEXT("512"), TEXT("1024"),
  53. TEXT("2048"), TEXT("reserved"), TEXT("reserved")
  54. };
  55. TCHAR *vWinSize[] =
  56. {
  57. TEXT("1"), TEXT("2"), TEXT("3"), TEXT("4"), TEXT("5"), TEXT("6"),
  58. TEXT("7"), TEXT("reserved")
  59. };
  60. TCHAR *vNumBofs[] =
  61. {
  62. TEXT("48"), TEXT("24"), TEXT("12"), TEXT("5"), TEXT("3"), TEXT("2"),
  63. TEXT("1"), TEXT("0")
  64. };
  65. TCHAR *vDiscThresh[] =
  66. {
  67. TEXT("3"), TEXT("8"), TEXT("12"), TEXT("16"), TEXT("20"), TEXT("25"),
  68. TEXT("30"), TEXT("40")
  69. };
  70. /*---------------------------------------------------------------------------*/
  71. void
  72. RawDump(UCHAR *pFrameBuf, UCHAR *pEndBuf, TCHAR **ppOutStr)
  73. {
  74. BOOLEAN First = TRUE;
  75. UCHAR *pBufPtr = pFrameBuf;
  76. if (!vDecodeLayer)
  77. return;
  78. if (vDispMode == DISP_ASCII || vDispMode == DISP_BOTH)
  79. {
  80. while (pBufPtr <= pEndBuf)
  81. {
  82. if (First)
  83. {
  84. First = FALSE;
  85. *(*ppOutStr)++ = TEXT('[');
  86. }
  87. *(*ppOutStr)++ = isprint(*pBufPtr) ? *pBufPtr : '.';
  88. pBufPtr++;
  89. }
  90. if (!First) // meaning, close [
  91. *(*ppOutStr)++ = ']';
  92. }
  93. First = TRUE;
  94. pBufPtr = pFrameBuf;
  95. if (vDispMode == DISP_HEX || vDispMode == DISP_BOTH)
  96. {
  97. while (pBufPtr <= pEndBuf)
  98. {
  99. if (First)
  100. {
  101. First = FALSE;
  102. *(*ppOutStr)++ = TEXT('[');
  103. }
  104. *ppOutStr += wsprintf(*ppOutStr, TEXT("%02X "), *pBufPtr);
  105. pBufPtr++;
  106. }
  107. if (!First) // meaning, close [
  108. *(*ppOutStr)++ = ']';
  109. }
  110. }
  111. /*---------------------------------------------------------------------------*/
  112. TCHAR *
  113. GetStatusStr(UCHAR status)
  114. {
  115. switch (status)
  116. {
  117. case LM_PDU_SUCCESS:
  118. return (TEXT("SUCCESS"));
  119. case LM_PDU_FAILURE:
  120. return (TEXT("FAILURE"));
  121. case LM_PDU_UNSUPPORTED:
  122. return (TEXT("UNSUPPORTED"));
  123. default:
  124. return (TEXT("BAD STATUS!"));
  125. }
  126. }
  127. void
  128. DecodeIas(UCHAR *pFrameBuf, UCHAR *pEndBuf, TCHAR **ppOutStr)
  129. {
  130. /*
  131. IAS_CNTL_HEADER *pCntlHeader = (IAS_CNTL_HEADER *) pFrameBuf;
  132. int NameLen;
  133. WCHAR NameBuffer[128];
  134. *ppOutStr += wsprintf(*ppOutStr, TEXT("lst:%d ack:%d opcode:%d "),
  135. pCntlHeader->Last, pCntlHeader->Ack,
  136. pCntlHeader->OpCode);
  137. switch (pCntlHeader->OpCode)
  138. {
  139. case LM_GETVALUEBYCLASS:
  140. *ppOutStr += wsprintf(*ppOutStr, TEXT("GetValueByClass"));
  141. break;
  142. default:
  143. *ppOutStr += wsprintf(*ppOutStr, TEXT("I DON'T DECODE THIS OPCODE!"));
  144. return;
  145. }
  146. pFrameBuf++;
  147. IasRequest = !IasRequest; // This can get out of sync, then we're f'd
  148. if (IasRequest)
  149. {
  150. *ppOutStr += wsprintf(*ppOutStr, TEXT("Req "));
  151. // Class name
  152. NameLen = (int) *pFrameBuf++;
  153. MultiByteToWideChar(
  154. CP_ACP,
  155. 0,
  156. pFrameBuf,
  157. NameLen,
  158. NameBuffer,
  159. 128);
  160. NameBuffer[NameLen] = TEXT('\0');
  161. *ppOutStr += wsprintf(*ppOutStr, TEXT("class:%ws "), NameBuffer);
  162. pFrameBuf += NameLen;
  163. // Attribute name
  164. NameLen = (int) *pFrameBuf++;
  165. MultiByteToWideChar(
  166. CP_ACP,
  167. 0,
  168. pFrameBuf,
  169. NameLen,
  170. NameBuffer,
  171. 128);
  172. NameBuffer[NameLen] = TEXT('\0');
  173. *ppOutStr += wsprintf(*ppOutStr, TEXT("attrib:%ws "), NameBuffer);
  174. }
  175. else
  176. {
  177. *ppOutStr += wsprintf(*ppOutStr, TEXT("Resp "));
  178. switch (*pFrameBuf)
  179. {
  180. case 0:
  181. *ppOutStr += wsprintf(*ppOutStr, TEXT("attrib:%ws "), NameBuffer);
  182. break;
  183. case 1:
  184. *ppOutStr += wsprintf(*ppOutStr, TEXT("No such class "));
  185. break;
  186. case 2:
  187. *ppOutStr += wsprintf(*ppOutStr, TEXT("No such attribute "));
  188. break;
  189. }
  190. }
  191. */
  192. return;
  193. }
  194. /*---------------------------------------------------------------------------*/
  195. void
  196. DecodeIFrm(UCHAR *pFrameBuf, UCHAR *pEndBuf, TCHAR **ppOutStr)
  197. {
  198. LM_HEADER *pLMHeader = (LM_HEADER *) pFrameBuf;
  199. LM_CNTL_FORMAT *pCFormat =
  200. (LM_CNTL_FORMAT *)(pFrameBuf + sizeof(LM_HEADER));
  201. UCHAR *pLMParm1 = ((UCHAR *) pCFormat + sizeof(LM_CNTL_FORMAT));
  202. UCHAR *pLMParm2 = ((UCHAR *) pCFormat + sizeof(LM_CNTL_FORMAT) + 1);
  203. TTP_CONN_HEADER *pTTPConnHeader = (TTP_CONN_HEADER *) pLMParm2;
  204. TTP_DATA_HEADER *pTTPDataHeader = (TTP_DATA_HEADER *)
  205. (pFrameBuf + sizeof(LM_HEADER));
  206. TCHAR RCStr[] = TEXT(" ");
  207. BOOLEAN IasFrame = FALSE;
  208. if (2 == vDecodeLayer) // LAP only
  209. {
  210. RawDump(pFrameBuf, pEndBuf, ppOutStr);
  211. return;
  212. }
  213. // Ensure the LMP header is there
  214. if (((UCHAR *)pLMHeader + sizeof(LM_HEADER) > pEndBuf+1))
  215. {
  216. *ppOutStr += wsprintf(*ppOutStr, TEXT("!-MISSING LMP HEADER-!"));
  217. return;
  218. }
  219. *ppOutStr += wsprintf(*ppOutStr, TEXT("sls:%02X dls:%02X "),
  220. pLMHeader->SLSAP_SEL, pLMHeader->DLSAP_SEL);
  221. if (pLMHeader->SLSAP_SEL == IAS_SEL || pLMHeader->DLSAP_SEL == IAS_SEL)
  222. {
  223. IasFrame = TRUE;
  224. *ppOutStr += wsprintf(*ppOutStr, TEXT("*IAS*"));
  225. }
  226. switch (pLMHeader->CntlBit)
  227. {
  228. case LM_PDU_CNTL_FRAME:
  229. _tcscpy(RCStr, pCFormat->ABit == LM_PDU_REQUEST ?
  230. TEXT("req") : TEXT("conf"));
  231. if (((UCHAR *)pCFormat + sizeof(LM_CNTL_FORMAT)) > pEndBuf+1)
  232. {
  233. *ppOutStr += wsprintf(*ppOutStr,
  234. TEXT("!-MISSING LMP-CNTL HEADER-!"));
  235. return;
  236. }
  237. else
  238. {
  239. if (pLMParm1 > pEndBuf)
  240. {
  241. pLMParm1 = NULL;
  242. pLMParm2 = NULL;
  243. pTTPConnHeader = NULL;
  244. }
  245. else
  246. {
  247. if (pLMParm2 > pEndBuf)
  248. {
  249. pLMParm2 = NULL;
  250. pTTPConnHeader = NULL;
  251. }
  252. else
  253. {
  254. if (((UCHAR *)pTTPConnHeader+sizeof(TTP_CONN_HEADER)) >
  255. pEndBuf+1)
  256. {
  257. pTTPConnHeader = NULL;
  258. }
  259. }
  260. }
  261. }
  262. switch (pCFormat->OpCode)
  263. {
  264. case LM_PDU_CONNECT:
  265. *ppOutStr += wsprintf(*ppOutStr, TEXT("LM-Connect.%s "),
  266. RCStr);
  267. if (pLMParm1 != NULL)
  268. {
  269. *ppOutStr += wsprintf(*ppOutStr, TEXT("rsvd:%02X "),
  270. *pLMParm1);
  271. }
  272. if (3 == vDecodeLayer) // LMP only
  273. {
  274. if (pLMParm2 != NULL)
  275. {
  276. // This is user data
  277. RawDump(pLMParm2, pEndBuf, ppOutStr);
  278. }
  279. }
  280. else
  281. {
  282. // TTP
  283. if (pTTPConnHeader == NULL)
  284. {
  285. *ppOutStr += wsprintf(*ppOutStr,
  286. TEXT("!-MISSING TTP CONNECT HEADER-!"));
  287. }
  288. else
  289. {
  290. *ppOutStr += wsprintf(*ppOutStr,
  291. TEXT("pf:%d ic:%d "),
  292. pTTPConnHeader->ParmFlag,
  293. pTTPConnHeader->InitialCredit);
  294. // This is user data
  295. RawDump(((UCHAR *) pTTPConnHeader +
  296. sizeof(TTP_CONN_HEADER)), pEndBuf,
  297. ppOutStr);
  298. }
  299. }
  300. break;
  301. case LM_PDU_DISCONNECT:
  302. *ppOutStr += wsprintf(*ppOutStr,
  303. TEXT("LM-Disconnect.%s"), RCStr);
  304. if (pLMParm1 == NULL)
  305. {
  306. *ppOutStr += wsprintf(*ppOutStr,
  307. TEXT("!-MISSING REASON CODE-!"));
  308. return;
  309. }
  310. else
  311. {
  312. if ((*pLMParm1 > LM_PDU_MAX_DSC_REASON ||
  313. *pLMParm1 == 0) && *pLMParm1 != 0xFF)
  314. {
  315. *ppOutStr += wsprintf(*ppOutStr,
  316. TEXT(" BAD REASON CODE:%02X "),
  317. *pLMParm1);
  318. }
  319. else
  320. {
  321. if (*pLMParm1 == 0xFF)
  322. {
  323. *pLMParm1 = 0x09; // KLUDGE HERE !!
  324. }
  325. *ppOutStr += wsprintf(*ppOutStr,
  326. TEXT("(%02X:%s) "), *pLMParm1,
  327. vLM_PDU_DscReason[*pLMParm1]);
  328. }
  329. if (pLMParm2 != NULL)
  330. {
  331. RawDump(pLMParm2, pEndBuf, ppOutStr);
  332. }
  333. }
  334. break;
  335. case LM_PDU_ACCESSMODE:
  336. *ppOutStr += wsprintf(*ppOutStr, TEXT("LM-AccessMode.%s "),
  337. RCStr);
  338. if (pLMParm1 == NULL || pLMParm2 == NULL)
  339. {
  340. *ppOutStr += wsprintf(*ppOutStr,
  341. TEXT("!-MISSING PARAMETER-!"));
  342. }
  343. else
  344. {
  345. if (pCFormat->ABit == LM_PDU_REQUEST)
  346. {
  347. *ppOutStr += wsprintf(*ppOutStr,
  348. TEXT("rsvd:%02X "), *pLMParm1);
  349. }
  350. else
  351. {
  352. *ppOutStr += wsprintf(*ppOutStr,
  353. TEXT("status:%s "), GetStatusStr(*pLMParm1));
  354. }
  355. *ppOutStr += wsprintf(*ppOutStr, TEXT("mode:%s "),
  356. *pLMParm2 == LM_PDU_EXCLUSIVE ?
  357. TEXT("Exclusive") :
  358. TEXT("Multiplexed"));
  359. }
  360. break;
  361. default:
  362. *ppOutStr += wsprintf(*ppOutStr, TEXT("Bad opcode: "));
  363. RawDump((UCHAR *) pCFormat, pEndBuf, ppOutStr);
  364. }
  365. break;
  366. case LM_PDU_DATA_FRAME:
  367. if (IasFrame)
  368. {
  369. DecodeIas((UCHAR *) pCFormat, pEndBuf, ppOutStr);
  370. break;
  371. }
  372. if (3 == vDecodeLayer)
  373. {
  374. RawDump((UCHAR *) pCFormat, pEndBuf, ppOutStr);
  375. }
  376. else
  377. {
  378. // TTP
  379. if ((UCHAR *) (pTTPDataHeader + 1) > pEndBuf + 1)
  380. {
  381. *ppOutStr += wsprintf(*ppOutStr,
  382. TEXT("!-MISSING TTP DATA HEADER-!"));
  383. }
  384. else
  385. {
  386. *ppOutStr += wsprintf(*ppOutStr,
  387. TEXT("mb:%d nc:%d "),
  388. pTTPDataHeader->MoreBit,
  389. pTTPDataHeader->AdditionalCredit);
  390. // This is user data
  391. RawDump(((UCHAR *) pTTPDataHeader +
  392. sizeof(TTP_DATA_HEADER)), pEndBuf,
  393. ppOutStr);
  394. }
  395. }
  396. break;
  397. default:
  398. *ppOutStr += wsprintf(*ppOutStr, TEXT("Bad LM-PDU type: "));
  399. RawDump((UCHAR *) pLMHeader, pEndBuf, ppOutStr);
  400. }
  401. }
  402. /*---------------------------------------------------------------------------*/
  403. UCHAR *
  404. DumpPv(TCHAR *PVTable[], UCHAR *pQosUChar, TCHAR **ppOutStr, UINT *pBitField)
  405. {
  406. int Pl = (int) *pQosUChar++;
  407. int i;
  408. BOOLEAN First = TRUE;
  409. UCHAR Mask = 1;
  410. *pBitField = 0;
  411. if (Pl == 1)
  412. {
  413. *pBitField = (UINT) *pQosUChar;
  414. }
  415. else
  416. {
  417. *pBitField = ((UINT) *(pQosUChar+1))<<8;
  418. *pBitField |= (UINT) *(pQosUChar);
  419. }
  420. for (i = 0; i <= 8; i++)
  421. {
  422. if (*pBitField & (Mask))
  423. {
  424. if (First)
  425. {
  426. *ppOutStr += wsprintf(*ppOutStr, PVTable[i]);
  427. First = FALSE;
  428. }
  429. else
  430. *ppOutStr += wsprintf(*ppOutStr, TEXT(",%s"), PVTable[i]);
  431. }
  432. Mask *= 2;
  433. }
  434. *(*ppOutStr)++ = '>';
  435. return pQosUChar + Pl;
  436. }
  437. /*---------------------------------------------------------------------------*/
  438. void
  439. DecodeNegParms(UCHAR *pCurPos, UCHAR *pEndBuf, TCHAR **ppOutStr)
  440. {
  441. UINT BitField;
  442. while (pCurPos+2 <= pEndBuf) /* need at least 3 bytes */
  443. /* to define a parm */
  444. {
  445. switch (*pCurPos)
  446. {
  447. case NEG_PI_BAUD:
  448. *ppOutStr += wsprintf(*ppOutStr, TEXT("<baud:"));
  449. pCurPos = DumpPv(vBaud, pCurPos+1, ppOutStr, &BitField);
  450. BaudBitField = BitField;
  451. break;
  452. case NEG_PI_MAX_TAT:
  453. *ppOutStr += wsprintf(*ppOutStr, TEXT("<max TAT:"));
  454. pCurPos = DumpPv(vMaxTAT, pCurPos+1, ppOutStr, &BitField);
  455. break;
  456. case NEG_PI_DATA_SZ:
  457. *ppOutStr += wsprintf(*ppOutStr, TEXT("<data size:"));
  458. pCurPos = DumpPv(vDataSize, pCurPos+1, ppOutStr, &BitField);
  459. break;
  460. case NEG_PI_WIN_SZ:
  461. *ppOutStr += wsprintf(*ppOutStr, TEXT("<win size:"));
  462. pCurPos = DumpPv(vWinSize, pCurPos+1, ppOutStr, &BitField);
  463. break;
  464. case NEG_PI_BOFS:
  465. *ppOutStr += wsprintf(*ppOutStr, TEXT("<BOFs:"));
  466. pCurPos = DumpPv(vNumBofs, pCurPos+1, ppOutStr, &BitField);
  467. break;
  468. case NEG_PI_MIN_TAT:
  469. *ppOutStr += wsprintf(*ppOutStr, TEXT("<min TAT:"));
  470. pCurPos = DumpPv(vMinTAT, pCurPos+1, ppOutStr, &BitField);
  471. break;
  472. case NEG_PI_DISC_THRESH:
  473. *ppOutStr += wsprintf(*ppOutStr, TEXT("<disc thresh:"));
  474. pCurPos = DumpPv(vDiscThresh, pCurPos+1, ppOutStr, &BitField);
  475. break;
  476. default:
  477. *ppOutStr += wsprintf(*ppOutStr, TEXT("!!BAD PARM:%02X!!"),*pCurPos);
  478. pCurPos += 3;
  479. }
  480. }
  481. }
  482. /*---------------------------------------------------------------------------*/
  483. void
  484. DecodeXID(UCHAR *FormatID, UCHAR *pEndBuf, TCHAR **ppOutStr)
  485. {
  486. XID_DISCV_FORMAT *DiscvFormat=(XID_DISCV_FORMAT *)((UCHAR *)FormatID + 1);
  487. UCHAR *NegParms = FormatID + 1;
  488. UCHAR *DiscvInfo = FormatID + sizeof(XID_DISCV_FORMAT);
  489. switch (*FormatID)
  490. {
  491. case XID_DISCV_FORMAT_ID:
  492. *ppOutStr += wsprintf(*ppOutStr, TEXT("dscv "));
  493. if (DiscvFormat->GenNewAddr)
  494. *ppOutStr += wsprintf(*ppOutStr, TEXT("new addr "));
  495. *ppOutStr += wsprintf(*ppOutStr, TEXT("sa:%02X%02X%02X%02X "),
  496. DiscvFormat->SrcAddr[0],
  497. DiscvFormat->SrcAddr[1],
  498. DiscvFormat->SrcAddr[2],
  499. DiscvFormat->SrcAddr[3]);
  500. *ppOutStr += wsprintf(*ppOutStr, TEXT("da:%02X%02X%02X%02X "),
  501. DiscvFormat->DestAddr[0],
  502. DiscvFormat->DestAddr[1],
  503. DiscvFormat->DestAddr[2],
  504. DiscvFormat->DestAddr[3]);
  505. *ppOutStr += wsprintf(*ppOutStr, TEXT("Slot:%02X/%X "),
  506. DiscvFormat->SlotNo,
  507. vSlotTable[DiscvFormat->NoOfSlots]);
  508. RawDump(DiscvInfo, pEndBuf, ppOutStr);
  509. break;
  510. case XID_NEGPARMS_FORMAT_ID:
  511. *ppOutStr += wsprintf(*ppOutStr, TEXT("Neg Parms "));
  512. DecodeNegParms(NegParms, pEndBuf, ppOutStr);
  513. break;
  514. }
  515. }
  516. /*---------------------------------------------------------------------------*/
  517. void
  518. BadFrame(UCHAR *pFrameBuf, UCHAR *pEndBuf, TCHAR **ppOutStr)
  519. {
  520. *ppOutStr += wsprintf(*ppOutStr, TEXT("Undefined Frame: "));
  521. RawDump(pFrameBuf, pEndBuf, ppOutStr);
  522. }
  523. /*---------------------------------------------------------------------------*/
  524. TCHAR *DecodeIRDA(int *pFrameType,// returned frame type (-1=bad frame)
  525. UCHAR *pFrameBuf, // pointer to buffer containing IRLAP frame
  526. UINT FrameLen, // length of buffer
  527. TCHAR *pOutStr, // string where decoded packet is placed
  528. UINT DecodeLayer,// 0, hdronly, 1,LAP only, 2 LAP/LMP, 3, LAP/LMP/TTP
  529. int fNoConnAddr,// TRUE->Don't show connection address in str
  530. int DispMode
  531. )
  532. {
  533. UINT CRBit;
  534. UINT PFBit;
  535. UCHAR *Addr = pFrameBuf;
  536. UCHAR *Cntl = pFrameBuf + 1;
  537. TCHAR CRStr[] = TEXT(" ");
  538. TCHAR PFChar = TEXT(' ');
  539. SNRM_FORMAT *SNRMFormat = (SNRM_FORMAT *) ((UCHAR *) pFrameBuf + 2);
  540. UA_FORMAT *UAFormat = (UA_FORMAT *) ((UCHAR *) pFrameBuf + 2);
  541. UINT Nr = IRLAP_GET_NR(*Cntl);
  542. UINT Ns = IRLAP_GET_NS(*Cntl);
  543. UCHAR *pEndBuf = pFrameBuf + FrameLen - 1;
  544. TCHAR *First = pOutStr;
  545. vDispMode = DispMode;
  546. vDecodeLayer = DecodeLayer;
  547. if ( !fNoConnAddr)
  548. pOutStr += wsprintf(pOutStr, TEXT("ca:%02X "), IRLAP_GET_ADDR(*Addr));
  549. CRBit = IRLAP_GET_CRBIT(*Addr);
  550. _tcscpy(CRStr, CRBit == _IRLAP_CMD ? TEXT("cmd"):TEXT("rsp"));
  551. PFBit = IRLAP_GET_PFBIT(*Cntl);
  552. if (1 == PFBit)
  553. {
  554. if (CRBit == _IRLAP_CMD)
  555. PFChar = 'P';
  556. else
  557. PFChar ='F';
  558. }
  559. *pFrameType = IRLAP_FRAME_TYPE(*Cntl);
  560. switch (IRLAP_FRAME_TYPE(*Cntl))
  561. {
  562. case IRLAP_I_FRM:
  563. pOutStr += wsprintf(pOutStr, TEXT("I %s %c ns:%01d nr:%01d "),
  564. CRStr, PFChar, Ns, Nr);
  565. if (DecodeLayer)
  566. DecodeIFrm(pFrameBuf + 2, pEndBuf, &pOutStr);
  567. break;
  568. case IRLAP_S_FRM:
  569. *pFrameType = IRLAP_GET_SCNTL(*Cntl);
  570. switch (IRLAP_GET_SCNTL(*Cntl))
  571. {
  572. case IRLAP_RR:
  573. pOutStr += wsprintf(pOutStr, TEXT("RR %s %c nr:%01d"),
  574. CRStr, PFChar, Nr);
  575. break;
  576. case IRLAP_RNR:
  577. pOutStr += wsprintf(pOutStr, TEXT("RNR %s %c nr:%01d"),
  578. CRStr, PFChar, Nr);
  579. break;
  580. case IRLAP_REJ:
  581. pOutStr += wsprintf(pOutStr, TEXT("REJ %s %c nr:%01d"),
  582. CRStr, PFChar, Nr);
  583. break;
  584. case IRLAP_SREJ:
  585. pOutStr += wsprintf(pOutStr, TEXT("SREJ %s %c nr:%01d"),
  586. CRStr, PFChar, Nr);
  587. break;
  588. default:
  589. BadFrame(pFrameBuf, pEndBuf, &pOutStr);
  590. }
  591. break;
  592. case IRLAP_U_FRM:
  593. *pFrameType = IRLAP_GET_UCNTL(*Cntl);
  594. switch (IRLAP_GET_UCNTL(*Cntl))
  595. {
  596. case IRLAP_UI:
  597. pOutStr += wsprintf(pOutStr,TEXT("UI %s %c "),
  598. CRStr, PFChar);
  599. RawDump(pFrameBuf + 2, pEndBuf, &pOutStr);
  600. break;
  601. case IRLAP_XID_CMD:
  602. case IRLAP_XID_RSP:
  603. pOutStr += wsprintf(pOutStr,TEXT("XID %s %c "),
  604. CRStr, PFChar);
  605. if (DecodeLayer)
  606. DecodeXID(pFrameBuf + 2, pEndBuf, &pOutStr);
  607. break;
  608. case IRLAP_TEST:
  609. pOutStr += wsprintf(pOutStr, TEXT("TEST %s %c "),
  610. CRStr, PFChar);
  611. pOutStr += wsprintf(pOutStr,
  612. TEXT("sa:%02X%02X%02X%02X da:%02X%02X%02X%02X "),
  613. UAFormat->SrcAddr[0],
  614. UAFormat->SrcAddr[1],
  615. UAFormat->SrcAddr[2],
  616. UAFormat->SrcAddr[3],
  617. UAFormat->DestAddr[0],
  618. UAFormat->DestAddr[1],
  619. UAFormat->DestAddr[2],
  620. UAFormat->DestAddr[3]);
  621. RawDump(pFrameBuf + 1 + sizeof(UA_FORMAT), pEndBuf,
  622. &pOutStr);
  623. break;
  624. case IRLAP_SNRM:
  625. if (CRBit == _IRLAP_CMD)
  626. {
  627. pOutStr += wsprintf(pOutStr,TEXT("SNRM %s %c "),
  628. CRStr,PFChar);
  629. if ((UCHAR *) SNRMFormat < pEndBuf)
  630. {
  631. pOutStr += wsprintf(pOutStr,
  632. TEXT("sa:%02X%02X%02X%02X da:%02X%02X%02X%02X ca:%02X "),
  633. SNRMFormat->SrcAddr[0],
  634. SNRMFormat->SrcAddr[1],
  635. SNRMFormat->SrcAddr[2],
  636. SNRMFormat->SrcAddr[3],
  637. SNRMFormat->DestAddr[0],
  638. SNRMFormat->DestAddr[1],
  639. SNRMFormat->DestAddr[2],
  640. SNRMFormat->DestAddr[3],
  641. // CRBit stored in conn addr
  642. // according to spec...
  643. (SNRMFormat->ConnAddr) >>1);
  644. if (DecodeLayer)
  645. DecodeNegParms(&(SNRMFormat->FirstPI),
  646. pEndBuf, &pOutStr);
  647. }
  648. }
  649. else
  650. pOutStr += wsprintf(pOutStr,
  651. TEXT("RNRM %s %c "),CRStr,PFChar);
  652. break;
  653. case IRLAP_DISC:
  654. if (CRBit == _IRLAP_CMD)
  655. pOutStr += wsprintf(pOutStr, TEXT("DISC %s %c "),
  656. CRStr, PFChar);
  657. else
  658. pOutStr += wsprintf(pOutStr, TEXT("RD %s %c "),
  659. CRStr, PFChar);
  660. break;
  661. case IRLAP_UA:
  662. pOutStr += wsprintf(pOutStr,
  663. TEXT("UA %s %c "),CRStr,PFChar);
  664. if ((UCHAR *) UAFormat < pEndBuf)
  665. {
  666. pOutStr += wsprintf(pOutStr,
  667. TEXT("sa:%02X%02X%02X%02X da:%02X%02X%02X%02X "),
  668. UAFormat->SrcAddr[0],
  669. UAFormat->SrcAddr[1],
  670. UAFormat->SrcAddr[2],
  671. UAFormat->SrcAddr[3],
  672. UAFormat->DestAddr[0],
  673. UAFormat->DestAddr[1],
  674. UAFormat->DestAddr[2],
  675. UAFormat->DestAddr[3]);
  676. if (DecodeLayer)
  677. DecodeNegParms(&(UAFormat->FirstPI), pEndBuf,
  678. &pOutStr);
  679. }
  680. break;
  681. case IRLAP_FRMR:
  682. pOutStr += wsprintf(pOutStr, TEXT("FRMR %s %c "),
  683. CRStr, PFChar);
  684. RawDump(pFrameBuf + 2, pEndBuf, &pOutStr);
  685. break;
  686. case IRLAP_DM:
  687. pOutStr += wsprintf(pOutStr, TEXT("DM %s %c "),
  688. CRStr, PFChar);
  689. break;
  690. default:
  691. BadFrame(pFrameBuf, pEndBuf, &pOutStr);
  692. }
  693. break;
  694. default:
  695. *pFrameType = -1;
  696. BadFrame(pFrameBuf, pEndBuf, &pOutStr);
  697. }
  698. *pOutStr = 0;
  699. return (First);
  700. }
  701. #endif