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.

1130 lines
27 KiB

  1. /*++
  2. Copyright (c) 1995-1996 Microsoft Corporation
  3. Module Name:
  4. pxcl.c
  5. Abstract:
  6. The module contains the calls to the proxy client from NDIS.
  7. Author:
  8. Richard Machin (RMachin)
  9. Revision History:
  10. Who When What
  11. -------- -------- ----------------------------------------------
  12. RMachin 10-3-96 created
  13. TonyBe 02-21-99 re-work/re-write
  14. Notes:
  15. --*/
  16. #include "precomp.h"
  17. #define MODULE_NUMBER MODULE_CL
  18. #define _FILENUMBER 'LCXP'
  19. NDIS_STATUS
  20. PxClCreateVc(
  21. IN NDIS_HANDLE ProtocolAfContext,
  22. IN NDIS_HANDLE NdisVcHandle,
  23. OUT PNDIS_HANDLE ProtocolVcContext
  24. )
  25. {
  26. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  27. PPX_CL_AF pClAf;
  28. PPX_VC pVc;
  29. PXDEBUGP(PXD_LOUD, PXM_CL,
  30. ("PxClCreateVc: ClAf %p\n", ProtocolAfContext));
  31. pClAf = (PPX_CL_AF)ProtocolAfContext;
  32. NdisAcquireSpinLock(&pClAf->Lock);
  33. if (pClAf->State != PX_AF_OPENED) {
  34. PXDEBUGP(PXD_WARNING, PXM_CL,
  35. ("PxClCreateVc: Invalid AfState ClAf %p, State %x\n",
  36. pClAf, pClAf->State));
  37. NdisReleaseSpinLock(&pClAf->Lock);
  38. return (NDIS_STATUS_FAILURE);
  39. }
  40. pVc = PxAllocateVc(pClAf);
  41. if (pVc == NULL) {
  42. PXDEBUGP(PXD_WARNING, PXM_CL,
  43. ("PxClCreateVc: Error allocating memory\n"));
  44. NdisReleaseSpinLock(&pClAf->Lock);
  45. return (NDIS_STATUS_RESOURCES);
  46. }
  47. pVc->ClVcHandle = NdisVcHandle;
  48. NdisReleaseSpinLock(&pClAf->Lock);
  49. if (!InsertVcInTable(pVc)) {
  50. PXDEBUGP(PXD_WARNING, PXM_CL,
  51. ("PxClCreateVc: failed to insert in vc table\n"));
  52. PxFreeVc(pVc);
  53. return (NDIS_STATUS_RESOURCES);
  54. }
  55. *ProtocolVcContext = (NDIS_HANDLE)pVc->hdCall;
  56. PXDEBUGP(PXD_LOUD, PXM_CL,
  57. ("PxClCreateVc: Exit\n"));
  58. return(NDIS_STATUS_SUCCESS);
  59. }
  60. NDIS_STATUS
  61. PxClDeleteVc(
  62. IN NDIS_HANDLE ProtocolVcContext
  63. )
  64. {
  65. PPX_VC pVc;
  66. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  67. PXDEBUGP(PXD_LOUD, PXM_CL,
  68. ("PxClDeleteVc: Enter\n"));
  69. GetVcFromCtx(ProtocolVcContext, &pVc);
  70. if (pVc == NULL) {
  71. PXDEBUGP(PXD_WARNING, PXM_CL,
  72. ("PxClDeleteVc: VcCtx invalid %x\n", ProtocolVcContext));
  73. return (NDIS_STATUS_FAILURE);
  74. }
  75. ASSERT(pVc->State == PX_VC_IDLE);
  76. //
  77. // Deref for ref applied when we allocated the Vc.
  78. // We do not need the full deref code as the ref
  79. // applied at entry will keep the vc around.
  80. //
  81. pVc->RefCount--;
  82. //
  83. // Deref for ref applied at entry when
  84. // validating the vc
  85. //
  86. DEREF_VC(pVc);
  87. PXDEBUGP(PXD_LOUD, PXM_CL,
  88. ("PxClDeleteVc: Exit, Status %x\n", Status));
  89. return (Status);
  90. }
  91. NDIS_STATUS
  92. PxClRequest(
  93. IN NDIS_HANDLE ProtocolAfContext,
  94. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  95. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  96. IN OUT PNDIS_REQUEST NdisRequest
  97. )
  98. /*++
  99. Routine Description:
  100. This is called by an underlying cm/mp to send an ndisrequest to
  101. a client. Since we might be proxying on behalf of multiple clients
  102. we need to broadcast this request on to all clients that have
  103. opened our address family for this adapter. We are interested in
  104. OID_CO_AF_CLOSE so that we can cleanup our open on the Af and
  105. OID_GEN_CO_LINK_SPEED so that we can get changes in linkspeed
  106. on the adapter (and Vc if active).
  107. Arguments:
  108. Return Value:
  109. --*/
  110. {
  111. PPX_CL_AF pClAf;
  112. PPX_CM_AF pCmAf;
  113. PPX_ADAPTER pAdapter;
  114. PPX_VC pVc = NULL;
  115. NDIS_STATUS Status;
  116. NDIS_HANDLE VcHandle;
  117. //
  118. // The Vc returned here could be NULL as this
  119. // request might not be on vc.
  120. //
  121. GetVcFromCtx(ProtocolVcContext, &pVc);
  122. pClAf = (PPX_CL_AF)ProtocolAfContext;
  123. pAdapter = pClAf->Adapter;
  124. PXDEBUGP(PXD_LOUD, PXM_CL,
  125. ("PxClRequest: ClAf %p, Vc %p\n", pClAf, pVc));
  126. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  127. switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) {
  128. case OID_CO_AF_CLOSE:
  129. {
  130. PPX_TAPI_PROVIDER TapiProvider;
  131. NdisAcquireSpinLock(&pAdapter->Lock);
  132. RemoveEntryList(&pClAf->Linkage);
  133. InsertTailList(&pAdapter->ClAfClosingList, &pClAf->Linkage);
  134. NdisReleaseSpinLock(&pAdapter->Lock);
  135. //
  136. // We need to cleanup and close the open
  137. // on this af. This would include tearing
  138. // down all active calls (Vc's), deregistering
  139. // all saps and closing the af.
  140. //
  141. NdisAcquireSpinLock(&pClAf->Lock);
  142. //
  143. // Mark the Af as closing...
  144. //
  145. pClAf->State = PX_AF_CLOSING;
  146. TapiProvider = pClAf->TapiProvider;
  147. NdisReleaseSpinLock(&pClAf->Lock);
  148. //
  149. // Take all tapi devices associated with
  150. // this address family offline
  151. //
  152. if (TapiProvider != NULL) {
  153. NdisAcquireSpinLock(&TapiProvider->Lock);
  154. MarkProviderOffline(TapiProvider);
  155. NdisReleaseSpinLock(&TapiProvider->Lock);
  156. }
  157. //
  158. // Build list of Vc's that need attention
  159. //
  160. NdisAcquireSpinLock(&pClAf->Lock);
  161. while (!IsListEmpty(&pClAf->VcList)) {
  162. PLIST_ENTRY Entry;
  163. PPX_VC pActiveVc;
  164. Entry = RemoveHeadList(&pClAf->VcList);
  165. InsertHeadList(&pClAf->VcClosingList, Entry);
  166. pActiveVc = CONTAINING_RECORD(Entry, PX_VC, ClAfLinkage);
  167. NdisReleaseSpinLock(&pClAf->Lock);
  168. NdisAcquireSpinLock(&pActiveVc->Lock);
  169. pActiveVc->CloseFlags |= PX_VC_CLOSE_AF;
  170. REF_VC(pActiveVc);
  171. PxVcCleanup(pActiveVc, 0);
  172. DEREF_VC_LOCKED(pActiveVc);
  173. NdisAcquireSpinLock(&pClAf->Lock);
  174. }
  175. //
  176. // Get rid of all of the saps
  177. //
  178. {
  179. PLIST_ENTRY pe;
  180. PPX_CL_SAP pClSap;
  181. pe = pClAf->ClSapList.Flink;
  182. pClSap =
  183. CONTAINING_RECORD(pe, PX_CL_SAP, Linkage);
  184. while ((PVOID)pClSap != (PVOID)&pClAf->ClSapList) {
  185. if (InterlockedCompareExchange((PLONG)&pClSap->State,
  186. PX_SAP_CLOSING,
  187. PX_SAP_OPENED)) {
  188. RemoveEntryList(&pClSap->Linkage);
  189. InsertTailList(&pClAf->ClSapClosingList, &pClSap->Linkage);
  190. NdisReleaseSpinLock(&pClAf->Lock);
  191. ClearSapWithTapiLine(pClSap);
  192. Status = NdisClDeregisterSap(pClSap->NdisSapHandle);
  193. if (Status != NDIS_STATUS_PENDING) {
  194. PxClDeregisterSapComplete(Status, pClSap);
  195. }
  196. NdisAcquireSpinLock(&pClAf->Lock);
  197. pe = pClAf->ClSapList.Flink;
  198. pClSap =
  199. CONTAINING_RECORD(pe, PX_CL_SAP, Linkage);
  200. } else {
  201. pe = pClSap->Linkage.Flink;
  202. pClSap =
  203. CONTAINING_RECORD(pe, PX_CL_SAP, Linkage);
  204. }
  205. }
  206. }
  207. DEREF_CL_AF_LOCKED(pClAf);
  208. //
  209. // Now broadcast this close to all of the clients
  210. // we have using this adapter/af.
  211. //
  212. NdisAcquireSpinLock(&pAdapter->Lock);
  213. while (!IsListEmpty(&pAdapter->CmAfList)) {
  214. PX_REQUEST ProxyRequest;
  215. PPX_REQUEST pProxyRequest = &ProxyRequest;
  216. ULONG Info = 0;
  217. PNDIS_REQUEST NdisRequest;
  218. pCmAf = (PPX_CM_AF)RemoveHeadList(&pAdapter->CmAfList);
  219. InsertTailList(&pAdapter->CmAfClosingList, &pCmAf->Linkage);
  220. NdisReleaseSpinLock(&pAdapter->Lock);
  221. NdisAcquireSpinLock(&pCmAf->Lock);
  222. pCmAf->State = PX_AF_CLOSING;
  223. REF_CM_AF(pCmAf);
  224. NdisReleaseSpinLock(&pCmAf->Lock);
  225. NdisZeroMemory(pProxyRequest, sizeof(PX_REQUEST));
  226. NdisRequest = &pProxyRequest->NdisRequest;
  227. NdisRequest->RequestType =
  228. NdisRequestSetInformation;
  229. NdisRequest->DATA.QUERY_INFORMATION.Oid =
  230. OID_CO_AF_CLOSE;
  231. NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =
  232. &Info;
  233. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength =
  234. sizeof(ULONG);
  235. PxInitBlockStruc(&pProxyRequest->Block);
  236. Status = NdisCoRequest(pAdapter->CmBindingHandle,
  237. pCmAf->NdisAfHandle,
  238. NULL,
  239. NULL,
  240. NdisRequest);
  241. if (Status == NDIS_STATUS_PENDING) {
  242. Status = PxBlock(&pProxyRequest->Block);
  243. }
  244. DEREF_CM_AF(pCmAf);
  245. NdisAcquireSpinLock(&pAdapter->Lock);
  246. }
  247. NdisReleaseSpinLock(&pAdapter->Lock);
  248. }
  249. break;
  250. case OID_GEN_CO_LINK_SPEED:
  251. //
  252. // We need to record the new speed of
  253. // the vc.
  254. //
  255. break;
  256. default:
  257. //
  258. // Just pass it through
  259. //
  260. break;
  261. }
  262. VcHandle = (pVc != NULL) ? pVc->CmVcHandle : NULL;
  263. //
  264. // Now broadcast this request up to all of the Clients
  265. // that have opend our af for this adapter.
  266. //
  267. NdisAcquireSpinLock(&pAdapter->Lock);
  268. pCmAf = (PPX_CM_AF)pAdapter->CmAfList.Flink;
  269. while ((PVOID)pCmAf != (PVOID)&pAdapter->CmAfList) {
  270. PPX_CM_AF NextAf;
  271. PX_REQUEST ProxyRequest;
  272. PPX_REQUEST pProxyRequest = &ProxyRequest;
  273. NextAf =
  274. (PPX_CM_AF)pCmAf->Linkage.Flink;
  275. NdisAcquireSpinLock(&pCmAf->Lock);
  276. if (pCmAf->State != PX_AF_OPENED) {
  277. NdisReleaseSpinLock(&pCmAf->Lock);
  278. pCmAf = NextAf;
  279. continue;
  280. }
  281. REF_CM_AF(pCmAf);
  282. NdisReleaseSpinLock(&pCmAf->Lock);
  283. NdisZeroMemory(pProxyRequest, sizeof(PX_REQUEST));
  284. NdisMoveMemory(&pProxyRequest->NdisRequest, NdisRequest, sizeof(NDIS_REQUEST));
  285. NdisReleaseSpinLock(&pAdapter->Lock);
  286. PxInitBlockStruc(&pProxyRequest->Block);
  287. Status = NdisCoRequest(pAdapter->CmBindingHandle,
  288. pCmAf->NdisAfHandle,
  289. VcHandle,
  290. NULL,
  291. &pProxyRequest->NdisRequest);
  292. if (Status == NDIS_STATUS_PENDING) {
  293. PxBlock(&pProxyRequest->Block);
  294. }
  295. NdisAcquireSpinLock(&pAdapter->Lock);
  296. //
  297. // deref for the ref applied before we
  298. // propagated this request
  299. //
  300. DEREF_CM_AF(pCmAf);
  301. pCmAf = NextAf;
  302. }
  303. NdisReleaseSpinLock(&pAdapter->Lock);
  304. //
  305. // Remove ref applied when we attempted to
  306. // map the vcctx to a vcptr at entry.
  307. //
  308. DEREF_VC(pVc);
  309. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  310. return (NDIS_STATUS_SUCCESS);
  311. }
  312. VOID
  313. PxClRequestComplete(
  314. IN NDIS_STATUS Status,
  315. IN NDIS_HANDLE ProtocolAfContext,
  316. IN NDIS_HANDLE ProtocolVcContext, // Optional
  317. IN NDIS_HANDLE ProtocolPartyContext, // Optional
  318. IN PNDIS_REQUEST NdisRequest
  319. )
  320. {
  321. PPX_REQUEST pProxyRequest;
  322. PPX_CL_AF pClAf;
  323. PPX_VC pVc = NULL;
  324. pClAf = (PPX_CL_AF)ProtocolAfContext;
  325. //
  326. // The Vc returned here could be NULL as this
  327. // request might not be on vc.
  328. //
  329. GetVcFromCtx(ProtocolVcContext, &pVc);
  330. PXDEBUGP(PXD_LOUD, PXM_CL,
  331. ("PxClRequestComplete: ClAf %p, Vc %p, Oid: %x, Status %x\n",
  332. pClAf, pVc, NdisRequest->DATA.QUERY_INFORMATION.Oid, Status));
  333. pProxyRequest = CONTAINING_RECORD(NdisRequest, PX_REQUEST, NdisRequest);
  334. if (pProxyRequest->Flags & PX_REQ_ASYNC) {
  335. pProxyRequest->Flags &= ~PX_REQ_ASYNC;
  336. PxFreeMem(pProxyRequest);
  337. } else {
  338. PxSignal(&pProxyRequest->Block, Status);
  339. }
  340. //
  341. // Remove ref applied when we attempted to
  342. // map the vcctx to a vcptr at entry.
  343. //
  344. DEREF_VC(pVc);
  345. }
  346. VOID
  347. PxClOpenAfComplete(
  348. IN NDIS_STATUS Status,
  349. IN NDIS_HANDLE ProtocolAfContext,
  350. IN NDIS_HANDLE NdisAfHandle
  351. )
  352. {
  353. PPX_CL_AF pClAf;
  354. pClAf = (PPX_CL_AF)ProtocolAfContext;
  355. PXDEBUGP(PXD_LOUD, PXM_CL,
  356. ("PxClOpenAfComplete: ClAf %p, Status %x\n", pClAf, Status));
  357. pClAf->NdisAfHandle = NdisAfHandle;
  358. PxSignal(&pClAf->Block, Status);
  359. }
  360. VOID
  361. PxClCloseAfComplete(
  362. IN NDIS_STATUS Status,
  363. IN NDIS_HANDLE ProtocolAfContext
  364. )
  365. {
  366. PPX_CL_AF pClAf;
  367. PPX_ADAPTER pAdapter;
  368. PPX_TAPI_PROVIDER TapiProvider;
  369. pClAf = (PPX_CL_AF)ProtocolAfContext;
  370. pAdapter = pClAf->Adapter;
  371. PXDEBUGP(PXD_LOUD, PXM_CL,
  372. ("PxClCloseAfComplete: ClAf %p, Status %x\n", pClAf, Status));
  373. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  374. NdisAcquireSpinLock(&pAdapter->Lock);
  375. RemoveEntryList(&pClAf->Linkage);
  376. DEREF_ADAPTER_LOCKED(pAdapter);
  377. NdisAcquireSpinLock(&pClAf->Lock);
  378. pClAf->State = PX_AF_CLOSED;
  379. TapiProvider = pClAf->TapiProvider;
  380. pClAf->TapiProvider = NULL;
  381. NdisReleaseSpinLock(&pClAf->Lock);
  382. if (TapiProvider != NULL) {
  383. NdisAcquireSpinLock(&TapiProvider->Lock);
  384. MarkProviderOffline(TapiProvider);
  385. NdisReleaseSpinLock(&TapiProvider->Lock);
  386. }
  387. PxFreeClAf(pClAf);
  388. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  389. }
  390. VOID
  391. PxClRegisterSapComplete(
  392. IN NDIS_STATUS Status,
  393. IN NDIS_HANDLE ProtocolSapContext,
  394. IN PCO_SAP pSap,
  395. IN NDIS_HANDLE NdisSapHandle
  396. )
  397. {
  398. PPX_CL_SAP pClSap;
  399. PPX_CL_AF pClAf;
  400. PPX_TAPI_LINE TapiLine;
  401. pClSap = (PPX_CL_SAP)ProtocolSapContext;
  402. pClAf = pClSap->ClAf;
  403. TapiLine = pClSap->TapiLine;
  404. PXDEBUGP(PXD_LOUD, PXM_CL,
  405. ("PxClRegisterSapComplete: ClSap %p, Status %x\n", pClSap, Status));
  406. if (Status != NDIS_STATUS_SUCCESS) {
  407. InterlockedExchange((PLONG)&pClSap->State, PX_SAP_CLOSED);
  408. NdisAcquireSpinLock(&pClAf->Lock);
  409. RemoveEntryList(&pClSap->Linkage);
  410. DEREF_CL_AF_LOCKED(pClAf);
  411. TapiLine->ClSap = NULL;
  412. PxFreeClSap(pClSap);
  413. return;
  414. }
  415. pClSap->NdisSapHandle = NdisSapHandle;
  416. NdisAcquireSpinLock(&pClAf->Lock);
  417. if (pClAf->State != PX_AF_OPENED) {
  418. //
  419. // the af is no longer open so we to deregister
  420. // this sap
  421. //
  422. NdisReleaseSpinLock(&pClAf->Lock);
  423. InterlockedExchange((PLONG)&pClSap->State, PX_SAP_CLOSING);
  424. Status = NdisClDeregisterSap(pClSap->NdisSapHandle);
  425. if (Status != NDIS_STATUS_PENDING) {
  426. PxClDeregisterSapComplete(Status, pClSap);
  427. }
  428. return;
  429. }
  430. NdisReleaseSpinLock(&pClAf->Lock);
  431. NdisAcquireSpinLock(&TapiLine->Lock);
  432. if (TapiLine->DevStatus->ulNumOpens == 0) {
  433. NdisReleaseSpinLock(&TapiLine->Lock);
  434. //
  435. // There are not any opens on the line so we
  436. // need to deregister the sap
  437. //
  438. InterlockedExchange((PLONG)&pClSap->State, PX_SAP_CLOSING);
  439. Status = NdisClDeregisterSap(pClSap->NdisSapHandle);
  440. if (Status != NDIS_STATUS_PENDING) {
  441. PxClDeregisterSapComplete(Status, pClSap);
  442. }
  443. return;
  444. }
  445. NdisReleaseSpinLock(&TapiLine->Lock);
  446. InterlockedExchange((PLONG)&pClSap->State, PX_SAP_OPENED);
  447. }
  448. VOID
  449. PxClDeregisterSapComplete(
  450. IN NDIS_STATUS Status,
  451. IN NDIS_HANDLE ProtocolSapContext
  452. )
  453. {
  454. PPX_CL_SAP pClSap;
  455. PPX_CL_AF pClAf;
  456. pClSap = (PPX_CL_SAP)ProtocolSapContext;
  457. pClAf = pClSap->ClAf;
  458. PXDEBUGP(PXD_LOUD, PXM_CL,
  459. ("PxClDeregisterSapComplete: ClSap %p, Status %x\n", pClSap, Status));
  460. NdisAcquireSpinLock(&pClAf->Lock);
  461. RemoveEntryList(&pClSap->Linkage);
  462. DEREF_CL_AF_LOCKED(pClAf);
  463. InterlockedExchange((PLONG)&pClSap->State, PX_SAP_CLOSED);
  464. PxFreeClSap(pClSap);
  465. }
  466. VOID
  467. PxClMakeCallComplete(
  468. IN NDIS_STATUS Status,
  469. IN NDIS_HANDLE ProtocolVcContext,
  470. IN NDIS_HANDLE ProxyNdisPartyHandle OPTIONAL,
  471. IN PCO_CALL_PARAMETERS pCallParameters
  472. )
  473. {
  474. PPX_VC pVc;
  475. PPX_CL_AF pClAf;
  476. ULONG ulCallState;
  477. ULONG ulCallStateMode;
  478. BOOLEAN TapiStateChange;
  479. PXDEBUGP(PXD_LOUD, PXM_CL,
  480. ("PxClMakeCallComplete: VcCtx %x, Status %x\n", ProtocolVcContext, Status));
  481. GetVcFromCtx(ProtocolVcContext, &pVc);
  482. if (pVc == NULL) {
  483. PXDEBUGP(PXD_WARNING, PXM_CL,
  484. ("PxClMakeCallComplete: pVc invalid %x\n", ProtocolVcContext));
  485. return;
  486. }
  487. TapiStateChange = TRUE;
  488. NdisAcquireSpinLock(&pVc->Lock);
  489. ASSERT(pVc->Flags & PX_VC_OWNER);
  490. do {
  491. if (pVc->Flags & PX_VC_OUTCALL_ABORTED) {
  492. //
  493. // This call has been aborted while
  494. // in the PROCEEDING state. This means
  495. // that the CloseCallComplete has run
  496. // and did our cleanup so just get
  497. // out.
  498. //
  499. break;
  500. } else if (pVc->Flags & PX_VC_OUTCALL_ABORTING) {
  501. pVc->Flags &= ~PX_VC_OUTCALL_ABORTING;
  502. pVc->Flags |= PX_VC_OUTCALL_ABORTED;
  503. }
  504. ASSERT((pVc->State == PX_VC_DISCONNECTING) ||
  505. (pVc->State == PX_VC_PROCEEDING));
  506. if (Status == NDIS_STATUS_SUCCESS) {
  507. //
  508. // This means that we received a drop from tapi
  509. // while the ClMakeCall was pending.
  510. //
  511. if (pVc->State == PX_VC_DISCONNECTING) {
  512. //
  513. // We need to drop the call with the
  514. // call manager/miniport
  515. //
  516. pVc->Flags &= ~PX_VC_OUTCALL_ABORTED;
  517. PxCloseCallWithCm(pVc);
  518. TapiStateChange = FALSE;
  519. } else {
  520. ulCallState = LINECALLSTATE_CONNECTED;
  521. ulCallStateMode = 0;
  522. pVc->PrevState = pVc->State;
  523. pVc->State = PX_VC_CONNECTED;
  524. }
  525. } else {
  526. ulCallState = LINECALLSTATE_DISCONNECTED;
  527. ulCallStateMode =
  528. PxMapNdisStatusToTapiDisconnectMode(Status, TRUE);
  529. //
  530. // Remove the ref applied before we
  531. // call NdisClMakeCall. We don't need
  532. // to do the full deref code here as the
  533. // ref applied when we mapped the vc will
  534. // keep the vc around!
  535. //
  536. pVc->RefCount--;
  537. pVc->PrevState = pVc->State;
  538. pVc->State = PX_VC_IDLE;
  539. }
  540. if (TapiStateChange == TRUE) {
  541. SendTapiCallState(pVc,
  542. ulCallState,
  543. ulCallStateMode,
  544. pVc->CallInfo->ulMediaMode);
  545. }
  546. if (pVc->Flags & PX_VC_DROP_PENDING){
  547. PxTapiCompleteDropIrps(pVc, Status);
  548. }
  549. } while (FALSE);
  550. //
  551. // Deref for ref applied when mapping the context.
  552. // This releases the Vc lock!
  553. //
  554. DEREF_VC_LOCKED(pVc);
  555. }
  556. VOID
  557. PxClModifyCallQosComplete(
  558. IN NDIS_STATUS Status,
  559. IN NDIS_HANDLE ProtocolVcContext,
  560. IN PCO_CALL_PARAMETERS CallParameters
  561. )
  562. {
  563. }
  564. VOID
  565. PxClCloseCallComplete(
  566. IN NDIS_STATUS Status,
  567. IN NDIS_HANDLE ProtocolVcContext,
  568. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL
  569. )
  570. {
  571. PPX_VC pVc;
  572. PPX_CL_AF pClAf;
  573. PXDEBUGP(PXD_LOUD, PXM_CL,
  574. ("PxClCloseCallComplete: VcCtx %x, Status %x\n", ProtocolVcContext, Status));
  575. GetVcFromCtx(ProtocolVcContext, &pVc);
  576. if (pVc == NULL) {
  577. PXDEBUGP(PXD_WARNING, PXM_CL,
  578. ("PxClCloseCallComplete: pVc invalid %x\n", ProtocolVcContext));
  579. return;
  580. }
  581. NdisAcquireSpinLock(&pVc->Lock);
  582. do {
  583. //
  584. // The closecall did not take (atm does
  585. // not support receiving a closecall while
  586. // an outgoing call is proceeding). We
  587. // need to get out and cleanup later.
  588. //
  589. if (Status != NDIS_STATUS_SUCCESS) {
  590. pVc->Flags |= PX_VC_CLEANUP_CM;
  591. pVc->CloseFlags |= PX_VC_CM_CLOSE_FAIL;
  592. break;
  593. }
  594. pVc->CloseFlags |= PX_VC_CM_CLOSE_COMP;
  595. if (pVc->Flags & PX_VC_OUTCALL_ABORTED) {
  596. //
  597. // This call has been aborted while
  598. // in the PROCEEDING state. This means
  599. // that the MakeCallComplete has run
  600. // and did our cleanup so just get
  601. // out.
  602. //
  603. break;
  604. } else if (pVc->Flags & PX_VC_OUTCALL_ABORTING) {
  605. pVc->Flags &= ~PX_VC_OUTCALL_ABORTING;
  606. pVc->Flags |= PX_VC_OUTCALL_ABORTED;
  607. } else if (pVc->Flags & PX_VC_INCALL_ABORTING) {
  608. pVc->Flags &= ~PX_VC_INCALL_ABORTING;
  609. pVc->Flags |= PX_VC_INCALL_ABORTED;
  610. }
  611. pVc->PrevState = pVc->State;
  612. pVc->State = PX_VC_IDLE;
  613. pClAf = pVc->ClAf;
  614. SendTapiCallState(pVc,
  615. LINECALLSTATE_DISCONNECTED,
  616. 0,
  617. pVc->CallInfo->ulMediaMode);
  618. if (pVc->Flags & PX_VC_DROP_PENDING) {
  619. PxTapiCompleteDropIrps(pVc, Status);
  620. }
  621. //
  622. // Remove the ref applied when this call
  623. // became connected with the call manager
  624. // (NdisClMakeCall/PxClIncomingCall).
  625. // We don't need to do the full deref code
  626. // here as the ref applied when we mapped
  627. // the vc will keep the vc around!
  628. //
  629. pVc->RefCount--;
  630. } while (FALSE);
  631. //
  632. // Deref for ref applied at entry when
  633. // validating the vc
  634. //
  635. DEREF_VC_LOCKED(pVc);
  636. }
  637. VOID
  638. PxClAddPartyComplete(
  639. IN NDIS_STATUS status,
  640. IN NDIS_HANDLE ProtocolPartyContext,
  641. IN NDIS_HANDLE NdisPartyHandle,
  642. IN PCO_CALL_PARAMETERS CallParameters
  643. )
  644. {
  645. ASSERT(0);
  646. }
  647. VOID
  648. PxClDropPartyComplete(
  649. IN NDIS_STATUS status,
  650. IN NDIS_HANDLE ProtocolPartyContext
  651. )
  652. {
  653. ASSERT(0);
  654. }
  655. NDIS_STATUS
  656. PxClIncomingCall(
  657. IN NDIS_HANDLE ProtocolSapContext,
  658. IN NDIS_HANDLE ProtocolVcContext,
  659. IN OUT PCO_CALL_PARAMETERS pCallParams
  660. )
  661. {
  662. PPX_VC pVc;
  663. PPX_CL_SAP pClSap;
  664. PPX_CL_AF pClAf;
  665. NDIS_STATUS Status;
  666. PXDEBUGP(PXD_LOUD, PXM_CL,
  667. ("PxClIncomingCall: Sap %p VcCtx %x\n",
  668. ProtocolSapContext, ProtocolVcContext));
  669. pClSap = (PPX_CL_SAP)ProtocolSapContext;
  670. if (pClSap->State != PX_SAP_OPENED) {
  671. PXDEBUGP(PXD_WARNING, PXM_CL,
  672. ("PxClIncomingCall: Invalid SapState Sap %p State %x\n",
  673. pClSap, pClSap->State));
  674. return (NDIS_STATUS_FAILURE);
  675. }
  676. pClAf = pClSap->ClAf;
  677. GetVcFromCtx(ProtocolVcContext, &pVc);
  678. if (pVc == NULL) {
  679. PXDEBUGP(PXD_WARNING, PXM_CL,
  680. ("PxClIncomingCall: pVc invalid %x\n", ProtocolVcContext));
  681. return (NDIS_STATUS_FAILURE);
  682. }
  683. Status =
  684. (*pClAf->AfGetTapiCallParams)(pVc, pCallParams);
  685. if (Status != NDIS_STATUS_SUCCESS) {
  686. PXDEBUGP(PXD_WARNING, PXM_CL,
  687. ("PxClIncomingCall: pVc invalid %x\n", ProtocolVcContext));
  688. return (Status);
  689. }
  690. NdisAcquireSpinLock(&pVc->Lock);
  691. // The algorithim for computing a unique "htCall" is to start
  692. // at the value 1, and perpetually increment by 2. Keeping
  693. // the low bit set will allow the user-mode TAPI component
  694. // we talk to to distinguish between these incoming call handles
  695. // and outgoing call handles, the latter of which will always
  696. // have the low bit zero'd (since they're really pointers to heap).
  697. //
  698. // In <= NT 4.0, valid values used to range between 0x80000000
  699. // and 0xffffffff, as we relied on the fact that user-mode
  700. // addresses always had the low bit zero'd. (Not a valid
  701. // assumption anymore!)
  702. //
  703. pVc->htCall =
  704. InterlockedExchangeAdd((PLONG)&TspCB.htCall, 2);
  705. //
  706. // This ref is applied for the indication to
  707. // tapi of a new call. The ref will be removed
  708. // when tapi closes the call in PxTapiCloseCall.
  709. //
  710. REF_VC(pVc);
  711. //
  712. // This ref is applied for the connection
  713. // between the proxy and the call manager.
  714. // The ref will be removed in either
  715. // PxClCloseCallComplete or PxVcCleanup
  716. // in the case where the offered call is
  717. // dropped by the client.
  718. //
  719. REF_VC(pVc);
  720. SendTapiNewCall(pVc,
  721. pVc->hdCall,
  722. pVc->htCall,
  723. 0);
  724. SendTapiCallState(pVc,
  725. LINECALLSTATE_OFFERING,
  726. 0,
  727. pVc->CallInfo->ulMediaMode);
  728. pVc->PrevState = pVc->State;
  729. pVc->State = PX_VC_OFFERING;
  730. PxStartIncomingCallTimeout(pVc);
  731. //
  732. // Deref for ref applied at entry when
  733. // validating the vc
  734. //
  735. DEREF_VC_LOCKED(pVc);
  736. return (NDIS_STATUS_PENDING);
  737. }
  738. VOID
  739. PxClIncomingCallQosChange(
  740. IN NDIS_HANDLE ProtocolVcContext,
  741. IN PCO_CALL_PARAMETERS pCallParams
  742. )
  743. {
  744. }
  745. VOID
  746. PxClIncomingCloseCall(
  747. IN NDIS_STATUS CloseStatus,
  748. IN NDIS_HANDLE ProtocolVcContext,
  749. IN PVOID CloseData OPTIONAL,
  750. IN UINT Size OPTIONAL
  751. )
  752. {
  753. PPX_VC pVc;
  754. PPX_CL_AF pClAf;
  755. PXDEBUGP(PXD_LOUD, PXM_CL,
  756. ("PxClIncomingCloseCall: VcCtx %x\n", ProtocolVcContext));
  757. GetVcFromCtx(ProtocolVcContext, &pVc);
  758. if (pVc == NULL) {
  759. PXDEBUGP(PXD_WARNING, PXM_CL,
  760. ("PxClIncomingCloseCall: pVc invalid %x\n", ProtocolVcContext));
  761. return;
  762. }
  763. NdisAcquireSpinLock(&pVc->Lock);
  764. pVc->CloseFlags |= PX_VC_INCOMING_CLOSE;
  765. PxVcCleanup(pVc, PX_VC_CLEANUP_CM);
  766. //
  767. // remove the ref applied when we
  768. // mapped the ctx to the vc at entry
  769. //
  770. DEREF_VC_LOCKED(pVc);
  771. }
  772. VOID
  773. PxClIncomingDropParty(
  774. IN NDIS_STATUS DropStatus,
  775. IN NDIS_HANDLE ProtocolPartyContext,
  776. IN PVOID CloseData OPTIONAL,
  777. IN UINT Size OPTIONAL
  778. )
  779. {
  780. ASSERT(0);
  781. }
  782. VOID
  783. PxClCallConnected(
  784. IN NDIS_HANDLE ProtocolVcContext
  785. )
  786. {
  787. PPX_VC pVc;
  788. PXDEBUGP(PXD_LOUD, PXM_CL,
  789. ("PxClCallConnected: VcCtx %x\n", ProtocolVcContext));
  790. GetVcFromCtx(ProtocolVcContext, &pVc);
  791. if (pVc == NULL) {
  792. PXDEBUGP(PXD_WARNING, PXM_CL,
  793. ("PxClCallConnected: pVc invalid %x\n", ProtocolVcContext));
  794. return;
  795. }
  796. NdisAcquireSpinLock(&pVc->Lock);
  797. PXDEBUGP(PXD_LOUD, PXM_CL,
  798. ("PxClCallConnected: pVc %p, State %x\n", pVc, pVc->State));
  799. if (pVc->State == PX_VC_CONNECTED) {
  800. SendTapiCallState(pVc,
  801. LINECALLSTATE_CONNECTED,
  802. 0,
  803. pVc->CallInfo->ulMediaMode);
  804. }
  805. //
  806. // Deref for ref applied at entry when
  807. // validating the vc
  808. //
  809. DEREF_VC_LOCKED(pVc);
  810. PXDEBUGP(PXD_LOUD, PXM_CL, ("PxClCallConnected: Exit\n"));
  811. }