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.

511 lines
13 KiB

  1. /*++
  2. Copyright (c) 1990-1997 Microsoft Corporation
  3. Module Name:
  4. cm.c
  5. Abstract:
  6. This file contains the functions that implement the ndiswan
  7. NDIS 5.0 call manager interface. These functions are used by the
  8. ndiswan miniport and NDIS 5.0 clients.
  9. Author:
  10. Tony Bell (TonyBe) January 9, 1997
  11. Environment:
  12. Kernel Mode
  13. Revision History:
  14. TonyBe 01/09/97 Created
  15. --*/
  16. #include "wan.h"
  17. #include "traffic.h"
  18. #include "ntddtc.h"
  19. #define __FILE_SIG__ CM_FILESIG
  20. NDIS_STATUS
  21. CmCreateVc(
  22. IN NDIS_HANDLE ProtocolAfContext,
  23. IN NDIS_HANDLE NdisVcHandle,
  24. OUT PNDIS_HANDLE ProtocolVcContext
  25. )
  26. {
  27. PCM_AFSAPCB AfSapCB = (PCM_AFSAPCB)ProtocolAfContext;
  28. PCM_VCCB CmVcCB;
  29. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmCreateVc: Enter"));
  30. CmVcCB =
  31. NdisWanAllocateCmVcCB(AfSapCB, NdisVcHandle);
  32. if (CmVcCB == NULL) {
  33. return (NDIS_STATUS_RESOURCES);
  34. }
  35. *ProtocolVcContext = CmVcCB;
  36. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmCreateVc: Exit"));
  37. return (NDIS_STATUS_SUCCESS);
  38. }
  39. NDIS_STATUS
  40. CmDeleteVc(
  41. IN NDIS_HANDLE ProtocolVcContext
  42. )
  43. {
  44. PCM_VCCB CmVcCB;
  45. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmDeleteVc: Enter"));
  46. CmVcCB = (PCM_VCCB)ProtocolVcContext;
  47. ASSERT(CmVcCB->RefCount == 0);
  48. NdisWanFreeCmVcCB(CmVcCB);
  49. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmDeleteVc: Exit"));
  50. return (NDIS_STATUS_SUCCESS);
  51. }
  52. NDIS_STATUS
  53. CmOpenAf(
  54. IN NDIS_HANDLE CallMgrBindingContext,
  55. IN PCO_ADDRESS_FAMILY AddressFamily,
  56. IN NDIS_HANDLE NdisAfHandle,
  57. OUT PNDIS_HANDLE CallMgrAfContext
  58. )
  59. {
  60. PMINIPORTCB MiniportCB = (PMINIPORTCB)CallMgrBindingContext;
  61. PCM_AFSAPCB AfSapCB;
  62. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmOpenAf: Enter"));
  63. if (AddressFamily->AddressFamily != CO_ADDRESS_FAMILY_PPP) {
  64. return (NDIS_STATUS_FAILURE);
  65. }
  66. AfSapCB =
  67. NdisWanAllocateCmAfSapCB(MiniportCB);
  68. if (AfSapCB == NULL) {
  69. return (NDIS_STATUS_RESOURCES);
  70. }
  71. *CallMgrAfContext = (NDIS_HANDLE)AfSapCB;
  72. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmOpenAf: Exit"));
  73. return(NDIS_STATUS_SUCCESS);
  74. }
  75. NDIS_STATUS
  76. CmCloseAf(
  77. IN NDIS_HANDLE CallMgrAfContext
  78. )
  79. {
  80. PCM_AFSAPCB AfSapCB = (PCM_AFSAPCB)CallMgrAfContext;
  81. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmCloseAf: Enter"));
  82. NdisWanFreeCmAfSapCB(AfSapCB);
  83. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmCloseAf: Exit"));
  84. return(NDIS_STATUS_SUCCESS);
  85. }
  86. NDIS_STATUS
  87. CmRegisterSap(
  88. IN NDIS_HANDLE CallMgrAfContext,
  89. IN PCO_SAP Sap,
  90. IN NDIS_HANDLE NdisSapHandle,
  91. OUT PNDIS_HANDLE CallMgrSapContext
  92. )
  93. {
  94. PMINIPORTCB MiniportCB = (PMINIPORTCB)CallMgrAfContext;
  95. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmRegisterSap: Enter SapType %d", Sap->SapType));
  96. *CallMgrSapContext = CallMgrAfContext;
  97. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmRegisterSap: Exit"));
  98. return(NDIS_STATUS_SUCCESS);
  99. }
  100. NDIS_STATUS
  101. CmDeregisterSap(
  102. IN NDIS_HANDLE CallMgrSapContext
  103. )
  104. {
  105. PCM_AFSAPCB AfSapCB = (PCM_AFSAPCB)CallMgrSapContext;
  106. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmDeregisterSap: Enter"));
  107. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmDeregisterSap: Exit"));
  108. return(NDIS_STATUS_SUCCESS);
  109. }
  110. NDIS_STATUS
  111. CmMakeCall(
  112. IN NDIS_HANDLE CallMgrVcContext,
  113. IN OUT PCO_CALL_PARAMETERS CallParameters,
  114. IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
  115. OUT PNDIS_HANDLE CallMgrPartyContext OPTIONAL
  116. )
  117. {
  118. PBUNDLECB BundleCB;
  119. PPROTOCOLCB ProtocolCB;
  120. PCM_VCCB CmVcCB;
  121. PCO_CALL_MANAGER_PARAMETERS CallMgrParams;
  122. PCO_MEDIA_PARAMETERS MediaParams;
  123. PCO_SPECIFIC_PARAMETERS SpecificParams;
  124. LPQOS_WAN_MEDIA QosMedia;
  125. LPQOS_OBJECT_HDR QoSObject;
  126. LONG ParamsLength;
  127. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  128. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmMakeCall: Enter"));
  129. CmVcCB = (PCM_VCCB)CallMgrVcContext;
  130. CallMgrParams =
  131. CallParameters->CallMgrParameters;
  132. MediaParams =
  133. CallParameters->MediaParameters;
  134. SpecificParams = &MediaParams->MediaSpecific;
  135. if (SpecificParams->ParamType != PARAM_TYPE_GQOS_INFO) {
  136. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_CM,
  137. ("CmMakeCall: Not a QOS Vc! ParamType %x", SpecificParams->ParamType));
  138. return (NDIS_STATUS_FAILURE);
  139. }
  140. QosMedia = (LPQOS_WAN_MEDIA)SpecificParams->Parameters;
  141. //
  142. // Need to check the flowspec for bandwidth
  143. //
  144. do {
  145. ULONG_PTR BIndex, PIndex;
  146. //
  147. // Get the protocolcb
  148. //
  149. GetNdisWanIndices(QosMedia->LinkId, BIndex, PIndex);
  150. if (!IsBundleValid((NDIS_HANDLE)BIndex,
  151. TRUE,
  152. &BundleCB)) {
  153. Status = NDIS_STATUS_FAILURE;
  154. break;
  155. }
  156. AcquireBundleLock(BundleCB);
  157. PROTOCOLCB_FROM_PROTOCOLH(BundleCB, ProtocolCB, PIndex);
  158. if (ProtocolCB == NULL ||
  159. ProtocolCB == (PVOID)RESERVED_PROTOCOLCB ||
  160. ProtocolCB->State != PROTOCOL_ROUTED) {
  161. ReleaseBundleLock(BundleCB);
  162. Status = NDIS_STATUS_FAILURE;
  163. break;
  164. }
  165. //
  166. // If we don't have multilink or if we have encryption then we can not
  167. // do isslow
  168. //
  169. if (!(BundleCB->FramingInfo.SendFramingBits & PPP_MULTILINK_FRAMING) ||
  170. (BundleCB->SendFlags & DO_ENCRYPTION)) {
  171. CmVcCB->FlowClass = 0;
  172. } else {
  173. if (QosMedia->ISSLOW == 1) {
  174. CmVcCB->FlowClass = MAX_MCML;
  175. BundleCB->Flags |= QOS_ENABLED;
  176. } else {
  177. CmVcCB->FlowClass = 0;
  178. }
  179. }
  180. #ifdef USE_QOS_WORKER
  181. NdisInitializeWorkItem(&BundleCB->QoSWorkItem,
  182. QoSSendFragments,
  183. BundleCB);
  184. #endif
  185. SetBundleFlags(BundleCB);
  186. NdisWanDbgOut(DBG_INFO, DBG_CM, ("MakeCall Vc/Protocol %p/%p %d/%d",
  187. CmVcCB, ProtocolCB, CmVcCB->State, ProtocolCB->State));
  188. NdisWanDbgOut(DBG_INFO, DBG_CM, ("Setting FlowClass %x Isslow %d",
  189. CmVcCB->FlowClass, QosMedia->ISSLOW));
  190. REF_CMVCCB(CmVcCB);
  191. CmVcCB->ProtocolCB = ProtocolCB;
  192. InsertTailList(&ProtocolCB->VcList, &CmVcCB->Linkage);
  193. REF_PROTOCOLCB(ProtocolCB);
  194. ReleaseBundleLock(BundleCB);
  195. InterlockedExchange((PLONG)&CmVcCB->State, CMVC_ACTIVE);
  196. NdisMCmActivateVc(CmVcCB->NdisVcHandle, CallParameters);
  197. } while (FALSE);
  198. //
  199. // Deref for ref applied in IsBundleValid
  200. //
  201. DEREF_BUNDLECB(BundleCB);
  202. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmMakeCall: Exit"));
  203. return(Status);
  204. }
  205. NDIS_STATUS
  206. CmCloseCall(
  207. IN NDIS_HANDLE CallMgrVcContext,
  208. IN NDIS_HANDLE CallMgrPartyContext OPTIONAL,
  209. IN PVOID CloseData OPTIONAL,
  210. IN UINT Size OPTIONAL
  211. )
  212. {
  213. PPROTOCOLCB ProtocolCB;
  214. PBUNDLECB BundleCB;
  215. PCM_VCCB CmVcCB;
  216. BOOLEAN DisableQoS = TRUE;
  217. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmCloseCall: Enter"));
  218. CmVcCB = (PCM_VCCB)CallMgrVcContext;
  219. ProtocolCB =
  220. CmVcCB->ProtocolCB;
  221. BundleCB =
  222. ProtocolCB->BundleCB;
  223. AcquireBundleLock(BundleCB);
  224. if (CmVcCB->State != CMVC_CLOSE_DISPATCHED) {
  225. RemoveEntryList(&CmVcCB->Linkage);
  226. }
  227. //
  228. // Walk the Vc list and see if there are any
  229. // ISSLOW Vc's. If there are not then disable QOS
  230. //
  231. {
  232. PCM_VCCB _vc;
  233. _vc = (PCM_VCCB)ProtocolCB->VcList.Flink;
  234. while ((PVOID)_vc != (PVOID)&ProtocolCB->VcList) {
  235. if (_vc->FlowClass == MAX_MCML) {
  236. DisableQoS = FALSE;
  237. break;
  238. }
  239. _vc = (PCM_VCCB)_vc->Linkage.Flink;
  240. }
  241. }
  242. NdisWanDbgOut(DBG_INFO, DBG_CM, ("CloseCall Vc/Protocol %p/%p %d/%d",
  243. CmVcCB, ProtocolCB, CmVcCB->State, ProtocolCB->State));
  244. InterlockedExchange((PLONG)&CmVcCB->State, CMVC_CLOSING);
  245. DEREF_CMVCCB(CmVcCB);
  246. DEREF_PROTOCOLCB(ProtocolCB);
  247. if (DisableQoS && BundleCB != NULL) {
  248. BundleCB->Flags &= ~QOS_ENABLED;
  249. }
  250. ReleaseBundleLock(BundleCB);
  251. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmCloseCall: Exit"));
  252. return(NDIS_STATUS_PENDING);
  253. }
  254. NDIS_STATUS
  255. CmModifyCallQoS(
  256. IN NDIS_HANDLE CallMgrVcContext,
  257. IN PCO_CALL_PARAMETERS CallParameters
  258. )
  259. {
  260. PCM_VCCB CmVcCB;
  261. PCO_CALL_MANAGER_PARAMETERS CallMgrParams;
  262. PCO_MEDIA_PARAMETERS MediaParams;
  263. PCO_SPECIFIC_PARAMETERS SpecificParams;
  264. LPQOS_WAN_MEDIA QosMedia;
  265. LPQOS_OBJECT_HDR QoSObject;
  266. PBUNDLECB BundleCB;
  267. PPROTOCOLCB ProtocolCB;
  268. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmModifyCallQos: Enter"));
  269. CmVcCB = (PCM_VCCB)CallMgrVcContext;
  270. CallMgrParams =
  271. CallParameters->CallMgrParameters;
  272. MediaParams =
  273. CallParameters->MediaParameters;
  274. SpecificParams = &MediaParams->MediaSpecific;
  275. if (SpecificParams->ParamType != PARAM_TYPE_GQOS_INFO) {
  276. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_CM,
  277. ("CmMakeCall: Not a QOS Vc! ParamType %x", SpecificParams->ParamType));
  278. return (NDIS_STATUS_SUCCESS);
  279. }
  280. QosMedia = (LPQOS_WAN_MEDIA)SpecificParams->Parameters;
  281. ProtocolCB = CmVcCB->ProtocolCB;
  282. if (ProtocolCB == NULL) {
  283. return (NDIS_STATUS_SUCCESS);
  284. }
  285. BundleCB = ProtocolCB->BundleCB;
  286. if (BundleCB == NULL) {
  287. return (NDIS_STATUS_SUCCESS);
  288. }
  289. AcquireBundleLock(BundleCB);
  290. //
  291. // If we don't have multilink or if we have encryption then we can not
  292. // do isslow
  293. //
  294. if (!(BundleCB->FramingInfo.SendFramingBits & PPP_MULTILINK_FRAMING) ||
  295. (BundleCB->SendFlags & DO_ENCRYPTION))
  296. {
  297. CmVcCB->FlowClass = 0;
  298. } else {
  299. if (QosMedia->ISSLOW == 1) {
  300. CmVcCB->FlowClass = MAX_MCML;
  301. BundleCB->Flags |= QOS_ENABLED;
  302. } else {
  303. CmVcCB->FlowClass = 0;
  304. // Walk the Vc list and see if there are any
  305. // ISSLOW Vc's. If there are not then disable QOS
  306. {
  307. PCM_VCCB _vc;
  308. BOOLEAN DisableQoS = TRUE;
  309. _vc = (PCM_VCCB)ProtocolCB->VcList.Flink;
  310. while ((PVOID)_vc != (PVOID)&ProtocolCB->VcList) {
  311. if (_vc->FlowClass == MAX_MCML) {
  312. DisableQoS = FALSE;
  313. break;
  314. }
  315. _vc = (PCM_VCCB)_vc->Linkage.Flink;
  316. }
  317. if (DisableQoS) {
  318. BundleCB->Flags &= ~QOS_ENABLED;
  319. }
  320. }
  321. }
  322. }
  323. SetBundleFlags(BundleCB);
  324. ReleaseBundleLock(BundleCB);
  325. NdisWanDbgOut(DBG_DEATH, DBG_CM, ("Updating FlowClass %x for Vc/Protocol %p/%p, Isslow %d",
  326. CmVcCB->FlowClass, CmVcCB, CmVcCB->ProtocolCB, QosMedia->ISSLOW));
  327. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmModifyCallQos: Exit"));
  328. return(NDIS_STATUS_SUCCESS);
  329. }
  330. VOID
  331. CmIncomingCallComplete(
  332. IN NDIS_STATUS Status,
  333. IN NDIS_HANDLE CallMgrVcContext,
  334. IN PCO_CALL_PARAMETERS CallParameters
  335. )
  336. {
  337. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmIncomingCallComplete: Enter"));
  338. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmIncomingCallComplete: Exit"));
  339. }
  340. VOID
  341. CmActivateVcComplete(
  342. IN NDIS_STATUS Status,
  343. IN NDIS_HANDLE CallMgrVcContext,
  344. IN PCO_CALL_PARAMETERS CallParameters
  345. )
  346. {
  347. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmActivateVcComplete: Enter"));
  348. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmActivateVcComplete: Exit"));
  349. }
  350. VOID
  351. CmDeactivateVcComplete(
  352. IN NDIS_STATUS Status,
  353. IN NDIS_HANDLE CallMgrVcContext
  354. )
  355. {
  356. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmDeactivateVcComplete: Enter"));
  357. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmDeactivateVcComplete: Exit"));
  358. }
  359. NDIS_STATUS
  360. CmRequest(
  361. IN NDIS_HANDLE ProtocolAfContext,
  362. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  363. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  364. IN OUT PNDIS_REQUEST NdisRequest
  365. )
  366. {
  367. NDIS_STATUS Status;
  368. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmRequest: Enter"));
  369. Status =
  370. NdisWanCoOidProc((PMINIPORTCB)ProtocolAfContext,
  371. (PCM_VCCB)ProtocolVcContext,
  372. NdisRequest);
  373. NdisWanDbgOut(DBG_TRACE, DBG_CM, ("CmRequest: Exit Status: 0x%x", Status));
  374. return(Status);
  375. }