Leaked source code of windows server 2003
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.

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