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.

950 lines
25 KiB

  1. /*****************************************************************************
  2. *
  3. * Copyright (c) 1995 Microsoft Corporation
  4. *
  5. * File: irlapio.c
  6. *
  7. * Description: IRLAP I/O routines
  8. *
  9. * Author: mbert
  10. *
  11. * Date: 4/25/95
  12. *
  13. */
  14. #include <irda.h>
  15. #include <irioctl.h>
  16. #include <irlap.h>
  17. #include <irlmp.h>
  18. #include <irlapp.h>
  19. #include <irlapio.h>
  20. #include <irlaplog.h>
  21. extern UCHAR IrlapBroadcastDevAddr[];
  22. __inline
  23. VOID
  24. SendFrame(PIRLAP_CB pIrlapCb, PIRDA_MSG pMsg)
  25. {
  26. pMsg->Prim = MAC_DATA_REQ;
  27. IrmacDown(pIrlapCb->pIrdaLinkCb, pMsg);
  28. // IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_DATA_REQ: %s"), FrameToStr(pMsg)));
  29. }
  30. /*****************************************************************************
  31. *
  32. * @func ret_type | func_name | funcdesc
  33. *
  34. * @rdesc SUCCESS, otherwise one of the following errors:
  35. * @flag val | desc
  36. *
  37. * @parm data_type | parm_name | description
  38. *
  39. * @comm
  40. * comments
  41. */
  42. VOID
  43. ClearRxWindow(PIRLAP_CB pIrlapCb)
  44. {
  45. UINT i;
  46. // Remove everything from Rx window
  47. for (i = pIrlapCb->Vr; i != pIrlapCb->RxWin.End; i = (i+1) % IRLAP_MOD)
  48. {
  49. if (pIrlapCb->RxWin.pMsg[i] != NULL)
  50. {
  51. ASSERT(pIrlapCb->RxWin.pMsg[i]->IRDA_MSG_RefCnt);
  52. pIrlapCb->RxWin.pMsg[i]->IRDA_MSG_RefCnt -= 1;
  53. if (pIrlapCb->RxWin.pMsg[i]->IRDA_MSG_RefCnt == 0)
  54. {
  55. pIrlapCb->RxWin.pMsg[i]->Prim = MAC_DATA_RESP;
  56. IrmacDown(pIrlapCb->pIrdaLinkCb, pIrlapCb->RxWin.pMsg[i]);
  57. }
  58. pIrlapCb->RxWin.pMsg[i] = NULL;
  59. }
  60. pIrlapCb->RxWin.End = pIrlapCb->Vr;
  61. }
  62. }
  63. /*****************************************************************************
  64. *
  65. * @func ret_type | func_name | funcdesc
  66. *
  67. * @rdesc SUCCESS, otherwise one of the following errors:
  68. * @flag val | desc
  69. *
  70. * @parm data_type | parm_name | description
  71. *
  72. * @comm
  73. * comments
  74. */
  75. VOID
  76. SendDscvXIDCmd(PIRLAP_CB pIrlapCb)
  77. {
  78. UINT rc = SUCCESS;
  79. IRLAP_XID_DSCV_FORMAT XIDFormat;
  80. CHAR *DscvInfo;
  81. int DscvInfoLen;
  82. IRDA_MSG *pIMsg;
  83. RtlCopyMemory(XIDFormat.SrcAddr, pIrlapCb->LocalDevice.DevAddr,
  84. IRDA_DEV_ADDR_LEN);
  85. RtlCopyMemory(XIDFormat.DestAddr, IrlapBroadcastDevAddr,
  86. IRDA_DEV_ADDR_LEN);
  87. XIDFormat.NoOfSlots = IRLAP_SLOT_FLAG(pIrlapCb->MaxSlot);
  88. XIDFormat.GenNewAddr = pIrlapCb->GenNewAddr;
  89. XIDFormat.Reserved = 0;
  90. if (pIrlapCb->SlotCnt == pIrlapCb->MaxSlot)
  91. {
  92. DscvInfo = pIrlapCb->LocalDevice.DscvInfo;
  93. DscvInfoLen = pIrlapCb->LocalDevice.DscvInfoLen;
  94. XIDFormat.SlotNo = IRLAP_END_DSCV_SLOT_NO;
  95. }
  96. else
  97. {
  98. DscvInfo = NULL;
  99. DscvInfoLen = 0;
  100. XIDFormat.SlotNo = (UCHAR) pIrlapCb->SlotCnt;
  101. }
  102. XIDFormat.Version = (UCHAR) pIrlapCb->LocalDevice.IRLAP_Version;
  103. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  104. return;
  105. pIMsg->IRDA_MSG_pWrite = Format_DscvXID(pIMsg,
  106. IRLAP_BROADCAST_CONN_ADDR,
  107. IRLAP_CMD, IRLAP_PFBIT_SET,
  108. &XIDFormat, DscvInfo,
  109. DscvInfoLen);
  110. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: DscvXidCmd")));
  111. SendFrame(pIrlapCb, pIMsg);
  112. }
  113. /****************************************************************************S*
  114. *
  115. * @func ret_type | func_name | funcdesc
  116. *
  117. * @rdesc SUCCESS, otherwise one of the following errors:
  118. * @flag val | desc
  119. *
  120. * @parm data_type | parm_name | description
  121. *
  122. * @comm
  123. * comments
  124. */
  125. VOID
  126. SendDscvXIDRsp(PIRLAP_CB pIrlapCb)
  127. {
  128. IRLAP_XID_DSCV_FORMAT XIDFormat;
  129. IRDA_MSG *pIMsg;
  130. XIDFormat.GenNewAddr = pIrlapCb->GenNewAddr;
  131. if (pIrlapCb->GenNewAddr)
  132. {
  133. StoreULAddr(pIrlapCb->LocalDevice.DevAddr, GetMyDevAddr(TRUE));
  134. pIrlapCb->GenNewAddr = FALSE;
  135. }
  136. RtlCopyMemory(XIDFormat.SrcAddr, pIrlapCb->LocalDevice.DevAddr,
  137. IRDA_DEV_ADDR_LEN);
  138. RtlCopyMemory(XIDFormat.DestAddr, pIrlapCb->RemoteDevice.DevAddr,
  139. IRDA_DEV_ADDR_LEN);
  140. XIDFormat.NoOfSlots = IRLAP_SLOT_FLAG(pIrlapCb->RemoteMaxSlot);
  141. XIDFormat.Reserved = 0;
  142. XIDFormat.SlotNo = (UCHAR) pIrlapCb->RespSlot;
  143. XIDFormat.Version = (UCHAR) pIrlapCb->LocalDevice.IRLAP_Version;
  144. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  145. return;
  146. pIMsg->IRDA_MSG_pWrite = Format_DscvXID(
  147. pIMsg,
  148. IRLAP_BROADCAST_CONN_ADDR,
  149. IRLAP_RSP, IRLAP_PFBIT_SET,
  150. &XIDFormat,
  151. pIrlapCb->LocalDevice.DscvInfo,
  152. pIrlapCb->LocalDevice.DscvInfoLen);
  153. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: DscvXidRsp")));
  154. SendFrame(pIrlapCb, pIMsg);
  155. }
  156. /*****************************************************************************
  157. *
  158. * @func UINT | SendSNRM | formats a SNRM frame and sends it
  159. *
  160. * @rdesc SUCCESS, otherwise one of the following errors:
  161. * @flag val | desc
  162. *
  163. * @parm UCHAR | ConnAddr | Connection address
  164. *
  165. * @comm
  166. * The ConnAddr can be different than that in the control block.
  167. * For reset, its the same, but set to broadcast for initial
  168. * connection.
  169. */
  170. VOID
  171. SendSNRM(PIRLAP_CB pIrlapCb, BOOLEAN SendQos)
  172. {
  173. IRDA_QOS_PARMS *pQos = NULL;
  174. int ConnAddr = pIrlapCb->ConnAddr;
  175. IRDA_MSG *pIMsg;
  176. if (SendQos)
  177. {
  178. ConnAddr = IRLAP_BROADCAST_CONN_ADDR;
  179. pQos = &pIrlapCb->LocalQos;
  180. }
  181. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  182. return;
  183. pIMsg->IRDA_MSG_pWrite = Format_SNRM(pIMsg, ConnAddr,
  184. IRLAP_CMD,
  185. IRLAP_PFBIT_SET,
  186. pIrlapCb->LocalDevice.DevAddr,
  187. pIrlapCb->RemoteDevice.DevAddr,
  188. pIrlapCb->ConnAddr,
  189. pQos);
  190. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: SNRM")));
  191. SendFrame(pIrlapCb, pIMsg);
  192. }
  193. /*****************************************************************************
  194. *
  195. * @func UINT | SendUA | formats a UA frame and sends it
  196. *
  197. * @rdesc SUCCESS, otherwise one of the following errors:
  198. * @flag val | desc
  199. *
  200. * @parm BOOLEAN | SendQos | Send the Qos
  201. *
  202. * @comm
  203. * comments
  204. */
  205. VOID
  206. SendUA(PIRLAP_CB pIrlapCb, BOOLEAN SendQos)
  207. {
  208. IRDA_QOS_PARMS NegQos;
  209. IRDA_QOS_PARMS *pNegQos = NULL;
  210. UCHAR *pSrcAddr = NULL;
  211. UCHAR *pDestAddr = NULL;
  212. IRDA_MSG *pIMsg;
  213. if (SendQos)
  214. {
  215. // Put all parms (type 0 and 1) in NegQos
  216. RtlCopyMemory(&NegQos, &pIrlapCb->LocalQos, sizeof(IRDA_QOS_PARMS));
  217. // Overwrite type 0 parameters that have already been negotiated
  218. NegQos.bfBaud = pIrlapCb->NegotiatedQos.bfBaud;
  219. NegQos.bfDisconnectTime = pIrlapCb->NegotiatedQos.bfDisconnectTime;
  220. pNegQos = &NegQos;
  221. }
  222. // This will be moved into the "if" above when the spec is clarified
  223. pSrcAddr = pIrlapCb->LocalDevice.DevAddr;
  224. pDestAddr = pIrlapCb->RemoteDevice.DevAddr;
  225. //------------------------------------------------------------------
  226. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  227. return;
  228. pIMsg->IRDA_MSG_pWrite = Format_UA(pIMsg,
  229. pIrlapCb->ConnAddr,
  230. IRLAP_RSP,
  231. IRLAP_PFBIT_SET,
  232. pSrcAddr, pDestAddr, pNegQos);
  233. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: UA")));
  234. SendFrame(pIrlapCb, pIMsg);
  235. }
  236. /*****************************************************************************
  237. *
  238. * @func UINT | SendDM | formats a DM frame and sends it
  239. *
  240. * @rdesc SUCCESS, otherwise one of the following errors:
  241. * @flag val | desc
  242. *
  243. *
  244. * @comm
  245. * comments
  246. */
  247. VOID
  248. SendDM(PIRLAP_CB pIrlapCb)
  249. {
  250. IRDA_MSG *pIMsg;
  251. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  252. return;
  253. pIMsg->IRDA_MSG_pWrite = Format_DM(pIMsg,
  254. pIrlapCb->ConnAddr,
  255. IRLAP_RSP,
  256. IRLAP_PFBIT_SET);
  257. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: DM")));
  258. SendFrame(pIrlapCb, pIMsg);
  259. }
  260. /*****************************************************************************
  261. *
  262. * @func UINT | SendRD | formats a RD frame and sends it
  263. *
  264. * @rdesc SUCCESS, otherwise one of the following errors:
  265. * @flag val | desc
  266. *
  267. *
  268. * @comm
  269. * comments
  270. */
  271. VOID
  272. SendRD(PIRLAP_CB pIrlapCb)
  273. {
  274. IRDA_MSG *pIMsg;
  275. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  276. return;
  277. pIMsg->IRDA_MSG_pWrite = Format_RD(pIMsg,
  278. pIrlapCb->ConnAddr,
  279. IRLAP_RSP,
  280. IRLAP_PFBIT_SET);
  281. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: RD")));
  282. SendFrame(pIrlapCb, pIMsg);
  283. }
  284. /*****************************************************************************
  285. *
  286. * @func UINT | SendRR | formats a RR frame and sends it
  287. *
  288. * @rdesc SUCCESS, otherwise one of the following errors:
  289. * @flag val | desc
  290. *
  291. *
  292. * @comm
  293. * comments
  294. */
  295. VOID
  296. SendRR(PIRLAP_CB pIrlapCb)
  297. {
  298. IRDA_MSG *pIMsg;
  299. ClearRxWindow(pIrlapCb);
  300. pIrlapCb->RxWin.Start = pIrlapCb->Vr; // RxWin.Start = what we've acked
  301. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  302. return;
  303. pIMsg->IRDA_MSG_pWrite = Format_RR(pIMsg, pIrlapCb->ConnAddr,
  304. pIrlapCb->CRBit, IRLAP_PFBIT_SET,
  305. pIrlapCb->Vr);
  306. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: RR")));
  307. SendFrame(pIrlapCb, pIMsg);
  308. }
  309. /*****************************************************************************
  310. *
  311. * @func UINT | SendRNR | formats a RNR frame and sends it
  312. *
  313. * @rdesc SUCCESS, otherwise one of the following errors:
  314. * @flag val | desc
  315. *
  316. *
  317. * @comm
  318. * comments
  319. */
  320. VOID
  321. SendRR_RNR(PIRLAP_CB pIrlapCb)
  322. {
  323. IRDA_MSG *pIMsg;
  324. UCHAR *(*pFormatRR_RNR)();
  325. if (pIrlapCb->LocalBusy)
  326. {
  327. pFormatRR_RNR = Format_RNR;
  328. }
  329. else
  330. {
  331. pFormatRR_RNR = Format_RR;
  332. }
  333. ClearRxWindow(pIrlapCb);
  334. pIrlapCb->RxWin.Start = pIrlapCb->Vr; // RxWin.Start = what we've acked
  335. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  336. return;
  337. pIMsg->IRDA_MSG_pWrite = (*pFormatRR_RNR)(pIMsg, pIrlapCb->ConnAddr,
  338. pIrlapCb->CRBit, IRLAP_PFBIT_SET,
  339. pIrlapCb->Vr);
  340. IRLAP_LOG_ACTION((pIrlapCb, (TEXT("Tx: %s"), pFormatRR_RNR == Format_RNR? TEXT("RNR"):TEXT("RR"))));
  341. SendFrame(pIrlapCb, pIMsg);
  342. }
  343. /*****************************************************************************
  344. *
  345. * @func UINT | SendDISC | formats a DISC frame and sends it
  346. *
  347. * @rdesc SUCCESS, otherwise one of the following errors:
  348. * @flag val | desc
  349. *
  350. *
  351. * @comm
  352. * comments
  353. */
  354. VOID
  355. SendDISC(PIRLAP_CB pIrlapCb)
  356. {
  357. IRDA_MSG *pIMsg;
  358. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  359. return;
  360. pIMsg->IRDA_MSG_pWrite = Format_DISC(pIMsg, pIrlapCb->ConnAddr,
  361. IRLAP_CMD, IRLAP_PFBIT_SET);
  362. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: DISC")));
  363. SendFrame(pIrlapCb, pIMsg);
  364. }
  365. /*****************************************************************************
  366. *
  367. * @func UINT | SendRNRM | formats a RNRM frame and sends it
  368. *
  369. * @rdesc SUCCESS, otherwise one of the following errors:
  370. * @flag val | desc
  371. *
  372. *
  373. * @comm
  374. * comments
  375. */
  376. VOID
  377. SendRNRM(PIRLAP_CB pIrlapCb)
  378. {
  379. IRDA_MSG *pIMsg;
  380. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  381. return;
  382. pIMsg->IRDA_MSG_pWrite = Format_RNRM(pIMsg, pIrlapCb->ConnAddr,
  383. IRLAP_RSP, IRLAP_PFBIT_SET);
  384. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: RNRM")));
  385. SendFrame(pIrlapCb, pIMsg);
  386. }
  387. /*****************************************************************************
  388. *
  389. * @func UINT | SendREJ | formats a REJ frame and sends it
  390. *
  391. * @rdesc SUCCESS, otherwise one of the following errors:
  392. * @flag val | desc
  393. *
  394. *
  395. * @comm
  396. * comments
  397. */
  398. VOID
  399. SendREJ(PIRLAP_CB pIrlapCb)
  400. {
  401. IRDA_MSG *pIMsg;
  402. ClearRxWindow(pIrlapCb);
  403. pIrlapCb->RxWin.Start = pIrlapCb->Vr; // RxWin.Start = what we've acked
  404. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  405. return;
  406. pIMsg->IRDA_MSG_pWrite = Format_REJ(pIMsg, pIrlapCb->ConnAddr,
  407. pIrlapCb->CRBit, IRLAP_PFBIT_SET,
  408. pIrlapCb->Vr);
  409. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: REJ")));
  410. SendFrame(pIrlapCb, pIMsg);
  411. }
  412. /*****************************************************************************
  413. *
  414. * @func UINT | SendSREJ | formats a SREJ frame and sends it
  415. *
  416. * @rdesc SUCCESS, otherwise one of the following errors:
  417. * @flag val | desc
  418. *
  419. * @parm int | Nr | Nr to be placed in SREJ frame
  420. *
  421. * @comm
  422. * comments
  423. */
  424. VOID
  425. SendSREJ(PIRLAP_CB pIrlapCb, int Nr)
  426. {
  427. IRDA_MSG *pIMsg;
  428. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  429. return;
  430. pIMsg->IRDA_MSG_pWrite = Format_SREJ(pIMsg, pIrlapCb->ConnAddr,
  431. pIrlapCb->CRBit, IRLAP_PFBIT_SET,
  432. Nr);
  433. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: SREJ")));
  434. SendFrame(pIrlapCb, pIMsg);
  435. }
  436. /*****************************************************************************
  437. *
  438. * @func UINT | SendFRMR | formats a FRMR frame and sends it
  439. *
  440. * @rdesc SUCCESS, otherwise one of the following errors:
  441. * @flag val | desc
  442. *
  443. * @parm int | Nr | Nr to be placed in SREJ frame
  444. *
  445. * @comm
  446. * comments
  447. */
  448. VOID
  449. SendFRMR(PIRLAP_CB pIrlapCb, IRLAP_FRMR_FORMAT *pFRMRFormat)
  450. {
  451. IRDA_MSG *pIMsg;
  452. if (!(pIMsg = AllocTxMsg(pIrlapCb->pIrdaLinkCb)))
  453. return;
  454. pIMsg->IRDA_MSG_pWrite = Format_FRMR(pIMsg, pIrlapCb->ConnAddr,
  455. pIrlapCb->CRBit, IRLAP_PFBIT_SET,
  456. pFRMRFormat);
  457. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: FRMR")));
  458. SendFrame(pIrlapCb, pIMsg);
  459. }
  460. /*****************************************************************************
  461. *
  462. * @func UINT | SendIFrame | Builds and sends an I frame to MAC
  463. *
  464. * @rdesc SUCCESS otherwise one of the following errors:
  465. * @flag val | desc
  466. *
  467. * @parm | |
  468. *
  469. * @comm
  470. * comments
  471. */
  472. VOID
  473. SendIFrame(PIRLAP_CB pIrlapCb, PIRDA_MSG pMsg, int Ns, int PFBit)
  474. {
  475. if (NULL == pMsg)
  476. {
  477. ASSERT(0);
  478. return; // LOG AN ERROR !!!
  479. }
  480. ClearRxWindow(pIrlapCb);
  481. pIrlapCb->RxWin.Start = pIrlapCb->Vr; // RxWin.Start = what we've acked
  482. (void) Format_I(pMsg, pIrlapCb->ConnAddr, pIrlapCb->CRBit, PFBit,
  483. pIrlapCb->Vr, Ns);
  484. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: IFrame pMsg:%X"), pMsg));
  485. InterlockedIncrement(&pMsg->IRDA_MSG_RefCnt);
  486. #if DBG_CHECKSUM
  487. // print first and last 4 bytes of frame to help isolate
  488. // data corruption problem. Should be used with sledge
  489. if ((pMsg->IRDA_MSG_pWrite - pMsg->IRDA_MSG_pRead) > 3)
  490. DEBUGMSG(1, ("T(%X): %c%c%c%c, %c%c%c%c\n",
  491. pMsg->IRDA_MSG_pRead,
  492. *(pMsg->IRDA_MSG_pRead),
  493. *(pMsg->IRDA_MSG_pRead+1),
  494. *(pMsg->IRDA_MSG_pRead+2),
  495. *(pMsg->IRDA_MSG_pRead+3),
  496. *(pMsg->IRDA_MSG_pWrite-4),
  497. *(pMsg->IRDA_MSG_pWrite-3),
  498. *(pMsg->IRDA_MSG_pWrite-2),
  499. *(pMsg->IRDA_MSG_pWrite-1)));
  500. #endif
  501. SendFrame(pIrlapCb, pMsg);
  502. pMsg->IRDA_MSG_pHdrRead +=2; // uglyness.. chop header in case frame
  503. // requires retransmission
  504. return;
  505. }
  506. /*****************************************************************************
  507. *
  508. * @func UINT | SendUIFrame | Builds and sends an UI frame to MAC
  509. *
  510. * @rdesc SUCCESS otherwise one of the following errors:
  511. * @flag val | desc
  512. *
  513. * @parm | |
  514. *
  515. * @comm
  516. * comments
  517. */
  518. VOID
  519. SendUIFrame(PIRLAP_CB pIrlapCb, PIRDA_MSG pMsg)
  520. {
  521. if (NULL == pMsg)
  522. {
  523. ASSERT(0);
  524. return;
  525. }
  526. (void) Format_UI(pMsg, pIrlapCb->ConnAddr,
  527. pIrlapCb->CRBit,IRLAP_PFBIT_SET);
  528. InterlockedIncrement(&pMsg->IRDA_MSG_RefCnt);
  529. IRLAP_LOG_ACTION((pIrlapCb, TEXT("Tx: UIFrame")));
  530. SendFrame(pIrlapCb, pMsg);
  531. }
  532. /*****************************************************************************
  533. *
  534. * @func UINT | _IRLMP_Up | Adds logging to the IRLMP_Up
  535. *
  536. * @rdesc returns of IRLMP_Up
  537. *
  538. * @parm PIRDA_MSG | pMsg | pointer to IRDA message
  539. *
  540. * @comm
  541. * comments
  542. */
  543. /*
  544. UINT
  545. _IRLMP_Up(PIRDA_MSG pMsg)
  546. {
  547. IRLAP_LOG_ACTION((TEXT("%s%s"), IRDA_PrimStr[pMsg->Prim],
  548. pMsg->Prim == IRLAP_DISCOVERY_CONF ?
  549. IRDA_StatStr[pMsg->IRDA_MSG_DscvStatus] :
  550. pMsg->Prim == IRLAP_CONNECT_CONF ?
  551. IRDA_StatStr[pMsg->IRDA_MSG_ConnStatus] :
  552. pMsg->Prim == IRLAP_DISCONNECT_IND ?
  553. IRDA_StatStr[pMsg->IRDA_MSG_DiscStatus] :
  554. pMsg->Prim == IRLAP_DATA_CONF || pMsg->Prim == IRLAP_UDATA_CONF ?
  555. IRDA_StatStr[pMsg->IRDA_MSG_DataStatus] : TEXT("")));
  556. return (IRLMP_Up(pMsg));
  557. }
  558. */
  559. UCHAR *
  560. BuildTuple(UCHAR *pBuf, UCHAR Pi, UINT BitField)
  561. {
  562. *pBuf++ = Pi;
  563. if (BitField > 0xFF)
  564. {
  565. *pBuf++ = 2; // Pl
  566. *pBuf++ = (UCHAR) (BitField);
  567. *pBuf++ = (UCHAR) (BitField >> 8);
  568. }
  569. else
  570. {
  571. *pBuf++ = 1; // Pl
  572. *pBuf++ = (UCHAR) (BitField);
  573. }
  574. return pBuf;
  575. }
  576. UCHAR *
  577. BuildNegParms(UCHAR *pBuf, IRDA_QOS_PARMS *pQos)
  578. {
  579. pBuf = BuildTuple(pBuf, QOS_PI_BAUD, pQos->bfBaud);
  580. pBuf = BuildTuple(pBuf, QOS_PI_MAX_TAT, pQos->bfMaxTurnTime);
  581. pBuf = BuildTuple(pBuf, QOS_PI_DATA_SZ, pQos->bfDataSize);
  582. pBuf = BuildTuple(pBuf, QOS_PI_WIN_SZ, pQos->bfWindowSize);
  583. pBuf = BuildTuple(pBuf, QOS_PI_BOFS, pQos->bfBofs);
  584. pBuf = BuildTuple(pBuf, QOS_PI_MIN_TAT, pQos->bfMinTurnTime);
  585. pBuf = BuildTuple(pBuf, QOS_PI_DISC_THRESH, pQos->bfDisconnectTime);
  586. return pBuf;
  587. }
  588. void
  589. StoreULAddr(UCHAR Addr[], ULONG ULAddr)
  590. {
  591. Addr[0] = (UCHAR) ( 0xFF & ULAddr);
  592. Addr[1] = (UCHAR) ((0xFF00 & ULAddr) >> 8);
  593. Addr[2] = (UCHAR) ((0xFF0000 & ULAddr) >> 16);
  594. Addr[3] = (UCHAR) ((0xFF000000 & ULAddr) >> 24);
  595. }
  596. UCHAR *
  597. _PutAddr(UCHAR *pBuf, UCHAR Addr[])
  598. {
  599. *pBuf++ = Addr[0];
  600. *pBuf++ = Addr[1];
  601. *pBuf++ = Addr[2];
  602. *pBuf++ = Addr[3];
  603. return (pBuf);
  604. }
  605. void
  606. BuildUHdr(IRDA_MSG *pMsg, int FrameType, int Addr, int CRBit, int PFBit)
  607. {
  608. if (pMsg->IRDA_MSG_pHdrRead != NULL)
  609. {
  610. pMsg->IRDA_MSG_pHdrRead -= 2;
  611. ASSERT(pMsg->IRDA_MSG_pHdrRead >= pMsg->IRDA_MSG_Header);
  612. *(pMsg->IRDA_MSG_pHdrRead) = (UCHAR) _MAKE_ADDR(Addr, CRBit);
  613. *(pMsg->IRDA_MSG_pHdrRead+1) = (UCHAR) _MAKE_UCNTL(FrameType, PFBit);
  614. }
  615. else
  616. {
  617. pMsg->IRDA_MSG_pRead -= 2;
  618. *(pMsg->IRDA_MSG_pRead) = (UCHAR) _MAKE_ADDR(Addr, CRBit);
  619. *(pMsg->IRDA_MSG_pRead+1) = (UCHAR) _MAKE_UCNTL(FrameType, PFBit);
  620. }
  621. return;
  622. }
  623. void
  624. BuildSHdr(IRDA_MSG *pMsg, int FrameType, int Addr, int CRBit, int PFBit,
  625. int Nr)
  626. {
  627. if (pMsg->IRDA_MSG_pHdrRead != NULL)
  628. {
  629. pMsg->IRDA_MSG_pHdrRead -= 2;
  630. ASSERT(pMsg->IRDA_MSG_pHdrRead >= pMsg->IRDA_MSG_Header);
  631. *(pMsg->IRDA_MSG_pHdrRead) = (UCHAR) _MAKE_ADDR(Addr, CRBit);
  632. *(pMsg->IRDA_MSG_pHdrRead+1) = (UCHAR) _MAKE_SCNTL(FrameType,
  633. PFBit, Nr);
  634. }
  635. else
  636. {
  637. pMsg->IRDA_MSG_pRead -= 2;
  638. *(pMsg->IRDA_MSG_pRead) = (UCHAR) _MAKE_ADDR(Addr, CRBit);
  639. *(pMsg->IRDA_MSG_pRead+1) = (UCHAR) _MAKE_SCNTL(FrameType, PFBit, Nr);
  640. }
  641. return;
  642. }
  643. UCHAR *
  644. Format_SNRM(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, UCHAR SAddr[],
  645. UCHAR DAddr[], int CAddr, IRDA_QOS_PARMS *pQos)
  646. {
  647. BuildUHdr(pMsg, IRLAP_SNRM, Addr, CRBit, PFBit);
  648. if (pQos != NULL)
  649. {
  650. pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, SAddr);
  651. pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, DAddr);
  652. *pMsg->IRDA_MSG_pWrite++ = CAddr << 1; // Thats what the f'n spec says
  653. pMsg->IRDA_MSG_pWrite = BuildNegParms(pMsg->IRDA_MSG_pWrite, pQos);
  654. }
  655. return (pMsg->IRDA_MSG_pWrite);
  656. }
  657. UCHAR *
  658. Format_DISC(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
  659. {
  660. BuildUHdr(pMsg, IRLAP_DISC, Addr, CRBit, PFBit);
  661. return (pMsg->IRDA_MSG_pWrite);
  662. }
  663. UCHAR *
  664. Format_UI(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
  665. {
  666. BuildUHdr(pMsg, IRLAP_UI, Addr, CRBit, PFBit);
  667. return (pMsg->IRDA_MSG_pWrite);
  668. }
  669. UCHAR *
  670. Format_DscvXID(IRDA_MSG *pMsg, int ConnAddr, int CRBit, int PFBit,
  671. IRLAP_XID_DSCV_FORMAT *pXIDFormat,
  672. CHAR DscvInfo[], int DscvInfoLen)
  673. {
  674. if (pMsg->IRDA_MSG_pHdrRead != NULL)
  675. {
  676. pMsg->IRDA_MSG_pHdrRead -= 2;
  677. ASSERT(pMsg->IRDA_MSG_pHdrRead >= pMsg->IRDA_MSG_Header);
  678. *(pMsg->IRDA_MSG_pHdrRead) = (UCHAR) _MAKE_ADDR(ConnAddr, CRBit);
  679. if (CRBit)
  680. *(pMsg->IRDA_MSG_pHdrRead+1)=
  681. (UCHAR) _MAKE_UCNTL(IRLAP_XID_CMD, PFBit);
  682. else
  683. *(pMsg->IRDA_MSG_pHdrRead+1)=
  684. (UCHAR) _MAKE_UCNTL(IRLAP_XID_RSP, PFBit);
  685. }
  686. else
  687. {
  688. pMsg->IRDA_MSG_pRead -= 2;
  689. *(pMsg->IRDA_MSG_pRead) = (UCHAR) _MAKE_ADDR(ConnAddr, CRBit);
  690. if (CRBit)
  691. *(pMsg->IRDA_MSG_pRead+1)=
  692. (UCHAR) _MAKE_UCNTL(IRLAP_XID_CMD, PFBit);
  693. else
  694. *(pMsg->IRDA_MSG_pRead+1)=
  695. (UCHAR) _MAKE_UCNTL(IRLAP_XID_RSP, PFBit);
  696. }
  697. *pMsg->IRDA_MSG_pWrite++ = IRLAP_XID_DSCV_FORMAT_ID;
  698. RtlCopyMemory(pMsg->IRDA_MSG_pWrite, (CHAR *) pXIDFormat,
  699. sizeof(IRLAP_XID_DSCV_FORMAT) - 1); // Subtract for FirstDscvUCHAR
  700. // in structure
  701. pMsg->IRDA_MSG_pWrite += sizeof(IRLAP_XID_DSCV_FORMAT) - 1;
  702. if (DscvInfo != NULL)
  703. {
  704. RtlCopyMemory(pMsg->IRDA_MSG_pWrite, DscvInfo, DscvInfoLen);
  705. pMsg->IRDA_MSG_pWrite += DscvInfoLen;
  706. }
  707. return (pMsg->IRDA_MSG_pWrite);
  708. }
  709. UCHAR *
  710. Format_TEST(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit,
  711. UCHAR SAddr[], UCHAR DAddr[])
  712. {
  713. BuildUHdr(pMsg, IRLAP_TEST, Addr, CRBit, PFBit);
  714. pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, SAddr);
  715. pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, DAddr);
  716. return (pMsg->IRDA_MSG_pWrite);
  717. }
  718. UCHAR *
  719. Format_RNRM(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
  720. {
  721. BuildUHdr(pMsg, IRLAP_RNRM, Addr, CRBit, PFBit);
  722. return (pMsg->IRDA_MSG_pWrite);
  723. }
  724. UCHAR *
  725. Format_UA(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, UCHAR SAddr[],
  726. UCHAR DAddr[], IRDA_QOS_PARMS *pQos)
  727. {
  728. BuildUHdr(pMsg, IRLAP_UA, Addr, CRBit, PFBit);
  729. if (SAddr != NULL)
  730. {
  731. pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, SAddr);
  732. }
  733. if (DAddr != NULL)
  734. {
  735. pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, DAddr);
  736. }
  737. if (pQos != NULL)
  738. pMsg->IRDA_MSG_pWrite = BuildNegParms(pMsg->IRDA_MSG_pWrite, pQos);
  739. return (pMsg->IRDA_MSG_pWrite);
  740. }
  741. UCHAR *
  742. Format_FRMR(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit,
  743. IRLAP_FRMR_FORMAT *pFormat)
  744. {
  745. BuildUHdr(pMsg, IRLAP_FRMR, Addr, CRBit, PFBit);
  746. RtlCopyMemory(pMsg->IRDA_MSG_pWrite, (CHAR *)pFormat,
  747. sizeof(IRLAP_FRMR_FORMAT));
  748. pMsg->IRDA_MSG_pWrite += sizeof(IRLAP_FRMR_FORMAT);
  749. return (pMsg->IRDA_MSG_pWrite);
  750. }
  751. UCHAR *
  752. Format_DM(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
  753. {
  754. BuildUHdr(pMsg, IRLAP_DM, Addr, CRBit, PFBit);
  755. return (pMsg->IRDA_MSG_pWrite);
  756. }
  757. UCHAR *
  758. Format_RD(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
  759. {
  760. BuildUHdr(pMsg, IRLAP_RD, Addr, CRBit, PFBit);
  761. return (pMsg->IRDA_MSG_pWrite);
  762. }
  763. UCHAR *
  764. Format_RR(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr)
  765. {
  766. BuildSHdr(pMsg, IRLAP_RR, Addr, CRBit, PFBit, Nr);
  767. return (pMsg->IRDA_MSG_pWrite);
  768. }
  769. UCHAR *
  770. Format_RNR(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr)
  771. {
  772. BuildSHdr(pMsg, IRLAP_RNR, Addr, CRBit, PFBit, Nr);
  773. return (pMsg->IRDA_MSG_pWrite);
  774. }
  775. UCHAR *
  776. Format_REJ(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr)
  777. {
  778. BuildSHdr(pMsg, IRLAP_REJ, Addr, CRBit, PFBit, Nr);
  779. return (pMsg->IRDA_MSG_pWrite);
  780. }
  781. UCHAR *
  782. Format_SREJ(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr)
  783. {
  784. BuildSHdr(pMsg, IRLAP_SREJ, Addr, CRBit, PFBit, Nr);
  785. return (pMsg->IRDA_MSG_pWrite);
  786. }
  787. UCHAR *
  788. Format_I(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr, int Ns)
  789. {
  790. if (pMsg->IRDA_MSG_pHdrRead != NULL)
  791. {
  792. pMsg->IRDA_MSG_pHdrRead -= 2;
  793. ASSERT(pMsg->IRDA_MSG_pHdrRead >= pMsg->IRDA_MSG_Header);
  794. *(pMsg->IRDA_MSG_pHdrRead) = (UCHAR) _MAKE_ADDR(Addr, CRBit);
  795. *(pMsg->IRDA_MSG_pHdrRead+1) = (UCHAR) (((Ns & 7) << 1) +
  796. ((PFBit & 1)<< 4) + (Nr <<5));
  797. }
  798. else
  799. {
  800. pMsg->IRDA_MSG_pRead -= 2;
  801. *(pMsg->IRDA_MSG_pRead) = (UCHAR) _MAKE_ADDR(Addr, CRBit);
  802. *(pMsg->IRDA_MSG_pRead+1) = (UCHAR) (((Ns & 7) << 1) +
  803. ((PFBit & 1)<< 4) + (Nr <<5));
  804. }
  805. return (pMsg->IRDA_MSG_pWrite);
  806. }