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.

684 lines
14 KiB

  1. /*++
  2. Copyright (c) 1995-1996 Microsoft Corporation
  3. Module Name:
  4. pxcm.c
  5. Abstract:
  6. This module contains the Call Manager (CM_) entry points listed
  7. in the protocol characteristics table. These entry points are called
  8. by the NDIS wrapper on behalf of requests made by a client.
  9. Author:
  10. Richard Machin (RMachin)
  11. Revision History:
  12. Who When What
  13. -------- -------- ----------------------------------------------
  14. RMachin 10-03-96 created
  15. tonybe 01-23-99 rewrite and cleanup
  16. Notes:
  17. --*/
  18. #include "precomp.h"
  19. #define MODULE_NUMBER MODULE_CM
  20. #define _FILENUMBER 'MCXP'
  21. NDIS_STATUS
  22. PxCmCreateVc(
  23. IN NDIS_HANDLE ProtocolAfContext,
  24. IN NDIS_HANDLE NdisVcHandle,
  25. OUT PNDIS_HANDLE pProtocolVcContext
  26. )
  27. /*++
  28. Routine Description:
  29. We do not allow a client of the proxy to create a Vc ever!
  30. Arguments:
  31. Return Value:
  32. NDIS_STATUS_SUCCESS if everything goes off well right here
  33. NDIS_STATUS_XXXX to indicate any error.
  34. --*/
  35. {
  36. PXDEBUGP(PXD_FATAL, PXM_CM,
  37. ("PxCmCreateVc: Should never be called!\n"));
  38. ASSERT(0);
  39. return(NDIS_STATUS_FAILURE);
  40. }
  41. NDIS_STATUS
  42. PxCmDeleteVc(
  43. IN NDIS_HANDLE ProtocolVcContext
  44. )
  45. /*++
  46. Routine Description:
  47. We do not allow a client to delete a vc!
  48. Arguments:
  49. Return Value:
  50. NDIS_STATUS_SUCCESS if everything goes off well right here
  51. NDIS_STATUS_XXXX to indicate any error.
  52. --*/
  53. {
  54. PXDEBUGP(PXD_FATAL, PXM_CM,
  55. ("PxCmDeleteVc: Should never be called!\n"));
  56. ASSERT(0);
  57. return(NDIS_STATUS_FAILURE);
  58. }
  59. NDIS_STATUS
  60. PxCmOpenAf(
  61. IN NDIS_HANDLE BindingContext,
  62. IN PCO_ADDRESS_FAMILY AddressFamily,
  63. IN NDIS_HANDLE NdisAfHandle,
  64. OUT PNDIS_HANDLE CallMgrAfContext
  65. )
  66. /*++
  67. Routine Description:
  68. This routine creats an Af context for the client that is opening
  69. our address family. The Af context is threaded up on the adapter
  70. block.
  71. Arguments:
  72. Return Value:
  73. NDIS_STATUS_SUCCESS if everything goes off well right here
  74. NDIS_STATUS_XXXX to indicate any error.
  75. --*/
  76. {
  77. PPX_CM_AF pCmAf;
  78. PPX_ADAPTER pAdapter;
  79. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmOpenAf: AF: %x\n",AddressFamily->AddressFamily));
  80. //
  81. // Make sure the address family being opened is ours
  82. //
  83. if(AddressFamily->AddressFamily != CO_ADDRESS_FAMILY_TAPI) {
  84. PXDEBUGP(PXD_ERROR, PXM_CM,
  85. ("PxCmOpenAf: not Proxy address family: %x\n",
  86. AddressFamily->AddressFamily));
  87. return(NDIS_STATUS_BAD_VERSION);
  88. }
  89. AdapterFromCmBindContext(BindingContext, pAdapter);
  90. NdisAcquireSpinLock(&pAdapter->Lock);
  91. if (pAdapter->State != PX_ADAPTER_OPEN) {
  92. NdisReleaseSpinLock(&pAdapter->Lock);
  93. return (NDIS_STATUS_CLOSING);
  94. }
  95. NdisReleaseSpinLock(&pAdapter->Lock);
  96. pCmAf =
  97. PxAllocateCmAf(AddressFamily);
  98. if (pCmAf == NULL) {
  99. PXDEBUGP(PXD_ERROR, PXM_CM, ("PXCmOpenAf: AfBlock memory allocation failed!\n"));
  100. return (NDIS_STATUS_RESOURCES);
  101. }
  102. pCmAf->NdisAfHandle = NdisAfHandle;
  103. pCmAf->State = PX_AF_OPENED;
  104. pCmAf->Adapter = pAdapter;
  105. NdisAcquireSpinLock(&pAdapter->Lock);
  106. InsertTailList(&pAdapter->CmAfList, &pCmAf->Linkage);
  107. REF_ADAPTER(pAdapter);
  108. NdisReleaseSpinLock(&pAdapter->Lock);
  109. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmOpenAf: CmAf %p, NdisAfHandle is %p\n",
  110. pCmAf,NdisAfHandle));
  111. *CallMgrAfContext = pCmAf;
  112. return(NDIS_STATUS_SUCCESS);
  113. }
  114. NDIS_STATUS
  115. PxCmCloseAf(
  116. IN NDIS_HANDLE CallMgrAfContext
  117. )
  118. /*++
  119. Routine Description:
  120. The client is closing the open of this address family.
  121. Arguments:
  122. Return Value:
  123. NDIS_STATUS_SUCCESS if everything goes off well right here
  124. NDIS_STATUS_XXXX to indicate any error.
  125. --*/
  126. {
  127. PPX_CM_AF pCmAf;
  128. PPX_ADAPTER pAdapter;
  129. pCmAf = (PPX_CM_AF)CallMgrAfContext;
  130. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  131. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmCloseAf: CmAf %p\n", pCmAf));
  132. //
  133. // There should not be any open saps on this af!
  134. //
  135. ASSERT(IsListEmpty(&pCmAf->CmSapList) == TRUE);
  136. //
  137. // There should not be any active Vc's on this af!
  138. //
  139. ASSERT(IsListEmpty(&pCmAf->VcList) == TRUE);
  140. pAdapter = pCmAf->Adapter;
  141. NdisAcquireSpinLock(&pAdapter->Lock);
  142. RemoveEntryList(&pCmAf->Linkage);
  143. DEREF_ADAPTER_LOCKED(pAdapter);
  144. NdisAcquireSpinLock(&pCmAf->Lock);
  145. pCmAf->State = PX_AF_CLOSED;
  146. pCmAf->Linkage.Flink =
  147. pCmAf->Linkage.Blink = (PLIST_ENTRY)pCmAf;
  148. DEREF_CM_AF_LOCKED(pCmAf);
  149. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  150. return (NDIS_STATUS_PENDING);
  151. }
  152. NDIS_STATUS
  153. PxCmRegisterSap(
  154. IN NDIS_HANDLE CallMgrAfContext,
  155. IN PCO_SAP Sap,
  156. IN NDIS_HANDLE NdisSapHandle,
  157. OUT PNDIS_HANDLE CallMgrSapContext
  158. )
  159. /*++
  160. Routine Description:
  161. Arguments:
  162. Return Value:
  163. NDIS_STATUS_SUCCESS if everything goes off well right here
  164. NDIS_STATUS_XXXX to indicate any error.
  165. --*/
  166. {
  167. PPX_CM_AF pCmAf;
  168. PPX_CM_SAP pCmSap;
  169. PPX_ADAPTER pAdapter;
  170. pCmAf = (PPX_CM_AF)CallMgrAfContext;
  171. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmRegisterSap: CmAf %p\n", pCmAf));
  172. NdisAcquireSpinLock(&pCmAf->Lock);
  173. if (pCmAf->State != PX_AF_OPENED) {
  174. PXDEBUGP(PXD_WARNING, PXM_CM,
  175. ("PxCmRegisterSap: Invalid state %x\n", pCmAf->State));
  176. NdisReleaseSpinLock(&pCmAf->Lock);
  177. return (NDIS_STATUS_FAILURE);
  178. }
  179. pAdapter = pCmAf->Adapter;
  180. NdisReleaseSpinLock(&pCmAf->Lock);
  181. NdisAcquireSpinLock(&pAdapter->Lock);
  182. if (pAdapter->State != PX_ADAPTER_OPEN) {
  183. NdisReleaseSpinLock(&pAdapter->Lock);
  184. return (NDIS_STATUS_CLOSING);
  185. }
  186. NdisReleaseSpinLock(&pAdapter->Lock);
  187. //
  188. // Allocate memory for the Sap
  189. //
  190. pCmSap = PxAllocateCmSap(Sap);
  191. if (pCmSap == NULL) {
  192. PXDEBUGP(PXD_WARNING, PXM_CM,
  193. ("PxCmRegisterSap: Error allocating memory for sap %p\n", Sap));
  194. NdisReleaseSpinLock(&pCmAf->Lock);
  195. return (NDIS_STATUS_RESOURCES);
  196. }
  197. NdisAcquireSpinLock(&pCmAf->Lock);
  198. pCmSap->NdisSapHandle = NdisSapHandle;
  199. pCmSap->CmAf = pCmAf;
  200. InsertTailList(&pCmAf->CmSapList, &pCmSap->Linkage);
  201. REF_CM_AF(pCmAf);
  202. NdisReleaseSpinLock(&pCmAf->Lock);
  203. *CallMgrSapContext = pCmSap;
  204. return(STATUS_SUCCESS);
  205. }
  206. NDIS_STATUS
  207. PxCmDeRegisterSap(
  208. IN NDIS_HANDLE CallMgrSapContext
  209. )
  210. /*++
  211. Routine Description:
  212. Arguments:
  213. Return Value:
  214. NDIS_STATUS_SUCCESS if everything goes off well right here
  215. NDIS_STATUS_XXXX to indicate any error.
  216. --*/
  217. {
  218. PPX_CM_SAP pCmSap;
  219. PPX_CM_AF pCmAf;
  220. pCmSap = (PPX_CM_SAP)CallMgrSapContext;
  221. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  222. PXDEBUGP(PXD_LOUD, PXM_CM, ("PxCmDeRegisterSap: CmSap %p\n", pCmSap));
  223. pCmAf = pCmSap->CmAf;
  224. InterlockedExchange((PLONG)&pCmSap->State, PX_SAP_CLOSED);
  225. NdisAcquireSpinLock(&pCmAf->Lock);
  226. RemoveEntryList(&pCmSap->Linkage);
  227. DEREF_CM_AF_LOCKED(pCmAf);
  228. PxFreeCmSap(pCmSap);
  229. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  230. return(STATUS_SUCCESS);
  231. }
  232. NDIS_STATUS
  233. PxCmMakeCall(
  234. IN NDIS_HANDLE CallMgrVcContext,
  235. IN OUT PCO_CALL_PARAMETERS pCallParameters,
  236. IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
  237. OUT PNDIS_HANDLE pCallMgrPartyContext OPTIONAL
  238. )
  239. /*++
  240. Routine Description:
  241. We do not allow a client to make a call!
  242. Arguments:
  243. Return Value:
  244. NDIS_STATUS_SUCCESS if everything goes off well right here
  245. NDIS_STATUS_XXXX to indicate any error.
  246. --*/
  247. {
  248. ASSERT(0);
  249. return(STATUS_SUCCESS);
  250. }
  251. NDIS_STATUS
  252. PxCmCloseCall(
  253. IN NDIS_HANDLE CallMgrVcContext,
  254. IN NDIS_HANDLE CallMgrPartyContext OPTIONAL,
  255. IN PVOID Buffer OPTIONAL,
  256. IN UINT Size OPTIONAL
  257. )
  258. {
  259. PPX_VC pVc;
  260. PPX_CM_AF pCmAf;
  261. NDIS_STATUS Status;
  262. PXDEBUGP(PXD_LOUD, PXM_CM,
  263. ("PxCmCloseCall: VcCtx %x\n", CallMgrVcContext));
  264. GetVcFromCtx(CallMgrVcContext, &pVc);
  265. if (pVc == NULL) {
  266. PXDEBUGP(PXD_WARNING, PXM_CM,
  267. ("PxCmCloseCall: Invalid VcCtx %x!\n", CallMgrVcContext));
  268. return (NDIS_STATUS_SUCCESS);
  269. }
  270. NdisAcquireSpinLock(&pVc->Lock);
  271. pVc->HandoffState = PX_VC_HANDOFF_IDLE;
  272. pVc->CloseFlags |= PX_VC_CL_CLOSE_CALL;
  273. NdisReleaseSpinLock(&pVc->Lock);
  274. NdisCmCloseCallComplete(NDIS_STATUS_SUCCESS,
  275. pVc->CmVcHandle,
  276. NULL);
  277. #ifdef CODELETEVC_FIXED
  278. //
  279. // Evidently the CoCreateVc is unbalanced
  280. // when creating a proxy vc. The call to
  281. // NdisCoDeleteVc will fail because the
  282. // Vc is still active.
  283. // Investigate this with ndis guys!!!!!
  284. //
  285. Status =
  286. NdisCoDeleteVc(pVc->CmVcHandle);
  287. if (Status == NDIS_STATUS_SUCCESS) {
  288. pVc->CmVcHandle = NULL;
  289. }
  290. #endif
  291. NdisAcquireSpinLock(&pVc->Lock);
  292. //
  293. // If the Vc is no longer connected then
  294. // we are waiting for this part of the vc
  295. // to go away before we can cleanup the
  296. // vc with the call manager.
  297. //
  298. if (pVc->Flags & PX_VC_CLEANUP_CM) {
  299. ASSERT(pVc->State == PX_VC_DISCONNECTING);
  300. PxCloseCallWithCm(pVc);
  301. }
  302. pCmAf = pVc->CmAf;
  303. //
  304. // Remove the reference applied when the call
  305. // was dispatched to the client. We do not need
  306. // all of the ref code because of the ref applied
  307. // at entry to this function.
  308. //
  309. pVc->RefCount--;
  310. //
  311. // Deref for ref applied at entry when
  312. // validating the vc
  313. //
  314. DEREF_VC_LOCKED(pVc);
  315. DEREF_CM_AF(pCmAf);
  316. return(NDIS_STATUS_PENDING);
  317. }
  318. VOID
  319. PxCmIncomingCallComplete(
  320. IN NDIS_STATUS Status,
  321. IN NDIS_HANDLE CallMgrVcContext,
  322. IN PCO_CALL_PARAMETERS pCallParameters
  323. )
  324. {
  325. PPX_VC pVc;
  326. PXDEBUGP(PXD_LOUD, PXM_CM,
  327. ("PxCmIncomingCallComplete: VcCtx %x\n", CallMgrVcContext));
  328. GetVcFromCtx(CallMgrVcContext, &pVc);
  329. if (pVc == NULL) {
  330. PXDEBUGP(PXD_WARNING, PXM_CM,
  331. ("PxCmIncomingCallComplete: Invalid VcCtx %x!\n",
  332. CallMgrVcContext));
  333. return;
  334. }
  335. NdisAcquireSpinLock(&pVc->Lock);
  336. PXDEBUGP(PXD_LOUD, PXM_CM,
  337. ("PxCmIncomingCallComplete: Vc %p, Status %x\n",
  338. pVc, Status));
  339. PxSignal(&pVc->Block, Status);
  340. //
  341. // remove the ref applied when we mapped
  342. // the vcctx to the vc
  343. //
  344. DEREF_VC_LOCKED(pVc);
  345. }
  346. NDIS_STATUS
  347. PxCmAddParty(
  348. IN NDIS_HANDLE CallMgrVcContext,
  349. IN OUT PCO_CALL_PARAMETERS pCallParameters,
  350. IN NDIS_HANDLE NdisPartyHandle,
  351. OUT PNDIS_HANDLE pCallMgrPartyContext
  352. )
  353. /*++
  354. Routine Description:
  355. We do not allow a client to add a party to a vc!
  356. Arguments:
  357. Return Value:
  358. NDIS_STATUS_SUCCESS if everything goes off well right here
  359. NDIS_STATUS_XXXX to indicate any error.
  360. --*/
  361. {
  362. ASSERT(0);
  363. return(STATUS_SUCCESS);
  364. }
  365. NDIS_STATUS
  366. PxCmDropParty(
  367. IN NDIS_HANDLE CallMgrPartyContext,
  368. IN PVOID Buffer OPTIONAL,
  369. IN UINT Size OPTIONAL
  370. )
  371. /*++
  372. Routine Description:
  373. We do not allow a client to drop a party on a vc!
  374. Arguments:
  375. Return Value:
  376. NDIS_STATUS_SUCCESS if everything goes off well right here
  377. NDIS_STATUS_XXXX to indicate any error.
  378. --*/
  379. {
  380. ASSERT(0);
  381. return(STATUS_SUCCESS);
  382. }
  383. VOID
  384. PxCmActivateVcComplete(
  385. IN NDIS_STATUS Status,
  386. IN NDIS_HANDLE CallMgrVcContext,
  387. IN PCO_CALL_PARAMETERS pCallParameters)
  388. /*++
  389. Routine Description:
  390. The vc has already been activate by the underlying
  391. call manager/miniport!
  392. Arguments:
  393. Return Value:
  394. NDIS_STATUS_SUCCESS if everything goes off well right here
  395. NDIS_STATUS_XXXX to indicate any error.
  396. --*/
  397. {
  398. ASSERT(0);
  399. }
  400. VOID
  401. PxCmDeActivateVcComplete(
  402. IN NDIS_STATUS Status,
  403. IN NDIS_HANDLE CallMgrVcContext
  404. )
  405. /*++
  406. Routine Description:
  407. The vc is never deactivated by our call manager!
  408. Arguments:
  409. Return Value:
  410. NDIS_STATUS_SUCCESS if everything goes off well right here
  411. NDIS_STATUS_XXXX to indicate any error.
  412. --*/
  413. {
  414. ASSERT(0);
  415. }
  416. NDIS_STATUS
  417. PxCmModifyCallQos(
  418. IN NDIS_HANDLE CallMgrVcContext,
  419. IN PCO_CALL_PARAMETERS pCallParameters
  420. )
  421. /*++
  422. Routine Description:
  423. Not sure what to do here right now!
  424. ToDo!!!!!!!!!!
  425. Arguments:
  426. Return Value:
  427. NDIS_STATUS_SUCCESS if everything goes off well right here
  428. NDIS_STATUS_XXXX to indicate any error.
  429. --*/
  430. {
  431. return(STATUS_SUCCESS);
  432. }
  433. NDIS_STATUS
  434. PxCmRequest(
  435. IN NDIS_HANDLE ProtocolAfContext,
  436. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  437. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  438. IN OUT PNDIS_REQUEST NdisRequest
  439. )
  440. /*++
  441. Routine Description:
  442. We will handle requests from the clients and pass them down
  443. to the underlying call manager/miniport if needed.
  444. Arguments:
  445. Return Value:
  446. NDIS_STATUS_SUCCESS if everything goes off well right here
  447. NDIS_STATUS_XXXX to indicate any error.
  448. --*/
  449. {
  450. return(STATUS_SUCCESS);
  451. }
  452. VOID
  453. PxCmRequestComplete(
  454. IN NDIS_STATUS Status,
  455. IN NDIS_HANDLE ProtocolAfContext,
  456. IN NDIS_HANDLE ProtocolVcContext, // Optional
  457. IN NDIS_HANDLE ProtocolPartyContext, // Optional
  458. IN PNDIS_REQUEST NdisRequest
  459. )
  460. /*++
  461. Routine Description:
  462. Called by the client upon completion of any requests
  463. that we have passed up to it. If this request needed to
  464. be completed synchronously (status matters) then we will
  465. signal completion and let the calling routine free the
  466. memory. If this could complete asynchronously then we
  467. just free the memory here.
  468. Arguments:
  469. Return Value:
  470. NDIS_STATUS_SUCCESS if everything goes off well right here
  471. NDIS_STATUS_XXXX to indicate any error.
  472. --*/
  473. {
  474. PPX_REQUEST pProxyRequest;
  475. PPX_CM_AF pCmAf;
  476. PPX_VC pVc;
  477. pCmAf = (PPX_CM_AF)ProtocolAfContext;
  478. pVc = (PPX_VC)ProtocolVcContext;
  479. PXDEBUGP(PXD_INFO, PXM_CM, ("PxCmRequestComplete: CmAf %p, Vc %p\n", pCmAf, pVc));
  480. pProxyRequest = CONTAINING_RECORD(NdisRequest, PX_REQUEST, NdisRequest);
  481. if (pProxyRequest->Flags & PX_REQ_ASYNC) {
  482. pProxyRequest->Flags &= ~PX_REQ_ASYNC;
  483. PxFreeMem(pProxyRequest);
  484. DEREF_CM_AF(pCmAf);
  485. } else {
  486. PxSignal(&pProxyRequest->Block, Status);
  487. }
  488. }