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.

1854 lines
52 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. callmgr.c
  5. Abstract:
  6. Call manager peice of the irda NDIS 5 miniport (WAN driver)
  7. Author:
  8. mbert 9-97
  9. RasIrda is a connection oriented Ndis 5 miniport with an integrated call manager.
  10. Proxy is the Ndis Tapi proxy (ndproxy.sys) and is the only client protocol that
  11. makes calls over RasIrda.
  12. Irda is a TDI transport driver (irda.sys). RasIrda uses irtdicl.lib to
  13. interface with irda.sys in order to abstract the complexity of the TDI client
  14. interface.
  15. *******************
  16. Standard Call Setup
  17. *******************
  18. Client Server
  19. Proxy RasIrda Irda RasIrda Proxy
  20. _______________________________________________________________________________
  21. RasIrCmCreateVc
  22. ---------------->
  23. RasIrCmMakeCall
  24. ---------------->
  25. IrdaDiscoverDevices
  26. IrdaOpenConnection
  27. -------------------->
  28. IrdaIncomingConnection
  29. ------------------>
  30. pVc->Flags =
  31. IRDA_OPEN
  32. NdisMCmCallComplete +RasIrCmCreateVc
  33. <----------------- pvc->Flags =
  34. CREATED_LOCAL
  35. pVc->Flags = IRDA_OPEN
  36. IRDA_OPEN
  37. VC_OPEN NdisMCmActivateVc
  38. ------------------>
  39. NdisMCmDispatchIncomingCall
  40. ------------------>
  41. RasIrCmIncomingCallComplete
  42. <----------------
  43. pVc->Flags =
  44. CREATED_LOCAL
  45. IRDA_OPEN
  46. VC_OPEN
  47. ===============================================================================
  48. *****************
  49. Client Disconnect
  50. *****************
  51. Client Server
  52. Proxy RasIrda Irda RasIrda Proxy
  53. _______________________________________________________________________________
  54. pVc->Flags = pVc->Flags =
  55. IRDA_OPEN CREATED_LOCAL
  56. VC_OPEN IRDA_OPEN
  57. VC_OPEN
  58. RasIrCmCloseCall
  59. --------------->
  60. IrdaCloseConnection
  61. ------------------->
  62. pVc->Flags =
  63. VC_OPEN
  64. IrdaConnectionClose
  65. ----------------->
  66. pVc->Flags =
  67. CREATED_LOCAL
  68. VC_OPEN
  69. NdisMCmCloseCallComplete
  70. <------------------
  71. IrdaCloseConnection
  72. <------------
  73. RasIrCmDeleteVc
  74. ----------------> NdisMCmDispatchIncomingCloseCall
  75. ----------------->
  76. RasIrCmCloseCall
  77. <---------------
  78. NdisMCmCloseCallComplete
  79. ------------------>
  80. +RasIrCmDeleteVc
  81. ===============================================================================
  82. *****************
  83. Server Disconnect
  84. *****************
  85. Client Server
  86. Proxy RasIrda Irda RasIrda Proxy
  87. _______________________________________________________________________________
  88. pVc->Flags = pVc->Flags =
  89. IRDA_OPEN CREATED_LOCAL
  90. VC_OPEN IRDA_OPEN
  91. VC_OPEN
  92. RasIrCmCloseCall
  93. <---------------
  94. IrdaCloseConnection
  95. <------------
  96. pVc->Flags =
  97. CREATED_LOCAL
  98. VC_OPEN
  99. IrdaConnectionClose NdisMCmCloseCallComplete
  100. <----------------- ------------------>
  101. pVc->Flags =
  102. VC_OPEN +RasIrCmDeleteVc
  103. IrdaCloseConnection
  104. --------------->
  105. NdisMCmDispathIncomingCloseConn
  106. <---------------------
  107. RasIrCmCloseCall
  108. --------------->
  109. NdisMCmCloseCallComplete
  110. <----------------------
  111. RasIrCmDeleteVc
  112. --------------->
  113. ===============================================================================
  114. --*/
  115. #include "rasirdap.h"
  116. NDIS_STATUS
  117. RasIrCmCreateVc(
  118. IN NDIS_HANDLE ProtocolAfContext,
  119. IN NDIS_HANDLE NdisVcHandle,
  120. OUT PNDIS_HANDLE ProtocolVcContext)
  121. {
  122. PRASIR_ADAPTER pAdapter = ProtocolAfContext;
  123. PRASIR_VC pVc;
  124. NDIS_STATUS Status;
  125. GOODADAPTER(pAdapter);
  126. NdisAllocateMemoryWithTag((PVOID *)&pVc, sizeof(RASIR_VC), MT_RASIR_VC);
  127. if (pVc == NULL)
  128. {
  129. DEBUGMSG(DBG_ERROR, ("RASIR: RasIrCmCreateVc failed, resources\n"));
  130. return NDIS_STATUS_RESOURCES;
  131. }
  132. NdisZeroMemory(pVc, sizeof(*pVc));
  133. #if DBG
  134. pVc->Sig = (ULONG) VC_SIG;
  135. #endif
  136. pVc->pAdapter = pAdapter;
  137. pVc->NdisVcHandle = NdisVcHandle;
  138. pVc->LinkInfo.MaxSendFrameSize = pAdapter->Info.MaxFrameSize;
  139. pVc->LinkInfo.MaxRecvFrameSize = pAdapter->Info.MaxFrameSize;
  140. pVc->LinkInfo.SendFramingBits = pAdapter->Info.FramingBits;
  141. pVc->LinkInfo.RecvFramingBits = pAdapter->Info.FramingBits;
  142. pVc->LinkInfo.SendACCM = (ULONG) -1;
  143. pVc->LinkInfo.RecvACCM = (ULONG) -1;
  144. InitializeListHead(&pVc->CompletedAsyncBufList);
  145. ReferenceInit(&pVc->RefCnt, pVc, DeleteVc);
  146. REFADD(&pVc->RefCnt, ' TS1');
  147. NdisInterlockedInsertTailList(&pAdapter->VcList,
  148. &pVc->Linkage,
  149. &pAdapter->SpinLock);
  150. NdisAllocatePacketPool(&Status,
  151. &pVc->RxPacketPool,
  152. IRTDI_RECV_BUF_CNT * 2, 0);
  153. if (Status != NDIS_STATUS_SUCCESS)
  154. {
  155. DEBUGMSG(DBG_ERROR, ("RASIR: NdisAllocatePacketPool failed %X\n",
  156. Status));
  157. goto done;
  158. }
  159. NdisAllocateBufferPool(&Status,
  160. &pVc->RxBufferPool,
  161. IRTDI_RECV_BUF_CNT);
  162. if (Status != NDIS_STATUS_SUCCESS)
  163. {
  164. DEBUGMSG(DBG_ERROR, ("RASIR: NdisAllocateBufferPool failed %X\n",
  165. Status));
  166. goto done;
  167. }
  168. *ProtocolVcContext = pVc;
  169. done:
  170. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmCreateVc status %X, vc:%X\n",
  171. Status, pVc));
  172. if (Status != NDIS_STATUS_SUCCESS)
  173. {
  174. REFDEL(&pVc->RefCnt, ' TS1');
  175. }
  176. return Status;
  177. }
  178. NDIS_STATUS
  179. RasIrCmDeleteVc(
  180. IN NDIS_HANDLE ProtocolVcContext)
  181. {
  182. PRASIR_VC pVc = ProtocolVcContext;
  183. PASYNC_BUFFER pAsyncBuf;
  184. GOODVC(pVc);
  185. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmDeleteVc vc:%X\n", pVc));
  186. if (pVc->pCurrAsyncBuf)
  187. {
  188. NdisFreeToNPagedLookasideList(&pVc->pAdapter->AsyncBufLList,
  189. pVc->pCurrAsyncBuf);
  190. }
  191. while ((pAsyncBuf = (PASYNC_BUFFER) NdisInterlockedRemoveHeadList(
  192. &pVc->CompletedAsyncBufList,
  193. &pVc->pAdapter->SpinLock)) != NULL)
  194. {
  195. NdisFreeToNPagedLookasideList(&pVc->pAdapter->AsyncBufLList,
  196. pAsyncBuf);
  197. }
  198. REFDEL(&pVc->RefCnt, ' TS1');
  199. return NDIS_STATUS_SUCCESS;
  200. }
  201. NDIS_STATUS
  202. RasIrCmOpenAf(
  203. IN NDIS_HANDLE CallMgrBindingContext,
  204. IN PCO_ADDRESS_FAMILY AddressFamily,
  205. IN NDIS_HANDLE NdisAfHandle,
  206. OUT PNDIS_HANDLE CallMgrAfContext)
  207. {
  208. PRASIR_ADAPTER pAdapter = (PRASIR_ADAPTER) CallMgrBindingContext;
  209. NDIS_HANDLE hExistingAf;
  210. GOODADAPTER(pAdapter);
  211. if ((AddressFamily->AddressFamily != CO_ADDRESS_FAMILY_TAPI_PROXY)) {
  212. DEBUGMSG(DBG_ERROR, ("RASIRDA: bad address family %08lx\n",AddressFamily->AddressFamily));
  213. return NDIS_STATUS_INVALID_ADDRESS;
  214. }
  215. pAdapter->Flags = 0;
  216. hExistingAf = (NDIS_HANDLE)
  217. InterlockedCompareExchangePointer(
  218. &pAdapter->NdisAfHandle, NdisAfHandle, NULL );
  219. if (hExistingAf)
  220. {
  221. // Our AF has already been opened and it doesn't make any sense to
  222. // accept another since there is no way to distinguish which should
  223. // receive incoming calls.
  224. //
  225. DEBUGMSG(DBG_ERROR, ("RASIR: OpenAddressFamily again!\n"));
  226. ASSERT( !"AF exists?" );
  227. return NDIS_STATUS_FAILURE;
  228. }
  229. *CallMgrAfContext = CallMgrBindingContext;
  230. return NDIS_STATUS_SUCCESS;
  231. }
  232. NDIS_STATUS
  233. RasIrCmCloseAf(
  234. IN NDIS_HANDLE CallMgrAfContext)
  235. {
  236. PRASIR_ADAPTER pAdapter = (PRASIR_ADAPTER) CallMgrAfContext;
  237. GOODADAPTER(pAdapter);
  238. if (pAdapter->NdisSapHandle != NULL)
  239. {
  240. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmCloseAf pending, Outstanding registered SAP\n"));
  241. pAdapter->Flags |= ADF_PENDING_AF_CLOSE;
  242. return NDIS_STATUS_PENDING;
  243. }
  244. else
  245. {
  246. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmCloseAf\n"));
  247. return NDIS_STATUS_SUCCESS;
  248. }
  249. }
  250. BOOLEAN
  251. CloseNextAdapterEndpoint(
  252. PRASIR_ADAPTER pAdapter)
  253. {
  254. PRASIR_IRDA_ENDPOINT pEndp;
  255. pEndp = (PRASIR_IRDA_ENDPOINT) NdisInterlockedRemoveHeadList(
  256. &pAdapter->EndpList,
  257. &pAdapter->SpinLock);
  258. //
  259. // Remove the first endpoint and close it.
  260. // The remaining endpoints are closed in
  261. // the completetion of this endpoint close
  262. // (see IrdaCloseEndpointComplete)
  263. //
  264. if (pEndp != NULL)
  265. {
  266. GOODENDP(pEndp);
  267. DEBUGMSG(DBG_CONNECT, ("RASIR: ->IrdaCloseEndpoint endp:%X\n",
  268. pEndp));
  269. IrdaCloseEndpoint(pEndp->IrdaEndpContext);
  270. return TRUE; // an endpoint was closed
  271. }
  272. return FALSE;
  273. }
  274. NDIS_STATUS
  275. OpenNewIrdaEndpoint(
  276. PRASIR_ADAPTER pAdapter,
  277. ULONG EndpointType,
  278. PCHAR ServiceName,
  279. ULONG ServiceNameSize)
  280. {
  281. PRASIR_IRDA_ENDPOINT pEndp;
  282. TDI_ADDRESS_IRDA ListenAddr;
  283. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  284. NdisAllocateMemoryWithTag((PVOID *) &pEndp,
  285. sizeof(RASIR_IRDA_ENDPOINT),
  286. MT_RASIR_ENDP);
  287. DEBUGMSG(DBG_CONNECT, ("RASIR: OpenNewIrdaEndpoint %X type %d on service %s\n",
  288. pEndp, EndpointType, ServiceName));
  289. if (pEndp == NULL)
  290. {
  291. Status = NDIS_STATUS_RESOURCES;
  292. goto EXIT;
  293. }
  294. pEndp->pAdapter = pAdapter;
  295. pEndp->EndpType = EndpointType;
  296. pEndp->Sig = (ULONG) ENDP_SIG;
  297. #if DBG
  298. RtlCopyMemory(pEndp->ServiceName,
  299. ServiceName,
  300. ServiceNameSize);
  301. #endif
  302. RtlCopyMemory(ListenAddr.irdaServiceName,
  303. ServiceName,
  304. ServiceNameSize);
  305. Status = IrdaOpenEndpoint(pEndp,
  306. &ListenAddr,
  307. &pEndp->IrdaEndpContext);
  308. EXIT:
  309. if (Status != NDIS_STATUS_SUCCESS)
  310. {
  311. DEBUGMSG(DBG_ERROR, ("RASIR: OpenNewIrdaEndpoint failed %X\n",
  312. Status));
  313. if (pEndp)
  314. {
  315. NdisFreeMemory(pEndp, 0, 0);
  316. }
  317. }
  318. else
  319. {
  320. NdisInterlockedInsertTailList(
  321. &pAdapter->EndpList,
  322. &pEndp->Linkage,
  323. &pAdapter->SpinLock);
  324. }
  325. return Status;
  326. }
  327. VOID
  328. RegisterSapPassive(
  329. IN NDIS_WORK_ITEM* pWork,
  330. IN VOID* pContext)
  331. {
  332. PRASIR_ADAPTER pAdapter = (PRASIR_ADAPTER) pContext;
  333. NDIS_STATUS Status;
  334. NDIS_HANDLE hOldSap;
  335. PRASIR_IRDA_ENDPOINT pEndp;
  336. GOODADAPTER(pAdapter);
  337. DEBUGMSG(DBG_CONNECT, ("RASIR: RegisterSapPassive\n"));
  338. NdisFreeToNPagedLookasideList(&pAdapter->WorkItemsLList, pWork);
  339. hOldSap = pAdapter->NdisSapHandle;
  340. if (pAdapter->ModemPort == FALSE)
  341. {
  342. Status = OpenNewIrdaEndpoint(pAdapter,
  343. EPT_DIRECT,
  344. RASIR_SERVICE_NAME_DIRECT,
  345. sizeof(RASIR_SERVICE_NAME_DIRECT));
  346. if (Status != NDIS_STATUS_SUCCESS)
  347. {
  348. goto EXIT;
  349. }
  350. Status = OpenNewIrdaEndpoint(pAdapter,
  351. EPT_ASYNC,
  352. RASIR_SERVICE_NAME_ASYNC,
  353. sizeof(RASIR_SERVICE_NAME_ASYNC));
  354. }
  355. else
  356. {
  357. DEBUGMSG(DBG_CONNECT, ("RASIR: Ignoring SAP registration for ModemPort\n"));
  358. Status = NDIS_STATUS_SUCCESS; // We don't except incoming connections for modems
  359. }
  360. if (Status != NDIS_STATUS_SUCCESS)
  361. {
  362. CloseNextAdapterEndpoint(pAdapter);
  363. goto EXIT;
  364. }
  365. EXIT:
  366. if (Status != NDIS_STATUS_SUCCESS)
  367. {
  368. pAdapter->NdisSapHandle = NULL;
  369. }
  370. NdisMCmRegisterSapComplete(Status, hOldSap, (NDIS_HANDLE) pAdapter);
  371. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmRegisterSapComplete status %X\n",
  372. Status));
  373. }
  374. NDIS_STATUS
  375. RasIrCmRegisterSap(
  376. IN NDIS_HANDLE CallMgrAfContext,
  377. IN PCO_SAP Sap,
  378. IN NDIS_HANDLE NdisSapHandle,
  379. OUT PNDIS_HANDLE CallMgrSapContext)
  380. {
  381. PRASIR_ADAPTER pAdapter = (PRASIR_ADAPTER) CallMgrAfContext;
  382. NDIS_HANDLE hExistingSap;
  383. NDIS_STATUS Status;
  384. GOODADAPTER(pAdapter);
  385. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmRegisterSap\n"));
  386. hExistingSap = (NDIS_HANDLE)
  387. InterlockedCompareExchangePointer(
  388. &pAdapter->NdisSapHandle, NdisSapHandle, NULL);
  389. if (hExistingSap)
  390. {
  391. // A SAP has already been registered and it doesn't make any sense to
  392. // accept another since there are no SAP parameters to distinguish
  393. // them.
  394. //
  395. DEBUGMSG(DBG_ERROR, ("RASIR: Registering SAP again, why. WHY??\n"));
  396. return NDIS_STATUS_SAP_IN_USE;
  397. }
  398. *CallMgrSapContext = (NDIS_HANDLE )pAdapter;
  399. Status = ScheduleWork(pAdapter, RegisterSapPassive, pAdapter);
  400. if (Status != NDIS_STATUS_SUCCESS)
  401. {
  402. InterlockedExchangePointer(&pAdapter->NdisSapHandle, NULL);
  403. return Status;
  404. }
  405. return NDIS_STATUS_PENDING;
  406. }
  407. VOID
  408. CompleteSapDeregistration(
  409. PRASIR_ADAPTER pAdapter)
  410. {
  411. NDIS_HANDLE hOldSap;
  412. GOODADAPTER(pAdapter);
  413. if ((pAdapter->Flags & ADF_SAP_DEREGISTERED) == 0)
  414. {
  415. //
  416. // Sap deregisteration never occured
  417. // (failure path for RegisterSap)
  418. //
  419. return;
  420. }
  421. NdisAcquireSpinLock(&pAdapter->SpinLock);
  422. hOldSap = pAdapter->NdisSapHandle;
  423. pAdapter->NdisSapHandle = NULL;
  424. NdisReleaseSpinLock(&pAdapter->SpinLock);
  425. if (hOldSap)
  426. {
  427. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmDeregisterSapComp\n"));
  428. NdisMCmDeregisterSapComplete(NDIS_STATUS_SUCCESS, hOldSap);
  429. }
  430. if (pAdapter->Flags & ADF_PENDING_AF_CLOSE)
  431. {
  432. pAdapter->Flags &= ~ADF_PENDING_AF_CLOSE;
  433. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmCloseAddresFamilyComplete hAf:%X\n",
  434. pAdapter->NdisAfHandle));
  435. NdisMCmCloseAddressFamilyComplete(NDIS_STATUS_SUCCESS,
  436. pAdapter->NdisAfHandle);
  437. }
  438. }
  439. VOID
  440. IrdaCloseEndpointComplete(
  441. IN PVOID ClEndpContext)
  442. {
  443. PRASIR_IRDA_ENDPOINT pEndp = (PRASIR_IRDA_ENDPOINT) ClEndpContext;
  444. PRASIR_ADAPTER pAdapter;
  445. GOODENDP(pEndp);
  446. pAdapter = pEndp->pAdapter;
  447. GOODADAPTER(pAdapter);
  448. DEBUGMSG(DBG_CONNECT, ("RASIR: IrdaCloseEndpointComplete adapter:%X, endp:%X\n",
  449. pAdapter, pEndp));
  450. pEndp->Sig = 0x66666666;
  451. NdisFreeMemory(pEndp, 0,0);
  452. if (CloseNextAdapterEndpoint(pAdapter) == FALSE)
  453. {
  454. CompleteSapDeregistration(pAdapter);
  455. }
  456. }
  457. VOID
  458. DeregisterSapPassive(
  459. IN NDIS_WORK_ITEM* pWork,
  460. IN VOID* pContext)
  461. {
  462. PRASIR_ADAPTER pAdapter = (PRASIR_ADAPTER) pContext;
  463. GOODADAPTER(pAdapter);
  464. DEBUGMSG(DBG_CONNECT, ("RASIR: DeregisterSapPassive\n"));
  465. NdisFreeToNPagedLookasideList(&pAdapter->WorkItemsLList, pWork);
  466. if (CloseNextAdapterEndpoint(pAdapter) == FALSE)
  467. {
  468. CompleteSapDeregistration(pAdapter);
  469. }
  470. }
  471. NDIS_STATUS
  472. RasIrCmDeregisterSap(
  473. NDIS_HANDLE CallMgrSapContext)
  474. {
  475. PRASIR_ADAPTER pAdapter = (PRASIR_ADAPTER) CallMgrSapContext;
  476. NDIS_STATUS Status;
  477. GOODADAPTER(pAdapter);
  478. pAdapter->Flags |= ADF_SAP_DEREGISTERED;
  479. Status = ScheduleWork(pAdapter, DeregisterSapPassive, pAdapter);
  480. if (Status != NDIS_STATUS_SUCCESS)
  481. {
  482. DEBUGMSG(DBG_ERROR, ("RASIR: RasIrCmDeregisterSap failed\n"));
  483. return Status;
  484. }
  485. DEBUGMSG(DBG_ERROR, ("RASIR: RasIrCmDeregisterSap pending\n"));
  486. return NDIS_STATUS_PENDING;
  487. }
  488. VOID
  489. CompleteMakeCall(
  490. PRASIR_VC pVc,
  491. NDIS_STATUS Status)
  492. {
  493. ULONG ConnectionSpeed;
  494. pVc->Flags &= ~VCF_MAKE_CALL_PEND;
  495. if (Status != NDIS_STATUS_SUCCESS)
  496. {
  497. goto COMPLETE_CALL;
  498. }
  499. AllocCallParms(pVc);
  500. if (pVc->IrModemCall)
  501. {
  502. ConnectionSpeed = pVc->ConnectionSpeed / 8;
  503. }
  504. else
  505. {
  506. ConnectionSpeed = IrdaGetConnectionSpeed(pVc->IrdaConnContext) / 8;
  507. }
  508. pVc->pMakeCall->CallMgrParameters->Receive.PeakBandwidth = ConnectionSpeed;
  509. pVc->pMakeCall->CallMgrParameters->Transmit.PeakBandwidth = ConnectionSpeed;
  510. DEBUGMSG(DBG_CONNECT, ("RASIR: Connection speed %d\n", ConnectionSpeed));
  511. Status = NdisMCmActivateVc(pVc->NdisVcHandle,
  512. pVc->pMakeCall);
  513. COMPLETE_CALL:
  514. NdisMCmMakeCallComplete(Status, pVc->NdisVcHandle, NULL, NULL,
  515. pVc->pMakeCall);
  516. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  517. if (Status == STATUS_SUCCESS)
  518. {
  519. pVc->Flags |= VCF_OPEN;
  520. REFADD(&pVc->RefCnt, 'NEPO');
  521. }
  522. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  523. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmMakeCallComplete status %X\n", Status));
  524. }
  525. NTSTATUS
  526. MakeIrdaConnection(
  527. PRASIR_VC pVc,
  528. PDEVICELIST pDevList,
  529. CHAR * ServiceName,
  530. int ServiceNameLen)
  531. {
  532. NTSTATUS Status;
  533. ULONG i;
  534. TDI_ADDRESS_IRDA IrdaAddr;
  535. DEBUGMSG(DBG_CONNECT, ("RASIR: Connect to service %s\n", ServiceName));
  536. //
  537. // Attempt a connection to all devices
  538. // in range until one succeeds
  539. //
  540. RtlCopyMemory(IrdaAddr.irdaServiceName,
  541. ServiceName,
  542. ServiceNameLen);
  543. for (i = 0; i < pDevList->numDevice; i++)
  544. {
  545. RtlCopyMemory(IrdaAddr.irdaDeviceID,
  546. pDevList->Device[i].irdaDeviceID, 4);
  547. Status = IrdaOpenConnection(&IrdaAddr, pVc, &pVc->IrdaConnContext, FALSE);
  548. DEBUGMSG(DBG_CONNECT, ("RASIR: Vc %X IrdaOpenConnection() to device %X, Status %X\n",
  549. pVc, IrdaAddr.irdaDeviceID, Status));
  550. if (Status == STATUS_SUCCESS)
  551. {
  552. break;
  553. }
  554. }
  555. return Status;
  556. }
  557. VOID
  558. IrdaCloseAddresses()
  559. {
  560. PRASIR_ADAPTER pAdapter, pNextAdapter;
  561. NdisAcquireSpinLock(&RasIrSpinLock);
  562. DEBUGMSG(DBG_ERROR, ("RASIR: Close addresses\n"));
  563. for (pAdapter = (PRASIR_ADAPTER) RasIrAdapterList.Flink;
  564. pAdapter != (PRASIR_ADAPTER) &RasIrAdapterList;
  565. pAdapter = pNextAdapter)
  566. {
  567. pNextAdapter = (PRASIR_ADAPTER) pAdapter->Linkage.Flink;
  568. NdisReleaseSpinLock(&RasIrSpinLock);
  569. DEBUGMSG(DBG_ERROR, ("RASIR: Close address on adapter %X\n", pAdapter));
  570. CloseNextAdapterEndpoint(pAdapter);
  571. NdisAcquireSpinLock(&RasIrSpinLock);
  572. }
  573. NdisReleaseSpinLock(&RasIrSpinLock);
  574. }
  575. VOID
  576. InitiateIrdaConnection(
  577. IN NDIS_WORK_ITEM *pWork,
  578. IN VOID *pContext)
  579. {
  580. PRASIR_VC pVc = pContext;
  581. PRASIR_ADAPTER pAdapter;
  582. NTSTATUS Status;
  583. CHAR DevListBuf[sizeof(DEVICELIST) - sizeof(IRDA_DEVICE_INFO) +
  584. (sizeof(IRDA_DEVICE_INFO) * 3)];
  585. PDEVICELIST pDevList = (PDEVICELIST) DevListBuf;
  586. ULONG DevListLen = sizeof(DevListBuf);
  587. DEBUGMSG(DBG_CONNECT, ("RASIR: InitiateIrdaConnection\n"));
  588. GOODVC(pVc);
  589. pAdapter = pVc->pAdapter;
  590. GOODADAPTER(pAdapter);
  591. NdisFreeToNPagedLookasideList(&pAdapter->WorkItemsLList, pWork);
  592. Status = IrdaDiscoverDevices(pDevList, &DevListLen);
  593. if (Status != STATUS_SUCCESS)
  594. {
  595. goto EXIT;
  596. }
  597. DEBUGMSG(DBG_CONNECT, ("RASIR: IrdaDiscoverDevices, %d devices found\n",
  598. pDevList->numDevice));
  599. if (pDevList->numDevice == 0)
  600. {
  601. DEBUGMSG(DBG_CONNECT, ("RASIR: No devices found\n"));
  602. Status = NDIS_STATUS_TAPI_DISCONNECTMODE_UNREACHABLE;
  603. goto EXIT;
  604. }
  605. // First attempt a direct connection. if it fails try a phone connection
  606. if (pVc->IrModemCall)
  607. {
  608. pVc->AsyncFraming = TRUE;
  609. pVc->ModemState = MS_OFFLINE;
  610. Status = MakeIrdaConnection(
  611. pVc,
  612. pDevList,
  613. RASIR_SERVICE_NAME_IRMODEM,
  614. sizeof(RASIR_SERVICE_NAME_IRMODEM));
  615. if (Status == STATUS_SUCCESS)
  616. {
  617. NdisAllocateBufferPool(&Status,
  618. &pVc->TxBufferPool,
  619. TX_BUF_POOL_SIZE);
  620. }
  621. }
  622. else
  623. {
  624. Status = MakeIrdaConnection(
  625. pVc,
  626. pDevList,
  627. RASIR_SERVICE_NAME_DIRECT,
  628. sizeof(RASIR_SERVICE_NAME_DIRECT));
  629. }
  630. if (Status != STATUS_SUCCESS)
  631. {
  632. DEBUGMSG(DBG_ERROR, ("RASIR: IrdaOpenConnection failed %X\n", Status));
  633. Status = NDIS_STATUS_TAPI_DISCONNECTMODE_REJECT;
  634. }
  635. else
  636. {
  637. pVc->Flags |= VCF_IRDA_OPEN;
  638. REFADD(&pVc->RefCnt, 'ADRI');
  639. }
  640. if (Status == NDIS_STATUS_SUCCESS && pVc->IrModemCall)
  641. {
  642. PASYNC_BUFFER pAsyncBuf;
  643. //
  644. // Start the IrDial exchange
  645. //
  646. pVc->ModemState = MS_CONNECTING;
  647. ASSERT(pVc->pOfflineNdisBuf == NULL);
  648. /*
  649. if (!BuildPhoneStrFromReg(pVc->OfflineSendBuf))
  650. {
  651. DEBUGMSG(DBG_ERROR, ("RASIR: Phone number not found\n"));
  652. Status = NDIS_STATUS_TAPI_DISCONNECTMODE_BADADDRESS;
  653. goto EXIT;
  654. //strcpy(pVc->OfflineSendBuf, "ATD8828823\r");
  655. //strcpy(pVc->OfflineSendBuf, "ATD7390181\r");
  656. }
  657. */
  658. //
  659. // Build the phone number string
  660. //
  661. {
  662. int i;
  663. char *pIn, *pOut;
  664. strcpy(pVc->OfflineSendBuf, "ATD");
  665. pOut = pVc->OfflineSendBuf+3;
  666. pIn = ((PUCHAR)&(pVc->pTmParams->DestAddress)) + pVc->pTmParams->DestAddress.Offset;
  667. // Tapi gives us a UNICODE number so fix it up
  668. for (i = 0; i < pVc->pTmParams->DestAddress.Length; i++)
  669. {
  670. if (*pIn != 0)
  671. {
  672. *pOut++ = *pIn;
  673. }
  674. pIn++;
  675. }
  676. *pOut++ = '\r';
  677. *pOut = 0;
  678. }
  679. NdisAllocateBuffer(&Status, &pVc->pOfflineNdisBuf,
  680. pVc->TxBufferPool,
  681. pVc->OfflineSendBuf, strlen(pVc->OfflineSendBuf));
  682. if (Status == NDIS_STATUS_SUCCESS)
  683. {
  684. REFADD(&pVc->RefCnt, 'DNES');
  685. DEBUGMSG(DBG_CONNECT, ("RASIR: Send dial string vc:%X, packet %X\n",
  686. pVc, pVc->pOfflineNdisBuf));
  687. IrdaSend(pVc->IrdaConnContext, pVc->pOfflineNdisBuf, RASIR_INTERNAL_SEND);
  688. return;
  689. }
  690. }
  691. EXIT:
  692. if (Status != NDIS_STATUS_SUCCESS && pVc->Flags & VCF_IRDA_OPEN)
  693. {
  694. IrdaCloseConnection(pVc->IrdaConnContext);
  695. }
  696. CompleteMakeCall(pVc, Status);
  697. }
  698. NDIS_STATUS
  699. RasIrCmMakeCall(
  700. IN NDIS_HANDLE CallMgrVcContext,
  701. IN OUT PCO_CALL_PARAMETERS CallParameters,
  702. IN NDIS_HANDLE NdisPartyHandle,
  703. OUT PNDIS_HANDLE CallMgrPartyContext)
  704. {
  705. PRASIR_VC pVc = CallMgrVcContext;
  706. PRASIR_ADAPTER pAdapter;
  707. PCO_SPECIFIC_PARAMETERS pMSpecifics;
  708. PCO_AF_TAPI_MAKE_CALL_PARAMETERS pTmParams;
  709. NDIS_STATUS Status = NDIS_STATUS_PENDING;
  710. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmMakeCall\n"));
  711. GOODVC(pVc);
  712. pAdapter = pVc->pAdapter;
  713. GOODADAPTER(pAdapter);
  714. if (CallParameters->Flags & (PERMANENT_VC | BROADCAST_VC | MULTIPOINT_VC))
  715. {
  716. Status = NDIS_STATUS_NOT_SUPPORTED;
  717. goto EXIT;
  718. }
  719. if (!CallParameters->MediaParameters)
  720. {
  721. Status = NDIS_STATUS_INVALID_DATA;
  722. goto EXIT;
  723. }
  724. pMSpecifics = &CallParameters->MediaParameters->MediaSpecific;
  725. if (pMSpecifics->Length < sizeof(CO_AF_TAPI_MAKE_CALL_PARAMETERS))
  726. {
  727. Status = NDIS_STATUS_INVALID_LENGTH;
  728. goto EXIT;
  729. }
  730. pTmParams = (CO_AF_TAPI_MAKE_CALL_PARAMETERS* )&pMSpecifics->Parameters;
  731. pVc->pMakeCall = CallParameters;
  732. pVc->pTmParams = pTmParams;
  733. if (CallMgrPartyContext)
  734. {
  735. *CallMgrPartyContext = NULL;
  736. }
  737. if (pAdapter->ModemPort)
  738. {
  739. pVc->IrModemCall = TRUE;
  740. }
  741. pVc->Flags |= VCF_MAKE_CALL_PEND;
  742. Status = ScheduleWork(pAdapter, InitiateIrdaConnection, pVc);
  743. EXIT:
  744. if (Status != NDIS_STATUS_SUCCESS)
  745. {
  746. DEBUGMSG(DBG_ERROR, ("RASIR: RasIrCmMakeCall failed %X\n",
  747. Status));
  748. InterlockedExchangePointer(&pAdapter->NdisSapHandle, NULL);
  749. return Status;
  750. }
  751. return NDIS_STATUS_PENDING;
  752. }
  753. VOID
  754. CompleteClose(PRASIR_VC pVc)
  755. {
  756. DEBUGMSG(DBG_CONNECT, ("RASIR: Complete close for vc:%X\n", pVc));
  757. REFADD(&pVc->RefCnt, 'DLOH');
  758. if (pVc->Flags & VCF_MAKE_CALL_PEND)
  759. {
  760. CompleteMakeCall(pVc, NDIS_STATUS_FAILURE);
  761. }
  762. if (pVc->Flags & VCF_OPEN)
  763. {
  764. NdisMCmDeactivateVc(pVc->NdisVcHandle);
  765. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmCloseCallComplete\n"));
  766. NdisMCmCloseCallComplete(NDIS_STATUS_SUCCESS,
  767. pVc->NdisVcHandle, NULL);
  768. REFDEL(&pVc->RefCnt, 'NEPO');
  769. }
  770. if (pVc->Flags & VCF_CREATED_LOCAL)
  771. {
  772. NDIS_STATUS Status;
  773. Status = NdisMCmDeleteVc(pVc->NdisVcHandle);
  774. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmDeleteVc returned %X\n",
  775. Status));
  776. RasIrCmDeleteVc((NDIS_HANDLE) pVc);
  777. }
  778. REFDEL(&pVc->RefCnt, 'DLOH');
  779. DEBUGMSG(DBG_CONNECT, ("RASIR: Close complete for vc:%X\n", pVc));
  780. }
  781. VOID
  782. InitiateCloseCall(
  783. IN NDIS_WORK_ITEM *pWork,
  784. IN VOID *pContext)
  785. {
  786. PRASIR_VC pVc = pContext;
  787. NdisFreeToNPagedLookasideList(&pVc->pAdapter->WorkItemsLList, pWork);
  788. GOODVC(pVc);
  789. DEBUGMSG(DBG_CONNECT, ("RASIR: InitiateCloseCall for vc:%X\n", pVc));
  790. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  791. if (pVc->Flags & VCF_IRDA_OPEN)
  792. {
  793. pVc->Flags &= ~VCF_IRDA_OPEN;
  794. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  795. ASSERT(pVc->IrdaConnContext);
  796. IrdaCloseConnection(pVc->IrdaConnContext);
  797. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  798. }
  799. if (pVc->OutstandingSends)
  800. {
  801. pVc->Flags |= VCF_CLOSE_PEND;
  802. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  803. DEBUGMSG(DBG_ERROR, ("RASIR: Outstanding sends, pending close\n"));
  804. }
  805. else
  806. {
  807. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  808. CompleteClose(pVc);
  809. }
  810. }
  811. NDIS_STATUS
  812. RasIrCmCloseCall(
  813. IN NDIS_HANDLE CallMgrVcContext,
  814. IN NDIS_HANDLE CallMgrPartyContext,
  815. IN PVOID CloseData,
  816. IN UINT Size)
  817. {
  818. PRASIR_VC pVc = CallMgrVcContext;
  819. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmCloseCall vc:%X\n", pVc));
  820. GOODVC(pVc);
  821. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  822. if (pVc->Flags & VCF_MAKE_CALL_PEND)
  823. {
  824. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  825. DEBUGMSG(DBG_CONNECT, ("RASIR: Make call is pending, not accepting close call\n"));
  826. return NDIS_STATUS_NOT_ACCEPTED;
  827. }
  828. pVc->Flags |= VCF_CLOSING;
  829. if (!(pVc->Flags & VCF_OPEN) && !(pVc->Flags & VCF_IRDA_OPEN))
  830. {
  831. DEBUGMSG(DBG_CONNECT, ("RASIR: IrDA and VC not open\n"));
  832. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  833. return NDIS_STATUS_SUCCESS;
  834. }
  835. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  836. ScheduleWork(pVc->pAdapter, InitiateCloseCall, pVc);
  837. return NDIS_STATUS_PENDING;
  838. }
  839. VOID
  840. RasIrCmIncomingCallComplete(
  841. IN NDIS_STATUS Status,
  842. IN NDIS_HANDLE CallMgrVcContext,
  843. IN PCO_CALL_PARAMETERS CallParameters)
  844. {
  845. PRASIR_VC pVc = CallMgrVcContext;
  846. PRASIR_ADAPTER pAdapter;
  847. // WAN_CO_LINKPARAMS WanCoLinkParams;
  848. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmIncomingCallComplete status %X\n",
  849. Status));
  850. GOODVC(pVc);
  851. pAdapter = pVc->pAdapter;
  852. GOODADAPTER(pAdapter);
  853. if (Status != NDIS_STATUS_SUCCESS)
  854. {
  855. NdisMCmDeactivateVc(pVc->NdisVcHandle);
  856. RasIrCmCloseCall(pVc, NULL, NULL, 0);
  857. return;
  858. }
  859. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmDispatchCallConnected\n"));
  860. NdisMCmDispatchCallConnected(pVc->NdisVcHandle);
  861. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  862. pVc->Flags |= VCF_OPEN;
  863. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  864. /* Don't need to do this
  865. WanCoLinkParams.TransmitSpeed = 4000000;
  866. WanCoLinkParams.ReceiveSpeed = 4000000;
  867. WanCoLinkParams.SendWindow = 10;
  868. NdisMCoIndicateStatus(
  869. pAdapter->MiniportAdapterHandle,
  870. pVc->NdisVcHandle,
  871. NDIS_STATUS_WAN_CO_LINKPARAMS,
  872. &WanCoLinkParams,
  873. sizeof(WanCoLinkParams));
  874. */
  875. REFADD(&pVc->RefCnt, 'NEPO');
  876. }
  877. VOID
  878. RasIrCmActivateVcComplete(
  879. IN NDIS_STATUS Status,
  880. IN NDIS_HANDLE CallMgrVcContext,
  881. IN PCO_CALL_PARAMETERS CallParameters)
  882. {
  883. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmActivateVcComplete\n"));
  884. DbgBreakPoint();
  885. return;
  886. }
  887. VOID
  888. RasIrCmDeactivateVcComplete(
  889. IN NDIS_STATUS Status,
  890. IN NDIS_HANDLE CallMgrVcContext)
  891. {
  892. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmDeactivateVcComplete\n"));
  893. DbgBreakPoint();
  894. return;
  895. }
  896. NDIS_STATUS
  897. RasIrCmModifyCallQoS(
  898. IN NDIS_HANDLE CallMgrVcContext,
  899. IN PCO_CALL_PARAMETERS CallParameters)
  900. {
  901. DEBUGMSG(DBG_CONNECT, ("RASIR: RasIrCmModifyCallQos\n"));
  902. DbgBreakPoint();
  903. return 0;
  904. }
  905. VOID
  906. DeleteVc(
  907. IN PRASIR_VC pVc)
  908. {
  909. GOODVC(pVc);
  910. DEBUGMSG(DBG_CONNECT, ("RASIR: Deleting vc:%X\n", pVc));
  911. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  912. RemoveEntryList(&pVc->Linkage);
  913. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  914. NdisFreePacketPool(pVc->RxPacketPool);
  915. NdisFreeBufferPool(pVc->RxBufferPool);
  916. if (pVc->TxBufferPool)
  917. {
  918. NdisFreeBufferPool(pVc->TxBufferPool);
  919. }
  920. #if DBG
  921. pVc->Sig = 0xBAD;
  922. #endif
  923. if (pVc->pInCallParms)
  924. {
  925. NdisFreeMemory(pVc->pInCallParms, 0, 0); // yikes, 0 len :)
  926. }
  927. NdisFreeMemory(pVc, 0, 0);
  928. }
  929. NTSTATUS
  930. IrdaIncomingConnection(
  931. PVOID ClEndpContext,
  932. PVOID ConnectionContext,
  933. PVOID *pClConnContext)
  934. {
  935. PRASIR_IRDA_ENDPOINT pEndp = (PRASIR_IRDA_ENDPOINT) ClEndpContext;
  936. PRASIR_ADAPTER pAdapter;
  937. PRASIR_VC pVc;
  938. NDIS_STATUS Status;
  939. CO_CALL_PARAMETERS* pCp;
  940. ULONG ConnectionSpeed;
  941. GOODENDP(pEndp);
  942. pAdapter = pEndp->pAdapter;
  943. GOODADAPTER(pAdapter);
  944. DEBUGMSG(DBG_CONNECT, ("RASIR: IrdaIncomingConnection, type %d service %s\n",
  945. pEndp->EndpType, pEndp->ServiceName));
  946. Status = RasIrCmCreateVc(pAdapter,
  947. NULL,
  948. &pVc);
  949. if (Status != NDIS_STATUS_SUCCESS)
  950. {
  951. goto error1;
  952. }
  953. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  954. pVc->IrdaConnContext = ConnectionContext;
  955. pVc->Flags |= VCF_CREATED_LOCAL;
  956. pVc->AsyncFraming = (pEndp->EndpType == EPT_DIRECT ? FALSE : TRUE);
  957. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  958. AllocCallParms(pVc);
  959. pCp = (CO_CALL_PARAMETERS *) pVc->pInCallParms;
  960. if (pVc->pInCallParms == NULL)
  961. {
  962. goto error2;
  963. }
  964. if (pVc->AsyncFraming)
  965. {
  966. NdisAllocateBufferPool(&Status,
  967. &pVc->TxBufferPool,
  968. TX_BUF_POOL_SIZE);
  969. if (Status != NDIS_STATUS_SUCCESS)
  970. {
  971. goto error2;
  972. }
  973. }
  974. Status = NdisMCmCreateVc(pAdapter->MiniportAdapterHandle,
  975. pAdapter->NdisAfHandle,
  976. pVc,
  977. &pVc->NdisVcHandle);
  978. if (Status != NDIS_STATUS_SUCCESS)
  979. {
  980. DEBUGMSG(DBG_ERROR, ("RASIR: NdisMCmCreateVc failed %X\n", Status));
  981. goto error2;
  982. }
  983. Status = NdisMCmActivateVc(pVc->NdisVcHandle, pCp);
  984. if (Status != NDIS_STATUS_SUCCESS)
  985. {
  986. DEBUGMSG(DBG_ERROR, ("RASIR: NdisMCmActivateVc failed %X\n", Status));
  987. goto error3;
  988. }
  989. ConnectionSpeed = IrdaGetConnectionSpeed(pVc->IrdaConnContext) / 8;
  990. DEBUGMSG(DBG_CONNECT, ("RASIR: Connection speed %d\n", ConnectionSpeed));
  991. pCp->CallMgrParameters->Receive.PeakBandwidth = ConnectionSpeed;
  992. pCp->CallMgrParameters->Transmit.PeakBandwidth = ConnectionSpeed;
  993. Status = NdisMCmDispatchIncomingCall(pAdapter->NdisSapHandle,
  994. pVc->NdisVcHandle,
  995. pCp);
  996. if (!(pVc->Flags & VCF_CLOSING))
  997. {
  998. pVc->Flags |= VCF_IRDA_OPEN;
  999. REFADD(&pVc->RefCnt, 'ADRI');
  1000. *pClConnContext = pVc;
  1001. switch (Status)
  1002. {
  1003. case NDIS_STATUS_SUCCESS:
  1004. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmDispatchIncomingCall completed synchronously\n"));
  1005. RasIrCmIncomingCallComplete(Status, pVc, NULL);
  1006. return STATUS_SUCCESS;
  1007. case NDIS_STATUS_PENDING:
  1008. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmDispatchIncomingCall returned pending\n"));
  1009. return STATUS_SUCCESS;
  1010. }
  1011. }
  1012. DEBUGMSG(DBG_ERROR, ("RASIR: NdisMCmDispatchIncomingCall failed %X\n",
  1013. Status));
  1014. NdisMCmDeactivateVc(pVc->NdisVcHandle);
  1015. error3:
  1016. NdisMCmDeleteVc(pVc->NdisVcHandle);
  1017. error2:
  1018. RasIrCmDeleteVc(pVc);
  1019. error1:
  1020. return STATUS_UNSUCCESSFUL;
  1021. }
  1022. VOID
  1023. IrdaConnectionClosed(
  1024. PVOID ConnectionContext)
  1025. {
  1026. PRASIR_VC pVc = ConnectionContext;
  1027. GOODVC(pVc);
  1028. DEBUGMSG(DBG_CONNECT, ("RASIR: IrdaConnectionClose vc:%X\n", pVc));
  1029. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  1030. if (!(pVc->Flags & VCF_IRDA_OPEN))
  1031. {
  1032. DEBUGMSG(DBG_CONNECT, (" Irda not open\n"));
  1033. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  1034. return;
  1035. }
  1036. pVc->Flags &= ~VCF_IRDA_OPEN;
  1037. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  1038. IrdaCloseConnection(pVc->IrdaConnContext);
  1039. DEBUGMSG(DBG_CONNECT, ("RASIR: ->NdisMCmDispatchIncomingCloseCall\n"));
  1040. NdisMCmDispatchIncomingCloseCall(
  1041. NDIS_STATUS_SUCCESS,
  1042. pVc->NdisVcHandle,
  1043. NULL, 0);
  1044. }
  1045. VOID
  1046. IrdaCloseConnectionComplete(
  1047. PVOID ConnectionContext)
  1048. {
  1049. PRASIR_VC pVc = ConnectionContext;
  1050. GOODVC(pVc);
  1051. DEBUGMSG(DBG_CONNECT, ("RASIR: IrdaCloseConnectionComplete vc:%X\n", pVc));
  1052. REFDEL(&pVc->RefCnt, 'ADRI');
  1053. }
  1054. VOID
  1055. AllocCallParms(
  1056. IN PRASIR_VC pVc)
  1057. {
  1058. CO_CALL_PARAMETERS* pCp;
  1059. CO_CALL_MANAGER_PARAMETERS* pCmp;
  1060. CO_MEDIA_PARAMETERS* pMp;
  1061. ULONG CallParmsSize;
  1062. CO_AF_TAPI_INCOMING_CALL_PARAMETERS* pTi;
  1063. LINE_CALL_INFO* pLci;
  1064. ASSERT(pVc->pInCallParms == NULL);
  1065. if (pVc->pInCallParms != NULL)
  1066. {
  1067. return;
  1068. }
  1069. // no attempt here to hide the beauty of CoNdis.
  1070. CallParmsSize = sizeof(CO_CALL_PARAMETERS) +
  1071. + sizeof(CO_CALL_MANAGER_PARAMETERS)
  1072. + sizeof(CO_MEDIA_PARAMETERS)
  1073. + sizeof(CO_AF_TAPI_INCOMING_CALL_PARAMETERS)
  1074. + sizeof(LINE_CALL_INFO);
  1075. NdisAllocateMemoryWithTag((PVOID *)&pVc->pInCallParms,
  1076. CallParmsSize, MT_RASIR_CALLPARMS);
  1077. if (pVc->pInCallParms == NULL)
  1078. {
  1079. return;
  1080. }
  1081. NdisZeroMemory(pVc->pInCallParms, CallParmsSize);
  1082. pCp = (CO_CALL_PARAMETERS* )pVc->pInCallParms;
  1083. pCmp = (PCO_CALL_MANAGER_PARAMETERS )(pCp + 1);
  1084. pCp->CallMgrParameters = pCmp;
  1085. pCmp->Transmit.TokenRate =
  1086. pCmp->Transmit.PeakBandwidth =
  1087. pCmp->Receive.TokenRate =
  1088. pCmp->Receive.PeakBandwidth = RASIR_MAX_RATE/8;
  1089. pMp = (PCO_MEDIA_PARAMETERS )(pCmp + 1);
  1090. pCp->MediaParameters = pMp;
  1091. pMp->ReceiveSizeHint = IRDA_MAX_DATA_SIZE;
  1092. pMp->MediaSpecific.Length = sizeof(CO_AF_TAPI_INCOMING_CALL_PARAMETERS)
  1093. + sizeof(LINE_CALL_INFO);
  1094. pTi = (CO_AF_TAPI_INCOMING_CALL_PARAMETERS* )
  1095. pMp->MediaSpecific.Parameters;
  1096. pTi->ulLineID = 0;
  1097. pTi->ulAddressID = CO_TAPI_ADDRESS_ID_UNSPECIFIED;
  1098. pTi->ulFlags = CO_TAPI_FLAG_INCOMING_CALL;
  1099. pTi->LineCallInfo.Length = sizeof(LINE_CALL_INFO);
  1100. pTi->LineCallInfo.MaximumLength = sizeof(LINE_CALL_INFO);
  1101. pTi->LineCallInfo.Offset = sizeof(pTi->LineCallInfo);
  1102. pLci = (LINE_CALL_INFO* )(pTi + 1);
  1103. pLci->ulTotalSize = sizeof(LINE_CALL_INFO);
  1104. pLci->ulNeededSize = sizeof(LINE_CALL_INFO);
  1105. pLci->ulUsedSize = sizeof(LINE_CALL_INFO);
  1106. pLci->ulLineDeviceID = pTi->ulLineID;
  1107. pLci->ulBearerMode = LINEBEARERMODE_DATA;
  1108. pLci->ulMediaMode = LINEMEDIAMODE_DIGITALDATA;
  1109. pLci->ulRate = RASIR_MAX_RATE;
  1110. pVc->pTiParams = pTi;
  1111. }
  1112. NDIS_STATUS
  1113. QueryCmInformation(
  1114. IN PRASIR_ADAPTER pAdapter,
  1115. IN PRASIR_VC pVc,
  1116. IN NDIS_OID Oid,
  1117. IN PVOID InformationBuffer,
  1118. IN ULONG InformationBufferLength,
  1119. OUT PULONG BytesWritten,
  1120. OUT PULONG BytesNeeded)
  1121. // Handle Call Manager QueryInformation requests. Arguments are as for
  1122. // the standard NDIS 'MiniportQueryInformation' handler except this
  1123. // routine does not count on being serialized with respect to other
  1124. // requests.
  1125. //
  1126. {
  1127. NDIS_STATUS Status;
  1128. ULONG ulInfo;
  1129. VOID* pInfo;
  1130. ULONG ulInfoLen;
  1131. ULONG extension;
  1132. ULONG ulPortIndex;
  1133. Status = NDIS_STATUS_SUCCESS;
  1134. // The cases in this switch statement find or create a buffer containing
  1135. // the requested information and point 'pInfo' at it, noting it's length
  1136. // in 'ulInfoLen'. Since many of the OIDs return a ULONG, a 'ulInfo'
  1137. // buffer is set up as the default.
  1138. //
  1139. ulInfo = 0;
  1140. pInfo = &ulInfo;
  1141. ulInfoLen = sizeof(ulInfo);
  1142. switch (Oid)
  1143. {
  1144. case OID_CO_TAPI_CM_CAPS:
  1145. {
  1146. CO_TAPI_CM_CAPS caps;
  1147. NTSTATUS statusDevice;
  1148. DEBUGMSG(DBG_CONFIG, ("RASIR: QueryCm OID_CO_TAPI_CM_CAPS\n"));
  1149. NdisZeroMemory( &caps, sizeof(caps) );
  1150. //
  1151. // Report 2 lines, 1 for phone and 1 for DCC
  1152. //
  1153. caps.ulCoTapiVersion = CO_TAPI_VERSION;
  1154. caps.ulNumLines = 1;
  1155. caps.ulFlags = CO_TAPI_FLAG_PER_LINE_CAPS;
  1156. pInfo = &caps;
  1157. ulInfoLen = sizeof(caps);
  1158. break;
  1159. }
  1160. case OID_CO_TAPI_LINE_CAPS:
  1161. {
  1162. RASIR_CO_TAPI_LINE_CAPS RasIrLineCaps;
  1163. CO_TAPI_LINE_CAPS* pInCaps;
  1164. LINE_DEV_CAPS* pldc;
  1165. ULONG ulPortForLineId;
  1166. if (InformationBufferLength < sizeof(RASIR_CO_TAPI_LINE_CAPS))
  1167. {
  1168. Status = NDIS_STATUS_INVALID_DATA;
  1169. ulInfoLen = 0;
  1170. break;
  1171. }
  1172. ASSERT( InformationBuffer );
  1173. pInCaps = (CO_TAPI_LINE_CAPS* )InformationBuffer;
  1174. DEBUGMSG(DBG_CONFIG, ("RASIR: QueryCm OID_CO_TAPI_LINE_CAPS line %d\n",
  1175. pInCaps->ulLineID));
  1176. NdisZeroMemory(&RasIrLineCaps, sizeof(RasIrLineCaps));
  1177. pldc = &RasIrLineCaps.caps.LineDevCaps;
  1178. // get the LineId from the incoming pInCaps (CO_TAPI_LINE_CAPS)
  1179. //
  1180. RasIrLineCaps.caps.ulLineID = pInCaps->ulLineID;
  1181. pldc->ulPermanentLineID = RasIrLineCaps.caps.ulLineID;
  1182. pldc->ulTotalSize = pInCaps->LineDevCaps.ulTotalSize;
  1183. pldc->ulNeededSize = (ULONG ) ((CHAR* )(&RasIrLineCaps + 1) - (CHAR* )(&RasIrLineCaps.caps.LineDevCaps));
  1184. pldc->ulUsedSize = pldc->ulNeededSize;
  1185. pldc->ulNumAddresses = 1;
  1186. pldc->ulBearerModes = LINEBEARERMODE_DATA;
  1187. pldc->ulMaxRate = RASIR_MAX_RATE;
  1188. pldc->ulMediaModes = LINEMEDIAMODE_UNKNOWN | LINEMEDIAMODE_DIGITALDATA;
  1189. pldc->ulStringFormat = STRINGFORMAT_ASCII;
  1190. pldc->ulLineNameOffset = (ULONG ) ((CHAR* )RasIrLineCaps.LineName - (CHAR* )pldc);
  1191. if (pAdapter->ModemPort)
  1192. {
  1193. pldc->ulMaxNumActiveCalls = 1;
  1194. }
  1195. else
  1196. {
  1197. pldc->ulMaxNumActiveCalls = 4;
  1198. }
  1199. RtlCopyMemory(RasIrLineCaps.LineName, pAdapter->TapiLineName.Buffer, pAdapter->TapiLineName.Length);
  1200. pldc->ulLineNameSize = pAdapter->TapiLineName.Length;
  1201. pInfo = &RasIrLineCaps;
  1202. ulInfoLen = sizeof(RasIrLineCaps);
  1203. break;
  1204. }
  1205. case OID_CO_TAPI_ADDRESS_CAPS:
  1206. {
  1207. CO_TAPI_ADDRESS_CAPS caps;
  1208. CO_TAPI_ADDRESS_CAPS* pInCaps;
  1209. LINE_ADDRESS_CAPS* plac;
  1210. if (InformationBufferLength < sizeof(CO_TAPI_ADDRESS_CAPS))
  1211. {
  1212. Status = NDIS_STATUS_INVALID_DATA;
  1213. ulInfoLen = 0;
  1214. break;
  1215. }
  1216. ASSERT( InformationBuffer );
  1217. pInCaps = (CO_TAPI_ADDRESS_CAPS* )InformationBuffer;
  1218. NdisZeroMemory( &caps, sizeof(caps) );
  1219. caps.ulLineID = pInCaps->ulLineID;
  1220. caps.ulAddressID = pInCaps->ulAddressID;
  1221. plac = &caps.LineAddressCaps;
  1222. if (pAdapter->ModemPort)
  1223. {
  1224. plac->ulAddrCapFlags = LINEADDRCAPFLAGS_DIALED;
  1225. DEBUGMSG(DBG_CONFIG, ("RASIR: QueryCm OID_CO_TAPI_ADDRESS_CAPS line %d address %d, DIALED\n",
  1226. pInCaps->ulLineID, pInCaps->ulAddressID));
  1227. }
  1228. else
  1229. {
  1230. DEBUGMSG(DBG_CONFIG, ("RASIR: QueryCm OID_CO_TAPI_ADDRESS_CAPS line %d address %d, DCC\n",
  1231. pInCaps->ulLineID, pInCaps->ulAddressID));
  1232. }
  1233. plac->ulTotalSize = sizeof(LINE_ADDRESS_CAPS);
  1234. plac->ulNeededSize = sizeof(LINE_ADDRESS_CAPS);
  1235. plac->ulUsedSize = sizeof(LINE_ADDRESS_CAPS);
  1236. plac->ulLineDeviceID = caps.ulLineID;
  1237. plac->ulMaxNumActiveCalls = 64;
  1238. pInfo = &caps;
  1239. ulInfoLen = sizeof(caps);
  1240. break;
  1241. }
  1242. case OID_CO_TAPI_GET_CALL_DIAGNOSTICS:
  1243. {
  1244. CO_TAPI_CALL_DIAGNOSTICS diags;
  1245. DEBUGMSG(DBG_CONFIG, ("RASIR: QueryCm OID_CO_TAPI_GET_CALL_DIAGS\n"));
  1246. if (!pVc)
  1247. {
  1248. Status = NDIS_STATUS_INVALID_DATA;
  1249. ulInfoLen = 0;
  1250. break;
  1251. }
  1252. NdisZeroMemory( &diags, sizeof(diags) );
  1253. diags.ulOrigin = pVc->Flags & VCF_CREATED_LOCAL ?
  1254. LINECALLORIGIN_EXTERNAL : LINECALLORIGIN_OUTBOUND;
  1255. diags.ulReason = LINECALLREASON_DIRECT;
  1256. pInfo = &diags;
  1257. ulInfoLen = sizeof(diags);
  1258. break;
  1259. }
  1260. default:
  1261. {
  1262. DEBUGMSG(DBG_ERROR, ("RASIR: QueryCm OID not supported %X\n", Oid));
  1263. Status = NDIS_STATUS_NOT_SUPPORTED;
  1264. ulInfoLen = 0;
  1265. break;
  1266. }
  1267. }
  1268. if (ulInfoLen > InformationBufferLength)
  1269. {
  1270. // Caller's buffer is too small. Tell him what he needs.
  1271. //
  1272. *BytesNeeded = ulInfoLen;
  1273. Status = NDIS_STATUS_INVALID_LENGTH;
  1274. }
  1275. else
  1276. {
  1277. // Copy the found result to caller's buffer.
  1278. //
  1279. if (ulInfoLen > 0)
  1280. {
  1281. NdisMoveMemory( InformationBuffer, pInfo, ulInfoLen );
  1282. }
  1283. *BytesNeeded = *BytesWritten = ulInfoLen;
  1284. }
  1285. return Status;
  1286. }
  1287. NDIS_STATUS
  1288. RasIrCmRequest(
  1289. IN NDIS_HANDLE CallMgrAfContext,
  1290. IN NDIS_HANDLE CallMgrVcContext,
  1291. IN NDIS_HANDLE CallMgrPartyContext,
  1292. IN OUT PNDIS_REQUEST NdisRequest )
  1293. // Standard 'CmRequestHandler' routine called by NDIS in response to a
  1294. // client's request for information from the mini-port.
  1295. //
  1296. {
  1297. PRASIR_ADAPTER pAdapter = (PRASIR_ADAPTER) CallMgrAfContext;
  1298. PRASIR_VC pVc = (PRASIR_VC) CallMgrVcContext;
  1299. NDIS_STATUS Status;
  1300. GOODADAPTER(pAdapter);
  1301. if (pVc)
  1302. {
  1303. GOODVC(pVc);
  1304. }
  1305. switch (NdisRequest->RequestType)
  1306. {
  1307. case NdisRequestQueryInformation:
  1308. {
  1309. Status = QueryCmInformation(
  1310. pAdapter,
  1311. pVc,
  1312. NdisRequest->DATA.QUERY_INFORMATION.Oid,
  1313. NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
  1314. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
  1315. &NdisRequest->DATA.QUERY_INFORMATION.BytesWritten,
  1316. &NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded );
  1317. break;
  1318. }
  1319. case NdisRequestSetInformation:
  1320. {
  1321. DEBUGMSG(DBG_ERROR, ("RASIR: RasIrCmRequest - NdisRequestSetInformation not supported\n"));
  1322. Status = NDIS_STATUS_NOT_SUPPORTED;
  1323. break;
  1324. }
  1325. default:
  1326. {
  1327. DEBUGMSG(DBG_ERROR, ("RASIR: RasIrCmRequest - Request type %d not supported\n",
  1328. NdisRequest->RequestType));
  1329. Status = NDIS_STATUS_NOT_SUPPORTED;
  1330. break;
  1331. }
  1332. }
  1333. return Status;
  1334. }
  1335. VOID
  1336. ProcessOfflineRxBuf(
  1337. IN PRASIR_VC pVc,
  1338. IN PIRDA_RECVBUF pRecvBuf)
  1339. {
  1340. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  1341. DEBUGMSG(DBG_CONNECT, ("RASIR: Offline command received. buflen %d %c%c%c%c\n",
  1342. pRecvBuf->BufLen, pRecvBuf->Buf[2], pRecvBuf->Buf[3],
  1343. pRecvBuf->Buf[4], pRecvBuf->Buf[5]));
  1344. if (pRecvBuf->BufLen < 3)
  1345. {
  1346. goto EXIT;
  1347. }
  1348. if (pVc->ModemState == MS_CONNECTING)
  1349. {
  1350. if (pRecvBuf->Buf[2] == 'C') // "<CR><LF>CONNECT 9600<CR><LF>"
  1351. {
  1352. pVc->ModemState = MS_ONLINE;
  1353. // Extract the baudrate
  1354. if (pRecvBuf->BufLen > 13)
  1355. {
  1356. // Replace <CR><LF> with 0
  1357. pRecvBuf->Buf[pRecvBuf->BufLen-1] = 0;
  1358. pRecvBuf->Buf[pRecvBuf->BufLen-2] = 0;
  1359. pVc->ConnectionSpeed = 2400;
  1360. RtlCharToInteger(&pRecvBuf->Buf[10], 10, &pVc->ConnectionSpeed);
  1361. DEBUGMSG(DBG_CONNECT, ("RASIR: Modem connected at %d\n",
  1362. pVc->ConnectionSpeed));
  1363. }
  1364. Status = NDIS_STATUS_SUCCESS;
  1365. }
  1366. else if (pRecvBuf->Buf[0] == 'A') // "ATD123-4567<CR>"
  1367. {
  1368. DEBUGMSG(DBG_CONNECT, ("RASIR: command echo received\n"));
  1369. return;
  1370. }
  1371. else
  1372. {
  1373. if (pRecvBuf->Buf[2] == 'N') // "<CR><LF>NO CARRIER<CR><LF>
  1374. {
  1375. Status = NDIS_STATUS_TAPI_DISCONNECTMODE_NOANSWER;
  1376. }
  1377. DEBUGMSG(DBG_CONNECT, ("RASIR: IrDial failed\n"));
  1378. pVc->ModemState = MS_OFFLINE;
  1379. }
  1380. }
  1381. EXIT:
  1382. if (Status != NDIS_STATUS_SUCCESS)
  1383. {
  1384. IrdaCloseConnection(pVc->IrdaConnContext);
  1385. }
  1386. CompleteMakeCall(pVc, Status);
  1387. }