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.

2964 lines
88 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. pxutils.c
  5. Abstract:
  6. Utility routines called by entry point functions. Split out into
  7. a separate file to keep the "entry point" files clean.
  8. Revision History:
  9. Who When What
  10. -------- -------- ----------------------------------------------
  11. arvindm 02-15-96 Created
  12. arvindm 04-30-96 Port to NDIS 4.1
  13. rmachin 11-01-96 ATM - utils adapted for NDIS Proxy
  14. tonybe 01-23-98 rewrite and cleanup
  15. Notes:
  16. --*/
  17. #include "precomp.h"
  18. #include "atm.h"
  19. #include "stdio.h"
  20. #define MODULE_NUMBER MODULE_UTIL
  21. #define _FILENUMBER 'LITU'
  22. #define MAX_SDU_SIZE 8192
  23. PXTAPI_CALL_PARAM_ENTRY PxTapiCallParamList[] =
  24. {
  25. PX_TCP_ENTRY(ulOrigAddressSize, ulOrigAddressOffset),
  26. PX_TCP_ENTRY(ulDisplayableAddressSize, ulDisplayableAddressOffset),
  27. PX_TCP_ENTRY(ulCalledPartySize, ulCalledPartyOffset),
  28. PX_TCP_ENTRY(ulCommentSize, ulCommentOffset),
  29. PX_TCP_ENTRY(ulUserUserInfoSize, ulUserUserInfoOffset),
  30. PX_TCP_ENTRY(ulHighLevelCompSize, ulHighLevelCompOffset),
  31. PX_TCP_ENTRY(ulLowLevelCompSize, ulLowLevelCompOffset),
  32. PX_TCP_ENTRY(ulDevSpecificSize, ulDevSpecificOffset)
  33. };
  34. #define PX_TCP_NUM_ENTRIES (sizeof(PxTapiCallParamList) / sizeof(PXTAPI_CALL_PARAM_ENTRY))
  35. PXTAPI_CALL_INFO_ENTRY PxTapiCallInfoList[] =
  36. {
  37. PX_TCI_ENTRY(ulCallerIDSize, ulCallerIDOffset),
  38. PX_TCI_ENTRY(ulCallerIDNameSize, ulCallerIDNameOffset),
  39. PX_TCI_ENTRY(ulCalledIDSize, ulCalledIDOffset),
  40. PX_TCI_ENTRY(ulCalledIDNameSize, ulCalledIDNameOffset),
  41. PX_TCI_ENTRY(ulConnectedIDSize, ulConnectedIDOffset),
  42. PX_TCI_ENTRY(ulConnectedIDNameSize, ulConnectedIDNameOffset),
  43. PX_TCI_ENTRY(ulRedirectionIDSize, ulRedirectionIDOffset),
  44. PX_TCI_ENTRY(ulRedirectionIDNameSize, ulRedirectionIDNameOffset),
  45. PX_TCI_ENTRY(ulRedirectingIDSize, ulRedirectingIDOffset),
  46. PX_TCI_ENTRY(ulRedirectingIDNameSize, ulRedirectingIDNameOffset),
  47. PX_TCI_ENTRY(ulAppNameSize, ulAppNameOffset),
  48. PX_TCI_ENTRY(ulDisplayableAddressSize, ulDisplayableAddressOffset),
  49. PX_TCI_ENTRY(ulCalledPartySize, ulCalledPartyOffset),
  50. PX_TCI_ENTRY(ulCommentSize, ulCommentOffset),
  51. PX_TCI_ENTRY(ulDisplaySize, ulDisplayOffset),
  52. PX_TCI_ENTRY(ulUserUserInfoSize, ulUserUserInfoOffset),
  53. PX_TCI_ENTRY(ulHighLevelCompSize, ulHighLevelCompOffset),
  54. PX_TCI_ENTRY(ulLowLevelCompSize, ulLowLevelCompOffset),
  55. PX_TCI_ENTRY(ulChargingInfoSize, ulChargingInfoOffset),
  56. PX_TCI_ENTRY(ulTerminalModesSize, ulTerminalModesOffset),
  57. PX_TCI_ENTRY(ulDevSpecificSize, ulDevSpecificOffset)
  58. };
  59. #define PX_TCI_NUM_ENTRIES (sizeof(PxTapiCallInfoList) / sizeof(PXTAPI_CALL_INFO_ENTRY))
  60. BOOLEAN
  61. PxIsAdapterAlreadyBound(
  62. PNDIS_STRING pDeviceName
  63. )
  64. /*++
  65. Routine Description:
  66. Check if we have already bound to a device (adapter).
  67. Arguments:
  68. pDeviceName - Points to device name to be checked.
  69. Return Value:
  70. TRUE iff we already have an Adapter structure representing
  71. this device.
  72. --*/
  73. {
  74. PPX_ADAPTER pAdapter;
  75. BOOLEAN bFound = FALSE;
  76. PLIST_ENTRY Entry;
  77. NdisAcquireSpinLock(&(DeviceExtension->Lock));
  78. Entry = DeviceExtension->AdapterList.Flink;
  79. pAdapter = CONTAINING_RECORD(Entry,
  80. PX_ADAPTER,
  81. Linkage);
  82. while ((PVOID)pAdapter != (PVOID)&DeviceExtension->AdapterList) {
  83. if ((pDeviceName->Length == pAdapter->DeviceName.Length) &&
  84. (NdisEqualMemory(pDeviceName->Buffer,
  85. pAdapter->DeviceName.Buffer,
  86. pDeviceName->Length) == (ULONG)1)) {
  87. bFound = TRUE;
  88. break;
  89. }
  90. Entry = pAdapter->Linkage.Flink;
  91. pAdapter = CONTAINING_RECORD(Entry,
  92. PX_ADAPTER,
  93. Linkage);
  94. }
  95. NdisReleaseSpinLock(&(DeviceExtension->Lock));
  96. return (bFound);
  97. }
  98. PPX_ADAPTER
  99. PxAllocateAdapter(
  100. ULONG ulAdditionalLength
  101. )
  102. /*++
  103. Routine Description:
  104. Allocate a new Adapter structure, assign an adapter number to it, and
  105. chain it to the Global list of adapters. We maintain this list in
  106. ascending order by AdapterNo, which makes it easy to figure out the
  107. lowest unused AdapterNo.
  108. Arguments:
  109. None
  110. Return Value:
  111. Pointer to allocated adapter structure, if successful. NULL otherwise.
  112. --*/
  113. {
  114. PPX_ADAPTER pNewAdapter;
  115. ULONG SizeNeeded;
  116. SizeNeeded = sizeof(PX_ADAPTER) + ulAdditionalLength;
  117. PxAllocMem(pNewAdapter,
  118. SizeNeeded,
  119. PX_ADAPTER_TAG);
  120. if(pNewAdapter == (PPX_ADAPTER)NULL){
  121. return NULL;
  122. }
  123. NdisZeroMemory(pNewAdapter, SizeNeeded);
  124. //
  125. // Initialize the new adapter structure
  126. //
  127. pNewAdapter->State = PX_ADAPTER_OPENING;
  128. pNewAdapter->Sig = PX_ADAPTER_SIG;
  129. NdisAllocateSpinLock(&pNewAdapter->Lock);
  130. InitializeListHead(&pNewAdapter->CmAfList);
  131. InitializeListHead(&pNewAdapter->CmAfClosingList);
  132. InitializeListHead(&pNewAdapter->ClAfList);
  133. InitializeListHead(&pNewAdapter->ClAfClosingList);
  134. NdisAcquireSpinLock(&DeviceExtension->Lock);
  135. InsertTailList(&DeviceExtension->AdapterList, &pNewAdapter->Linkage);
  136. NdisReleaseSpinLock(&DeviceExtension->Lock);
  137. PXDEBUGP(PXD_LOUD, PXM_UTILS, ("PxAllocAdapter: new adapter %p\n", pNewAdapter));
  138. return (pNewAdapter);
  139. }
  140. VOID
  141. PxFreeAdapter(
  142. PPX_ADAPTER pAdapter
  143. )
  144. /*++
  145. Routine Description:
  146. Remove an adapter structure from the global list of adapters and free
  147. its memory.
  148. Arguments:
  149. pAdapter - pointer to Adapter to be released
  150. Return Value:
  151. None
  152. --*/
  153. {
  154. PPX_ADAPTER *ppNextAdapter;
  155. PXDEBUGP(PXD_LOUD, PXM_UTILS, ("PxFreeAdapter: pAdapter 0x%x\n", pAdapter));
  156. ASSERT(pAdapter->State == PX_ADAPTER_CLOSING);
  157. ASSERT(IsListEmpty(&pAdapter->CmAfList));
  158. ASSERT(IsListEmpty(&pAdapter->CmAfClosingList));
  159. ASSERT(IsListEmpty(&pAdapter->ClAfList));
  160. ASSERT(IsListEmpty(&pAdapter->ClAfClosingList));
  161. pAdapter->State = PX_ADAPTER_CLOSED;
  162. NdisAcquireSpinLock(&(DeviceExtension->Lock));
  163. RemoveEntryList(&pAdapter->Linkage);
  164. NdisReleaseSpinLock(&(DeviceExtension->Lock));
  165. NdisFreeSpinLock(&(pAdapter->Lock));
  166. PxFreeMem(pAdapter);
  167. }
  168. PPX_CM_AF
  169. PxAllocateCmAf(
  170. IN PCO_ADDRESS_FAMILY pFamily
  171. )
  172. {
  173. UINT SizeNeeded;
  174. PPX_CM_AF pCmAf;
  175. SizeNeeded = sizeof(PX_CM_AF);
  176. PxAllocMem(pCmAf, SizeNeeded, PX_CMAF_TAG);
  177. if(pCmAf == (PPX_CM_AF)NULL) {
  178. return NULL;
  179. }
  180. NdisZeroMemory((PUCHAR)pCmAf, SizeNeeded);
  181. NdisAllocateSpinLock(&(pCmAf->Lock));
  182. NdisMoveMemory(&pCmAf->Af, pFamily, sizeof(CO_ADDRESS_FAMILY));
  183. InitializeListHead(&pCmAf->CmSapList);
  184. InitializeListHead(&pCmAf->VcList);
  185. pCmAf->RefCount = 1;
  186. PXDEBUGP(PXD_LOUD, PXM_UTILS, ("PxAllocCmAf: new af %p\n", pCmAf));
  187. return (pCmAf);
  188. }
  189. VOID
  190. PxFreeCmAf(
  191. PPX_CM_AF pCmAf
  192. )
  193. {
  194. ASSERT(pCmAf->Linkage.Flink == pCmAf->Linkage.Blink);
  195. PXDEBUGP(PXD_LOUD, PXM_UTILS, ("PxFreeCmAf: CmAf %p\n", pCmAf));
  196. NdisFreeSpinLock(&pCmAf->Lock);
  197. PxFreeMem(pCmAf);
  198. }
  199. PPX_CL_AF
  200. PxAllocateClAf(
  201. IN PCO_ADDRESS_FAMILY pFamily,
  202. IN PPX_ADAPTER pAdapter
  203. )
  204. /*++
  205. Routine Description:
  206. Allocate a new AF block structure and queue it off the global list.
  207. Arguments:
  208. None
  209. Return Value:
  210. Pointer to allocated AF block structure, if successful. NULL otherwise.
  211. --*/
  212. {
  213. PPX_CL_AF pClAf;
  214. PxAllocMem(pClAf, sizeof(PX_CL_AF), PX_CLAF_TAG);
  215. if(pClAf == (PPX_CL_AF)NULL) {
  216. return NULL;
  217. }
  218. NdisZeroMemory((PUCHAR)pClAf, sizeof(PX_CL_AF));
  219. PxInitBlockStruc(&pClAf->Block);
  220. NdisAllocateSpinLock(&(pClAf->Lock));
  221. NdisMoveMemory(&pClAf->Af, pFamily, sizeof(CO_ADDRESS_FAMILY));
  222. InitializeListHead(&pClAf->ClSapList);
  223. InitializeListHead(&pClAf->ClSapClosingList);
  224. InitializeListHead(&pClAf->VcList);
  225. InitializeListHead(&pClAf->VcClosingList);
  226. //
  227. // Specify any AF-specific functions
  228. //
  229. switch(pFamily->AddressFamily) {
  230. case CO_ADDRESS_FAMILY_Q2931:
  231. pClAf->AfGetNdisCallParams = PxAfXyzTranslateTapiCallParams;
  232. pClAf->AfGetTapiCallParams = PxAfXyzTranslateNdisCallParams;
  233. pClAf->AfGetNdisSap = PxAfXyzTranslateTapiSap;
  234. break;
  235. case CO_ADDRESS_FAMILY_TAPI_PROXY:
  236. pClAf->AfGetNdisCallParams = PxAfTapiTranslateTapiCallParams;
  237. pClAf->AfGetTapiCallParams = PxAfTapiTranslateNdisCallParams;
  238. pClAf->AfGetNdisSap = PxAfTapiTranslateTapiSap;
  239. break;
  240. #if 0
  241. case CO_ADDRESS_FAMILY_L2TP:
  242. case CO_ADDRESS_FAMILY_IRDA:
  243. pClAf->AfGetNdisCallParams = GenericGetNdisCallParams;
  244. pClAf->AfGetTapiCallParams = GenericGetTapiCallParams;
  245. pClAf->AfGetNdisSap = GenericTranslateTapiSap;
  246. break;
  247. #endif
  248. default:
  249. pClAf->AfGetNdisCallParams = PxAfXyzTranslateTapiCallParams;
  250. pClAf->AfGetTapiCallParams = PxAfXyzTranslateNdisCallParams;
  251. pClAf->AfGetNdisSap = PxAfXyzTranslateTapiSap;
  252. break;
  253. }
  254. pClAf->State = PX_AF_OPENING;
  255. pClAf->RefCount = 1;
  256. pClAf->Adapter = pAdapter;
  257. PXDEBUGP(PXD_INFO, PXM_UTILS, ("PxAllocateClAf: exit. new ClAf %p\n", pClAf));
  258. return (pClAf);
  259. }
  260. VOID
  261. PxFreeClAf(
  262. PPX_CL_AF pClAf
  263. )
  264. /*++
  265. Routine Description:
  266. Remove an AF block structure from the global list and free
  267. its memory.
  268. Arguments:
  269. pAdapter - pointer to AF block to be released
  270. Return Value:
  271. None
  272. --*/
  273. {
  274. PXDEBUGP(PXD_INFO, PXM_UTILS, ("PxFreeClAf: ClAf %p\n", pClAf));
  275. NdisFreeSpinLock(&(pClAf->Lock));
  276. PxFreeMem(pClAf);
  277. }
  278. PPX_CM_SAP
  279. PxAllocateCmSap(
  280. PCO_SAP Sap
  281. )
  282. {
  283. PPX_CM_SAP pCmSap;
  284. ULONG SizeNeeded;
  285. PXDEBUGP(PXD_INFO, PXM_UTILS, ("PxAllocateCmSap: Sap %p\n", Sap));
  286. SizeNeeded = sizeof(PX_CM_SAP) + sizeof(CO_SAP) +
  287. Sap->SapLength + sizeof(PVOID);
  288. PxAllocMem((PUCHAR)pCmSap, SizeNeeded, PX_CMSAP_TAG);
  289. if (pCmSap == NULL) {
  290. PXDEBUGP(PXD_WARNING, PXM_UTILS,
  291. ("PxAllocateCmSap: Allocation failed Size %d\n", SizeNeeded));
  292. return (NULL);
  293. }
  294. NdisZeroMemory(pCmSap, SizeNeeded);
  295. InterlockedExchange((PLONG)&pCmSap->State, PX_SAP_OPENED);
  296. pCmSap->CoSap = (PCO_SAP)
  297. ((PUCHAR)pCmSap + sizeof(PX_CM_SAP) + sizeof(PVOID));
  298. (ULONG_PTR)pCmSap->CoSap &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  299. NdisMoveMemory(pCmSap->CoSap, Sap, sizeof(CO_SAP) - 1 + Sap->SapLength);
  300. return (pCmSap);
  301. }
  302. VOID
  303. PxFreeCmSap(
  304. PPX_CM_SAP pCmSap
  305. )
  306. {
  307. PXDEBUGP(PXD_LOUD, PXM_UTILS, ("PxFreeCmSap: CmSap %p\n", pCmSap));
  308. pCmSap->CoSap = NULL;
  309. PxFreeMem(pCmSap);
  310. }
  311. VOID
  312. PxFreeClSap(
  313. PPX_CL_SAP pClSap
  314. )
  315. {
  316. PXDEBUGP(PXD_LOUD, PXM_UTILS, ("PxFreeClSap: ClSap %p\n", pClSap));
  317. pClSap->CoSap = NULL;
  318. PxFreeMem(pClSap);
  319. }
  320. PPX_VC
  321. PxAllocateVc(
  322. IN PPX_CL_AF pClAf
  323. )
  324. {
  325. PPX_VC pVc;
  326. pVc =
  327. ExAllocateFromNPagedLookasideList(&VcLookaside);
  328. if (pVc == NULL) {
  329. return (NULL);
  330. }
  331. NdisZeroMemory(pVc, sizeof(PX_VC));
  332. NdisAllocateSpinLock(&pVc->Lock);
  333. NdisInitializeTimer(&pVc->InCallTimer,
  334. PxIncomingCallTimeout,
  335. (PVOID)pVc);
  336. PxInitBlockStruc(&pVc->Block);
  337. pVc->State = PX_VC_IDLE;
  338. InitializeListHead(&pVc->PendingDropReqs);
  339. //
  340. // This ref is removed when all vc activity
  341. // between the proxy and the client is finished.
  342. // For an outgoing call this is after the proxy
  343. // calls NdisClDeleteVc. For an incoming call
  344. // this is after the call manager has called
  345. // PxClDeleteVc.
  346. //
  347. pVc->RefCount = 1;
  348. pVc->ClAf = pClAf;
  349. pVc->Adapter = pClAf->Adapter;
  350. return (pVc);
  351. }
  352. VOID
  353. PxFreeVc(
  354. PPX_VC pVc
  355. )
  356. {
  357. PPX_TAPI_ADDR TapiAddr;
  358. PPX_TAPI_LINE TapiLine;
  359. if (pVc->CallInfo != NULL) {
  360. PxFreeMem(pVc->CallInfo);
  361. pVc->CallInfo = NULL;
  362. }
  363. if (pVc->pCallParameters != NULL) {
  364. PxFreeMem(pVc->pCallParameters);
  365. pVc->pCallParameters = NULL;
  366. }
  367. TapiAddr = pVc->TapiAddr;
  368. pVc->TapiAddr = NULL;
  369. TapiLine = pVc->TapiLine;
  370. pVc->TapiLine = NULL;
  371. if (TapiAddr != NULL) {
  372. InterlockedDecrement((PLONG)&TapiAddr->CallCount);
  373. }
  374. if (TapiLine != NULL) {
  375. InterlockedDecrement((PLONG)&TapiLine->DevStatus->ulNumActiveCalls);
  376. }
  377. NdisFreeSpinLock(&pVc->Lock);
  378. ExFreeToNPagedLookasideList(&VcLookaside, pVc);
  379. }
  380. #if 0
  381. NDIS_STATUS
  382. GenericGetNdisCallParams(
  383. IN PPX_VC pProxyVc,
  384. IN ULONG ulLineID,
  385. IN ULONG ulAddressID,
  386. IN ULONG ulFlags,
  387. IN PNDIS_TAPI_MAKE_CALL TapiBuffer,
  388. OUT PCO_CALL_PARAMETERS * pOutNdisCallParams
  389. )
  390. /*++
  391. Routine Description:
  392. Copies everything we can from TAPI CallParams buffer for a generic WAN_CO call to a WAN_CO
  393. call params buffer.
  394. Arguments:
  395. TapiBuffer -- the TAPI call params buffer
  396. pOutNdisCallParams -- pointer to the NDIS call params buffer pointer
  397. Return Value:
  398. None
  399. --*/
  400. {
  401. PCO_CALL_PARAMETERS pNdisCallParams;
  402. PCO_CALL_MANAGER_PARAMETERS pCallMgrParams;
  403. PCO_MEDIA_PARAMETERS pMediaParams;
  404. PWAN_CO_CALLMGR_PARAMETERS pWanCallMgrParams;
  405. PCO_MEDIA_PARAMETERS pMediaParameters;
  406. LINE_CALL_PARAMS* pTapiCallParams = (LINE_CALL_PARAMS*)&TapiBuffer->LineCallParams;
  407. ULONG ulRequestSize;
  408. UNICODE_STRING DialAddress;
  409. NDIS_STATUS Status;
  410. LPCWSTR lpcwszTemp;
  411. ULONG i;
  412. PXDEBUGP(PXD_INFO, PXM_UTILS, ("GenericGetNdisCallParams: enter\n"));
  413. //
  414. // Set up CallParameters structure.
  415. //
  416. ulRequestSize = sizeof(CO_CALL_PARAMETERS) +
  417. sizeof(CO_CALL_MANAGER_PARAMETERS) +
  418. sizeof(WAN_CO_CALLMGR_PARAMETERS) +
  419. sizeof(CO_MEDIA_PARAMETERS);
  420. do
  421. {
  422. PxAllocMem(pNdisCallParams, ulRequestSize, PX_COCALLPARAMS_TAG);
  423. if (pNdisCallParams == (PCO_CALL_PARAMETERS)NULL)
  424. {
  425. PXDEBUGP(PXD_WARNING, PXM_UTILS, ("GenericGetNdisCallParams: alloc (%d) failed\n", ulRequestSize));
  426. Status = NDIS_STATUS_RESOURCES;
  427. break;
  428. }
  429. NdisZeroMemory(pNdisCallParams, ulRequestSize);
  430. pCallMgrParams = (PCO_CALL_MANAGER_PARAMETERS)((PUCHAR)pNdisCallParams + sizeof(CO_CALL_PARAMETERS));
  431. pMediaParams = (PCO_MEDIA_PARAMETERS)((PUCHAR)pCallMgrParams +
  432. sizeof(CO_CALL_MANAGER_PARAMETERS) +
  433. sizeof(WAN_CO_CALLMGR_PARAMETERS));
  434. pNdisCallParams->CallMgrParameters = pCallMgrParams;
  435. pNdisCallParams->MediaParameters = pMediaParams;
  436. pCallMgrParams->CallMgrSpecific.ParamType = WAN_CO_CALLMGR_SPECIFIC;
  437. pCallMgrParams->CallMgrSpecific.Length = sizeof(WAN_CO_CALLMGR_PARAMETERS);
  438. pWanCallMgrParams = (PWAN_CO_CALLMGR_PARAMETERS)(pCallMgrParams->CallMgrSpecific.Parameters);
  439. pWanCallMgrParams->BearerType = pTapiCallParams->ulBearerMode;
  440. pWanCallMgrParams->MediaMode = pTapiCallParams->ulMediaMode;
  441. pWanCallMgrParams->MinRate = pTapiCallParams->ulMinRate;
  442. pWanCallMgrParams->MaxRate = pTapiCallParams->ulMaxRate;
  443. //
  444. // If there's a called address (should be), stick it in the
  445. // WAN call params
  446. //
  447. PxAssert (0 != TapiBuffer->ulDestAddressSize);
  448. lpcwszTemp = (LPWSTR) ((UCHAR *)TapiBuffer + TapiBuffer->ulDestAddressOffset);
  449. pWanCallMgrParams->CalledAddr.AddressLength = TapiBuffer->ulDestAddressSize;
  450. //
  451. // Move the address from the tapi buffer to the ndis buffer and
  452. // change from wchar to uchar.
  453. //
  454. for (i = 0;
  455. i < pWanCallMgrParams->CalledAddr.AddressLength;
  456. i++)
  457. {
  458. pWanCallMgrParams->CalledAddr.Address[i] = (UCHAR)lpcwszTemp[i];
  459. }
  460. pWanCallMgrParams->CalledAddr.Address[i] = '\0';
  461. pWanCallMgrParams->CalledAddr.Address[i+1] ='\0';
  462. pWanCallMgrParams->CalledAddr.Address[i+2] ='\0';
  463. PXDEBUGP(PXD_INFO, PXM_UTILS, ("CalledAddr %s\n", pWanCallMgrParams->CalledAddr.Address));
  464. //
  465. // If there's an originating address, stick it in the
  466. // WAN call params
  467. //
  468. if (0 != pTapiCallParams->ulOrigAddressSize)
  469. { // Address of call originator
  470. ULONG i;
  471. NdisMoveMemory(pWanCallMgrParams->OriginatingAddr.Address,
  472. ((UCHAR *)pTapiCallParams + pTapiCallParams->ulOrigAddressOffset),
  473. pTapiCallParams->ulOrigAddressSize);
  474. i = pWanCallMgrParams->OriginatingAddr.AddressLength =
  475. pTapiCallParams->ulOrigAddressSize;
  476. pWanCallMgrParams->OriginatingAddr.Address[i] = '\0';
  477. pWanCallMgrParams->OriginatingAddr.Address[i+1] ='\0';
  478. pWanCallMgrParams->OriginatingAddr.Address[i+2] ='\0';
  479. PXDEBUGP(PXD_INFO, PXM_UTILS, ("OriginatingAddr %s\n", pWanCallMgrParams->OriginatingAddr.Address));
  480. }
  481. if (0 != pTapiCallParams->ulLowLevelCompSize)
  482. {
  483. NdisMoveMemory ((UCHAR *)&pWanCallMgrParams->LowerLayerComp,
  484. &pTapiCallParams->ulLowLevelCompOffset,
  485. MIN (sizeof (WAN_LLI_COMP), pTapiCallParams->ulLowLevelCompSize));
  486. }
  487. if (0 != pTapiCallParams->ulHighLevelCompSize)
  488. {
  489. NdisMoveMemory ((UCHAR *)&pWanCallMgrParams->HigherLayerComp,
  490. &pTapiCallParams->ulHighLevelCompOffset,
  491. MIN (sizeof (WAN_HLI_COMP), pTapiCallParams->ulHighLevelCompSize));
  492. }
  493. if (0 != pTapiCallParams->ulDevSpecificSize)
  494. {
  495. pWanCallMgrParams->DevSpecificLength = pTapiCallParams->ulDevSpecificSize;
  496. NdisMoveMemory ((UCHAR *)&pWanCallMgrParams->DevSpecificData[0],
  497. &pTapiCallParams->ulDevSpecificOffset,
  498. pTapiCallParams->ulDevSpecificSize);
  499. }
  500. //
  501. // Set up the flowspec.
  502. // TBS: Start with a default flowspec that matches the service requirements for
  503. // specified mediamode. Then refine it.
  504. //
  505. if (!TapiBuffer->bUseDefaultLineCallParams)
  506. {
  507. PXDEBUGP(PXD_LOUD, PXM_UTILS, ("GenericGetNdisCallParams: moving TAPI call params\n"));
  508. //
  509. // These fields are in the FLOWSPEC sub-structure
  510. //
  511. pCallMgrParams->Transmit.TokenRate = pTapiCallParams->ulMaxRate;
  512. pCallMgrParams->Receive.TokenRate = pTapiCallParams->ulMaxRate;
  513. pCallMgrParams->Transmit.TokenBucketSize = 4096; //UNSPECIFIED_FLOWSPEC_VALUE;
  514. pCallMgrParams->Receive.TokenBucketSize = 4096; //UNSPECIFIED_FLOWSPEC_VALUE;
  515. pCallMgrParams->Transmit.MaxSduSize = 4096; //UNSPECIFIED_FLOWSPEC_VALUE;
  516. pCallMgrParams->Receive.MaxSduSize = 4096; //UNSPECIFIED_FLOWSPEC_VALUE;
  517. pCallMgrParams->Transmit.PeakBandwidth = pTapiCallParams->ulMaxRate;
  518. pCallMgrParams->Receive.PeakBandwidth = pTapiCallParams->ulMaxRate;
  519. if ((pTapiCallParams->ulBearerMode == LINEBEARERMODE_VOICE) ||
  520. (pTapiCallParams->ulBearerMode == LINEBEARERMODE_SPEECH) ||
  521. (pTapiCallParams->ulBearerMode == LINEBEARERMODE_ALTSPEECHDATA) ||
  522. (pTapiCallParams->ulBearerMode == LINEBEARERMODE_MULTIUSE))
  523. {
  524. pCallMgrParams->Receive.ServiceType = SERVICETYPE_BESTEFFORT;
  525. pCallMgrParams->Transmit.ServiceType = SERVICETYPE_BESTEFFORT;
  526. }
  527. //
  528. // TBS: Should MediaMode determine AAL?
  529. //
  530. }
  531. Status = NDIS_STATUS_SUCCESS;
  532. }while (FALSE);
  533. *pOutNdisCallParams = pNdisCallParams;
  534. PXDEBUGP(PXD_INFO, PXM_UTILS, ("GenericGetNdisCallParams: exit: NdisCallParams = x%x\n", pNdisCallParams));
  535. return (Status);
  536. }
  537. NDIS_STATUS
  538. GenericGetTapiCallParams(
  539. IN PPX_VC pVc,
  540. IN PCO_CALL_PARAMETERS pCallParams
  541. )
  542. /*++
  543. Routine Description:
  544. Copies everything we can from NDIS CallParams buffer for a Q2931 call into TAPI
  545. call params buffer.
  546. Arguments:
  547. pCallParams -- the NDIS call params buffer
  548. pVc -- pointer to a TAPI call
  549. Return Value:
  550. None
  551. --*/
  552. {
  553. PCO_CALL_MANAGER_PARAMETERS pCallMgrParams;
  554. PWAN_CO_CALLMGR_PARAMETERS pWanCallMgrParams;
  555. LINE_CALL_INFO *CallInfo;
  556. INT VarDataUsed = 0;
  557. NDIS_STATUS Status;
  558. PPX_TAPI_PROVIDER TapiProvider;
  559. PPX_TAPI_LINE TapiLine;
  560. PPX_TAPI_ADDR TapiAddr;
  561. PXDEBUGP(PXD_LOUD, PXM_UTILS, ("GenericGetTapiCallParams: enter. Call %x\n", pVc));
  562. pVc->pCallParameters =
  563. PxCopyCallParameters(pCallParams);
  564. if (pVc->pCallParameters == NULL) {
  565. PXDEBUGP(PXD_WARNING, PXM_CL,
  566. ("GenericGetTapiCallParams: failed to allocate memory for callparams\n"));
  567. return (NDIS_STATUS_RESOURCES);
  568. }
  569. Status = AllocateTapiCallInfo(pVc, NULL);
  570. if (Status != NDIS_STATUS_SUCCESS) {
  571. return (Status);
  572. }
  573. pCallMgrParams = (PCO_CALL_MANAGER_PARAMETERS)
  574. ((PUCHAR)pCallParams +
  575. sizeof(CO_CALL_PARAMETERS));
  576. pWanCallMgrParams = (PWAN_CO_CALLMGR_PARAMETERS)
  577. pCallMgrParams->CallMgrSpecific.Parameters;
  578. TapiProvider = pVc->ClAf->TapiProvider;
  579. pVc->ulCallInfoFieldsChanged = 0;
  580. //
  581. // Need to find a line and an address for this puppy
  582. //
  583. if (!GetAvailLineFromProvider(TapiProvider, &TapiLine, &TapiAddr)) {
  584. return (NDIS_STATUS_RESOURCES);
  585. }
  586. pVc->TapiLine = TapiLine;
  587. pVc->TapiAddr = TapiAddr;
  588. InterlockedIncrement((PLONG)&TapiAddr->CallCount);
  589. InterlockedIncrement((PLONG)&TapiLine->DevStatus->ulNumActiveCalls);
  590. CallInfo = pVc->CallInfo;
  591. CallInfo->ulLineDeviceID = TapiLine->CmLineID;
  592. CallInfo->ulAddressID = TapiAddr->AddrId;
  593. CallInfo->ulOrigin = LINECALLORIGIN_INBOUND;
  594. //
  595. // Set up structure size
  596. //
  597. CallInfo->ulNeededSize =
  598. CallInfo->ulUsedSize =
  599. sizeof(LINE_CALL_INFO);// + LINE_CALL_INFO_VAR_DATA_SIZE;
  600. CallInfo->ulBearerMode =
  601. (LINEBEARERMODE_VOICE | LINEBEARERMODE_SPEECH |
  602. LINEBEARERMODE_ALTSPEECHDATA | LINEBEARERMODE_MULTIUSE);
  603. CallInfo->ulRate =
  604. MIN(pCallMgrParams->Receive.PeakBandwidth, pCallMgrParams->Transmit.PeakBandwidth);
  605. CallInfo->ulRate = CallInfo->ulRate * 8;
  606. pVc->ulCallInfoFieldsChanged |= LINECALLINFOSTATE_RATE;
  607. PXDEBUGP(PXD_LOUD, PXM_UTILS, ("GenericGetTapiCallParams: CallInfo->ulRate %x\n", CallInfo->ulRate));
  608. CallInfo->ulMediaMode = pWanCallMgrParams->MediaMode |
  609. LINEMEDIAMODE_DIGITALDATA;
  610. CallInfo->ulAppSpecific = 0;
  611. CallInfo->ulCallID = 0;
  612. CallInfo->ulRelatedCallID = 0;
  613. CallInfo->ulCallParamFlags = 0;
  614. CallInfo->ulCallStates = LINECALLSTATE_IDLE |
  615. LINECALLSTATE_OFFERING |
  616. LINECALLSTATE_BUSY |
  617. LINECALLSTATE_CONNECTED |
  618. LINECALLSTATE_DISCONNECTED |
  619. LINECALLSTATE_SPECIALINFO |
  620. LINECALLSTATE_UNKNOWN;
  621. CallInfo->DialParams.ulDialPause = 0;
  622. CallInfo->DialParams.ulDialSpeed = 0;
  623. CallInfo->DialParams.ulDigitDuration = 0;
  624. CallInfo->DialParams.ulWaitForDialtone = 0;
  625. CallInfo->ulReason = LINECALLREASON_UNAVAIL;
  626. CallInfo->ulCompletionID = 0;
  627. CallInfo->ulCountryCode = 0;
  628. CallInfo->ulTrunk = (ULONG)-1;
  629. if (pWanCallMgrParams->OriginatingAddr.AddressLength != 0) {
  630. if ((VarDataUsed + pWanCallMgrParams->OriginatingAddr.AddressLength)
  631. <= LINE_CALL_INFO_VAR_DATA_SIZE) {
  632. CallInfo->ulCallerIDFlags = LINECALLPARTYID_ADDRESS;
  633. CallInfo->ulCallerIDSize = pWanCallMgrParams->OriginatingAddr.AddressLength;
  634. //
  635. // var data comes in the LINE_CALL_INFO_VAR_DATA_SIZE
  636. // space at the end of this structure.
  637. //
  638. CallInfo->ulCallerIDOffset = sizeof (LINE_CALL_INFO);
  639. NdisMoveMemory ( (USHORT *)(CallInfo)+CallInfo->ulCallerIDOffset,
  640. &pWanCallMgrParams->OriginatingAddr.Address,
  641. pWanCallMgrParams->OriginatingAddr.AddressLength);
  642. VarDataUsed += pWanCallMgrParams->OriginatingAddr.AddressLength;
  643. pVc->ulCallInfoFieldsChanged |= LINECALLINFOSTATE_ORIGIN;
  644. }
  645. } else {
  646. CallInfo->ulCallerIDFlags = LINECALLPARTYID_UNAVAIL;
  647. CallInfo->ulCallerIDSize = 0;
  648. CallInfo->ulCallerIDOffset = 0;
  649. }
  650. CallInfo->ulCallerIDNameSize = 0;
  651. CallInfo->ulCallerIDNameOffset = 0;
  652. if (pWanCallMgrParams->CalledAddr.AddressLength != 0) {
  653. if ((VarDataUsed + pWanCallMgrParams->CalledAddr.AddressLength)
  654. <= sizeof (LINE_CALL_INFO_VAR_DATA_SIZE)) {
  655. CallInfo->ulCalledIDFlags = LINECALLPARTYID_ADDRESS;
  656. CallInfo->ulCalledIDSize = pWanCallMgrParams->CalledAddr.AddressLength;
  657. //
  658. // var data comes in the LINE_CALL_INFO_VAR_DATA_SIZE
  659. // space at the end of this structure.
  660. //
  661. CallInfo->ulCalledIDOffset = sizeof (LINE_CALL_INFO) + VarDataUsed;
  662. NdisMoveMemory ( (USHORT *)(CallInfo)+CallInfo->ulCalledIDOffset,
  663. &pWanCallMgrParams->CalledAddr.Address,
  664. pWanCallMgrParams->CalledAddr.AddressLength);
  665. VarDataUsed += pWanCallMgrParams->CalledAddr.AddressLength;
  666. pVc->ulCallInfoFieldsChanged |= LINECALLINFOSTATE_CALLEDID;
  667. }
  668. } else {
  669. CallInfo->ulCalledIDFlags = LINECALLPARTYID_UNAVAIL;
  670. CallInfo->ulCalledIDSize = 0;
  671. CallInfo->ulCalledIDOffset = 0;
  672. }
  673. CallInfo->ulCalledIDNameSize = 0;
  674. CallInfo->ulCalledIDNameOffset = 0;
  675. CallInfo->ulConnectedIDFlags = LINECALLPARTYID_UNAVAIL;
  676. CallInfo->ulConnectedIDSize = 0;
  677. CallInfo->ulConnectedIDOffset = 0;
  678. CallInfo->ulConnectedIDNameSize = 0;
  679. CallInfo->ulConnectedIDNameOffset = 0;
  680. CallInfo->ulRedirectionIDFlags = LINECALLPARTYID_UNAVAIL;
  681. CallInfo->ulRedirectionIDSize = 0;
  682. CallInfo->ulRedirectionIDOffset = 0;
  683. CallInfo->ulRedirectionIDNameSize = 0;
  684. CallInfo->ulRedirectionIDNameOffset = 0;
  685. CallInfo->ulRedirectingIDFlags = LINECALLPARTYID_UNAVAIL;
  686. CallInfo->ulRedirectingIDSize = 0;
  687. CallInfo->ulRedirectingIDOffset = 0;
  688. CallInfo->ulRedirectingIDNameSize = 0;
  689. CallInfo->ulRedirectingIDNameOffset = 0;
  690. CallInfo->ulDisplaySize = 0;
  691. CallInfo->ulDisplayOffset = 0;
  692. CallInfo->ulUserUserInfoSize = 0;
  693. CallInfo->ulUserUserInfoOffset = 0;
  694. CallInfo->ulHighLevelCompSize = 0;
  695. CallInfo->ulHighLevelCompOffset = 0;
  696. CallInfo->ulLowLevelCompSize = 0;
  697. CallInfo->ulLowLevelCompOffset = 0;
  698. CallInfo->ulChargingInfoSize = 0;
  699. CallInfo->ulChargingInfoOffset = 0;
  700. CallInfo->ulTerminalModesSize = 0;
  701. CallInfo->ulTerminalModesOffset = 0;
  702. CallInfo->ulDevSpecificSize = 0;
  703. CallInfo->ulDevSpecificOffset = 0;
  704. CallInfo->ulUsedSize += VarDataUsed;
  705. CallInfo->ulNeededSize = CallInfo->ulUsedSize;
  706. return (NDIS_STATUS_SUCCESS);
  707. }
  708. PPX_CL_SAP
  709. GenericTranslateTapiSap(
  710. IN PPX_CL_AF pClAf,
  711. IN PPX_TAPI_LINE TapiLine
  712. )
  713. {
  714. PCO_SAP pCoSap;
  715. PPX_CL_SAP pClSap;
  716. PWAN_CO_SAP pWanSap;
  717. ULONG SapLength;
  718. ULONG MediaModes;
  719. ULONG SizeNeeded;
  720. do {
  721. SapLength = sizeof(CO_SAP) + sizeof(WAN_CO_SAP);
  722. SizeNeeded = sizeof(PX_CL_SAP) + SapLength + sizeof(PVOID);
  723. PxAllocMem(pClSap, SizeNeeded, PX_CLSAP_TAG);
  724. if (pClSap == NULL) {
  725. return(NULL);
  726. }
  727. NdisZeroMemory(pClSap, SizeNeeded);
  728. pCoSap = (PCO_SAP)
  729. ((PUCHAR)pClSap + sizeof(PX_CL_SAP) + sizeof(PVOID));
  730. (ULONG_PTR)pCoSap &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  731. MediaModes = TapiLine->DevStatus->ulOpenMediaModes;
  732. pCoSap->SapType = 0;
  733. pCoSap->SapLength = sizeof(WAN_CO_SAP);
  734. pWanSap = (PWAN_CO_SAP)&pCoSap->Sap[0];
  735. pWanSap->BearerCaps = SAP_FIELD_ANY;
  736. pWanSap->MediaModes = SAP_FIELD_ANY;
  737. pWanSap->CalledAddr.AddressLength = 0;
  738. pWanSap->HigherLayerComp.HighLayerInfoLength = 0;
  739. pWanSap->LowerLayerComp.InfoTransferCap = SAP_FIELD_ANY;
  740. pWanSap->LowerLayerComp.InfoTransferMode = SAP_FIELD_ANY;
  741. pWanSap->LowerLayerComp.InfoTransferSymmetry = SAP_FIELD_ANY;
  742. pClSap->CoSap = pCoSap;
  743. InterlockedExchange((PLONG)&pClSap->State, PX_SAP_OPENING);
  744. pClSap->ClAf = pClAf;
  745. pClSap->MediaModes = MediaModes;
  746. TapiLine->ClSap = pClSap;
  747. pClSap->TapiLine = TapiLine;
  748. } while (FALSE);
  749. return (pClSap);
  750. }
  751. #endif
  752. NDIS_STATUS
  753. PxAfXyzTranslateTapiCallParams(
  754. IN PPX_VC pVc,
  755. IN ULONG ulLineID,
  756. IN ULONG ulAddressID,
  757. IN ULONG ulFlags,
  758. IN PNDIS_TAPI_MAKE_CALL pTapiParams,
  759. OUT PCO_CALL_PARAMETERS * ppNdisCallParams
  760. )
  761. /*++
  762. Routine Description:
  763. Translate from TAPI-format to NDIS-format call parameters for an
  764. outgoing call. We request the Call Manager to do it.
  765. There is a lot of brute force copying in this routine. The goal is
  766. to get all parameters into one flat buffer to fit into an NDIS Request.
  767. Arguments:
  768. pVc - the proxy VC to which the MakeCall will be directed
  769. pTapiParams - Points to TAPI call parameters
  770. ppNdisCallParams - where we return a pointer to NDIS call parameters.
  771. Return Value:
  772. NDIS_STATUS_SUCCESS if successful, NDIS_STATUS_XXX error otherwise.
  773. --*/
  774. {
  775. NDIS_STATUS Status;
  776. CO_TAPI_TRANSLATE_TAPI_CALLPARAMS * pTranslateReq = NULL;
  777. LINE_CALL_PARAMS * pInLineCallParams;
  778. LINE_CALL_PARAMS * pDstLineCallParams;
  779. PCO_CALL_PARAMETERS pNdisCallParams;
  780. ULONG RetryCount;
  781. ULONG RequestSize;
  782. ULONG InputParamSize;
  783. ULONG DestAddrBytes;
  784. ULONG i, BytesFilled;
  785. PUCHAR pBuffer;
  786. PX_REQUEST ProxyRequest;
  787. PPX_REQUEST pProxyRequest = &ProxyRequest;
  788. PNDIS_REQUEST pNdisRequest;
  789. //
  790. // Initialize.
  791. //
  792. Status = NDIS_STATUS_SUCCESS;
  793. pNdisCallParams = NULL;
  794. *ppNdisCallParams = NULL;
  795. DestAddrBytes = sizeof(WCHAR)*(pTapiParams->ulDestAddressSize);
  796. do {
  797. pInLineCallParams = (LINE_CALL_PARAMS*)&pTapiParams->LineCallParams;
  798. //
  799. // Calculate space needed for the input parameters
  800. //
  801. InputParamSize =
  802. sizeof(CO_TAPI_TRANSLATE_TAPI_CALLPARAMS) +
  803. DestAddrBytes + sizeof(LINE_CALL_PARAMS) +
  804. sizeof(CO_CALL_PARAMETERS) + 1024 +
  805. 3*sizeof(PVOID);
  806. //
  807. // Add space for all var length fields in LINE_CALL_PARAMS.
  808. //
  809. for (i = 0; i < PX_TCP_NUM_ENTRIES; i++) {
  810. InputParamSize +=
  811. *(ULONG *)((PUCHAR)pInLineCallParams + PxTapiCallParamList[i].SizePointer);
  812. InputParamSize += sizeof(PVOID);
  813. }
  814. //
  815. // We'll try this atmost twice: the second time would be
  816. // if the Call Manager wants us to try again with more
  817. // buffer space.
  818. //
  819. for (RetryCount = 0; RetryCount < 2; RetryCount++) {
  820. //
  821. // Calculate total space required for the NDIS request.
  822. //
  823. RequestSize = InputParamSize + pVc->ClAf->NdisCallParamSize;
  824. //
  825. // Allocate it.
  826. //
  827. PxAllocMem(pBuffer, RequestSize, PX_TRANSLATE_CALL);
  828. if (pBuffer == NULL) {
  829. Status = NDIS_STATUS_RESOURCES;
  830. break;
  831. }
  832. NdisZeroMemory(pProxyRequest, sizeof(PX_REQUEST));
  833. //
  834. // Lay out and fill up the request.
  835. //
  836. pNdisRequest = &pProxyRequest->NdisRequest;
  837. pNdisRequest->RequestType = NdisRequestQueryInformation;
  838. pNdisRequest->DATA.QUERY_INFORMATION.Oid =
  839. OID_CO_TAPI_TRANSLATE_TAPI_CALLPARAMS;
  840. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =
  841. pBuffer;
  842. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength =
  843. RequestSize;
  844. //
  845. // InformationBuffer points to this:
  846. //
  847. pTranslateReq = (CO_TAPI_TRANSLATE_TAPI_CALLPARAMS *)pBuffer;
  848. pTranslateReq->ulLineID = ulLineID;
  849. pTranslateReq->ulAddressID = ulAddressID;
  850. pTranslateReq->ulFlags = CO_TAPI_FLAG_OUTGOING_CALL;
  851. pBuffer =
  852. (UCHAR*)((ULONG_PTR)(pTranslateReq + 1) + sizeof(PVOID));
  853. (ULONG_PTR)pBuffer &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  854. pTranslateReq->DestAddress.Offset =
  855. ((ULONG_PTR)pBuffer -
  856. (ULONG_PTR)&pTranslateReq->DestAddress);
  857. //
  858. // Fill in the Destination Address.
  859. //
  860. pTranslateReq->DestAddress.MaximumLength = // same as Length below
  861. pTranslateReq->DestAddress.Length = (USHORT)DestAddrBytes;
  862. NdisMoveMemory(pBuffer,
  863. (PUCHAR)((ULONG_PTR)pTapiParams + pTapiParams->ulDestAddressOffset),
  864. DestAddrBytes);
  865. pBuffer += (DestAddrBytes + sizeof(PVOID));
  866. (ULONG_PTR)pBuffer &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  867. pTranslateReq->LineCallParams.Offset =
  868. (USHORT)((ULONG_PTR)pBuffer - (ULONG_PTR)&pTranslateReq->LineCallParams);
  869. pDstLineCallParams = (LINE_CALL_PARAMS *)pBuffer;
  870. //
  871. // Copy in input parameters.
  872. //
  873. BytesFilled = PxCopyLineCallParams(pInLineCallParams,
  874. pDstLineCallParams);
  875. pDstLineCallParams->ulAddressMode = LINEADDRESSMODE_ADDRESSID;
  876. pDstLineCallParams->ulAddressID = ulAddressID;
  877. pTranslateReq->LineCallParams.MaximumLength = // same as Length below
  878. pTranslateReq->LineCallParams.Length = (USHORT)BytesFilled;
  879. pBuffer += (BytesFilled + sizeof(PVOID));
  880. (ULONG_PTR)pBuffer &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  881. //
  882. // Assign space for NDIS Call Parameters == remaining space.
  883. //
  884. pTranslateReq->NdisCallParams.MaximumLength = // same as Length below
  885. pTranslateReq->NdisCallParams.Length =
  886. (USHORT)(RequestSize - BytesFilled);
  887. pTranslateReq->NdisCallParams.Offset =
  888. (USHORT)((ULONG_PTR)pBuffer - (ULONG_PTR)&pTranslateReq->NdisCallParams);
  889. pNdisCallParams = (CO_CALL_PARAMETERS *)pBuffer;
  890. //
  891. // Do the request.
  892. //
  893. PxInitBlockStruc(&pProxyRequest->Block);
  894. Status = NdisCoRequest(pVc->Adapter->ClBindingHandle,
  895. pVc->ClAf->NdisAfHandle,
  896. pVc->ClVcHandle,
  897. NULL, // PartyHandle
  898. pNdisRequest);
  899. //
  900. // Wait for it to complete if it pends.
  901. //
  902. if (Status == NDIS_STATUS_PENDING) {
  903. Status = PxBlock(&pProxyRequest->Block);
  904. }
  905. //
  906. // Did the translation succeed?
  907. //
  908. if (Status == NDIS_STATUS_SUCCESS) {
  909. break;
  910. }
  911. //
  912. // If the Call Manager needed more buffer, try again.
  913. // Remember how much the Call Manager wanted so that we get
  914. // smart the next time around.
  915. //
  916. if ((Status == NDIS_STATUS_INVALID_LENGTH) ||
  917. (Status == NDIS_STATUS_BUFFER_TOO_SHORT)) {
  918. //
  919. // Should happen only if the supplied space for NDIS Call parameters
  920. // is not sufficient. And we expect the CM to return the length
  921. // it expects in "pTranslateReq->NdisCallParams.MaximumLength".
  922. //
  923. //
  924. // Remember this new length for future translates.
  925. //
  926. pVc->ClAf->NdisCallParamSize =
  927. pTranslateReq->NdisCallParams.Length;
  928. PxFreeMem(pTranslateReq);
  929. pTranslateReq = NULL;
  930. } else {
  931. //
  932. // Major problem (e.g. the AF is closing).
  933. //
  934. break;
  935. }
  936. }
  937. //
  938. // Check if translation was successful.
  939. //
  940. if (Status != NDIS_STATUS_SUCCESS) {
  941. break;
  942. }
  943. //
  944. // Copy the NDIS Call Parameters into a separate block.
  945. //
  946. PxAssert(pNdisCallParams != NULL);
  947. *ppNdisCallParams =
  948. PxCopyCallParameters(pNdisCallParams);
  949. if (*ppNdisCallParams == NULL) {
  950. Status = NDIS_STATUS_RESOURCES;
  951. break;
  952. }
  953. }
  954. while (FALSE);
  955. if (pTranslateReq != NULL) {
  956. PxFreeMem(pTranslateReq);
  957. }
  958. return (Status);
  959. }
  960. NDIS_STATUS
  961. PxAfXyzTranslateNdisCallParams(
  962. IN PPX_VC pVc,
  963. IN PCO_CALL_PARAMETERS pNdisCallParams
  964. )
  965. /*++
  966. Routine Description:
  967. Translate from NDIS-format to TAPI-format call parameters for an
  968. incoming call. We request the Call Manager to do it.
  969. Arguments:
  970. pVc - the proxy VC on which the incoming call arrived.
  971. pNdisCallParams - points to NDIS call parameters for the call
  972. Return Value:
  973. NDIS_STATUS_SUCCESS if successful, NDIS_STATUS_XXX error otherwise.
  974. --*/
  975. {
  976. ULONG NdisParamLength;
  977. ULONG RetryCount;
  978. ULONG RequestSize;
  979. PUCHAR pBuffer;
  980. ULONG CallMgrParamsLength = 0;
  981. ULONG MediaParamsLength = 0;
  982. NDIS_STATUS Status;
  983. PNDIS_REQUEST pNdisRequest;
  984. PPX_TAPI_PROVIDER TapiProvider;
  985. PPX_TAPI_LINE TapiLine;
  986. PPX_TAPI_ADDR TapiAddr;
  987. LINE_CALL_INFO * pLineCallInfo;
  988. PCO_CALL_PARAMETERS pReqNdisCallParams;
  989. CO_TAPI_TRANSLATE_NDIS_CALLPARAMS * pTranslateReq = NULL;
  990. PX_REQUEST ProxyRequest;
  991. PPX_REQUEST pProxyRequest = &ProxyRequest;
  992. //
  993. // Initialize.
  994. //
  995. TapiProvider = pVc->ClAf->TapiProvider;
  996. Status = NDIS_STATUS_SUCCESS;
  997. do
  998. {
  999. pVc->pCallParameters =
  1000. PxCopyCallParameters(pNdisCallParams);
  1001. if (pVc->pCallParameters == NULL) {
  1002. PXDEBUGP(PXD_WARNING, PXM_CL,
  1003. ("PxAfXyzTranslateNdisCallParams: failed to allocate memory for callparams\n"));
  1004. Status = NDIS_STATUS_RESOURCES;
  1005. break;
  1006. }
  1007. //
  1008. // Calculate total length needed for NDIS parameters.
  1009. //
  1010. NdisParamLength = sizeof(CO_CALL_PARAMETERS);
  1011. if (pNdisCallParams->CallMgrParameters) {
  1012. CallMgrParamsLength = (sizeof(CO_CALL_MANAGER_PARAMETERS) +
  1013. ROUND_UP(pNdisCallParams->CallMgrParameters->CallMgrSpecific.Length));
  1014. NdisParamLength += CallMgrParamsLength;
  1015. }
  1016. if (pNdisCallParams->MediaParameters) {
  1017. MediaParamsLength = (sizeof(CO_MEDIA_PARAMETERS) +
  1018. ROUND_UP(pNdisCallParams->MediaParameters->MediaSpecific.Length));
  1019. NdisParamLength += MediaParamsLength;
  1020. }
  1021. //
  1022. // Calculate total space needed for the input parameters
  1023. //
  1024. RequestSize =
  1025. sizeof(CO_TAPI_TRANSLATE_NDIS_CALLPARAMS) + NdisParamLength +
  1026. sizeof(LINE_CALL_INFO) + LINE_CALL_INFO_VAR_DATA_SIZE;
  1027. //
  1028. // We'll try this atmost twice: the second time would be
  1029. // if the Call Manager wants us to try again with more
  1030. // buffer space.
  1031. //
  1032. for (RetryCount = 0; RetryCount < 2; RetryCount++) {
  1033. //
  1034. // Allocate it.
  1035. //
  1036. PxAllocMem(pBuffer, RequestSize, PX_TRANSLATE_CALL);
  1037. if (pBuffer == NULL) {
  1038. Status = NDIS_STATUS_RESOURCES;
  1039. break;
  1040. }
  1041. NdisZeroMemory(pProxyRequest, sizeof(PX_REQUEST));
  1042. //
  1043. // Lay out and fill up the request.
  1044. //
  1045. pNdisRequest = &pProxyRequest->NdisRequest;
  1046. pNdisRequest->RequestType = NdisRequestQueryInformation;
  1047. pNdisRequest->DATA.QUERY_INFORMATION.Oid = OID_CO_TAPI_TRANSLATE_NDIS_CALLPARAMS;
  1048. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  1049. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = RequestSize;
  1050. //
  1051. // InformationBuffer points to this:
  1052. //
  1053. pTranslateReq = (CO_TAPI_TRANSLATE_NDIS_CALLPARAMS *)pBuffer;
  1054. pTranslateReq->ulFlags = CO_TAPI_FLAG_INCOMING_CALL;
  1055. pBuffer += sizeof(CO_TAPI_TRANSLATE_NDIS_CALLPARAMS);
  1056. pTranslateReq->NdisCallParams.Offset =
  1057. (USHORT)((ULONG_PTR)pBuffer -
  1058. (ULONG_PTR)&pTranslateReq->NdisCallParams);
  1059. pTranslateReq->NdisCallParams.MaximumLength =
  1060. pTranslateReq->NdisCallParams.Length = (USHORT)NdisParamLength;
  1061. //
  1062. // Copy in the NDIS call parameters.
  1063. //
  1064. pReqNdisCallParams = (PCO_CALL_PARAMETERS)pBuffer;
  1065. NdisZeroMemory(pReqNdisCallParams, NdisParamLength);
  1066. pReqNdisCallParams->Flags = pNdisCallParams->Flags;
  1067. pBuffer = (PUCHAR)((ULONG_PTR)pReqNdisCallParams + sizeof(CO_CALL_PARAMETERS));
  1068. if (pNdisCallParams->CallMgrParameters) {
  1069. pReqNdisCallParams->CallMgrParameters = (PCO_CALL_MANAGER_PARAMETERS)pBuffer;
  1070. NdisMoveMemory(pReqNdisCallParams->CallMgrParameters,
  1071. pNdisCallParams->CallMgrParameters,
  1072. sizeof(*pNdisCallParams->CallMgrParameters));
  1073. NdisMoveMemory(&pReqNdisCallParams->CallMgrParameters->CallMgrSpecific.Parameters[0],
  1074. &pNdisCallParams->CallMgrParameters->CallMgrSpecific.Parameters[0],
  1075. pNdisCallParams->CallMgrParameters->CallMgrSpecific.Length);
  1076. pBuffer += CallMgrParamsLength;
  1077. }
  1078. if (pNdisCallParams->MediaParameters) {
  1079. pReqNdisCallParams->MediaParameters = (PCO_MEDIA_PARAMETERS)pBuffer;
  1080. NdisMoveMemory(pReqNdisCallParams->MediaParameters,
  1081. pNdisCallParams->MediaParameters,
  1082. sizeof(*pNdisCallParams->MediaParameters));
  1083. NdisMoveMemory(&pReqNdisCallParams->MediaParameters->MediaSpecific.Parameters[0],
  1084. &pNdisCallParams->MediaParameters->MediaSpecific.Parameters[0],
  1085. pNdisCallParams->MediaParameters->MediaSpecific.Length);
  1086. pBuffer += MediaParamsLength;
  1087. }
  1088. //
  1089. // Space for LINE_CALL_INFO == all that is left.
  1090. //
  1091. pLineCallInfo = (LINE_CALL_INFO *)pBuffer;
  1092. pTranslateReq->LineCallInfo.Offset =
  1093. (USHORT)((ULONG_PTR)pBuffer -
  1094. (ULONG_PTR)&pTranslateReq->LineCallInfo);
  1095. pTranslateReq->LineCallInfo.MaximumLength =
  1096. pTranslateReq->LineCallInfo.Length = (USHORT)(RequestSize -
  1097. pTranslateReq->LineCallInfo.Offset);
  1098. PxInitBlockStruc(&pProxyRequest->Block);
  1099. //
  1100. // Do the request.
  1101. //
  1102. Status = NdisCoRequest(pVc->Adapter->ClBindingHandle,
  1103. pVc->ClAf->NdisAfHandle,
  1104. pVc->ClVcHandle,
  1105. NULL, // PartyHandle
  1106. pNdisRequest);
  1107. //
  1108. // This call will always return pending (ndis behavior) even
  1109. // though the underlying call manager can never pend it
  1110. // so make pending look like success.
  1111. //
  1112. if (Status == NDIS_STATUS_PENDING) {
  1113. Status = NDIS_STATUS_SUCCESS;
  1114. }
  1115. //
  1116. // Did the translation succeed?
  1117. //
  1118. if (Status == NDIS_STATUS_SUCCESS) {
  1119. break;
  1120. }
  1121. //
  1122. // If the Call Manager needed more buffer, try again.
  1123. //
  1124. if ((Status == NDIS_STATUS_INVALID_LENGTH) ||
  1125. (Status == NDIS_STATUS_BUFFER_TOO_SHORT)) {
  1126. //
  1127. // Should happen only if the supplied space for LINE_CALL_INFO
  1128. // is not sufficient. Get the desired length.
  1129. //
  1130. RequestSize =
  1131. pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;
  1132. PxFreeMem(pTranslateReq);
  1133. }
  1134. }
  1135. if (Status != NDIS_STATUS_SUCCESS) {
  1136. break;
  1137. }
  1138. //
  1139. // Now that we have the Id's that this call came in on...
  1140. // validate and setup tapiline/tapiaddr
  1141. //
  1142. //
  1143. // Validate the lineid and get the line control block
  1144. //
  1145. if (!GetLineFromCmLineID(TapiProvider,
  1146. pLineCallInfo->ulLineDeviceID,
  1147. &TapiLine)) {
  1148. PXDEBUGP (PXD_WARNING, PXM_UTILS,
  1149. ("PxAfXyzTranslateNdisCallParams: Invalid LineID %d on Provider %p\n",
  1150. pLineCallInfo->ulLineDeviceID, TapiProvider));
  1151. Status = NDIS_STATUS_RESOURCES;
  1152. break;
  1153. }
  1154. NdisAcquireSpinLock(&TapiLine->Lock);
  1155. //
  1156. // Validate the addressid and get the address control block
  1157. //
  1158. if (!IsAddressValid(TapiLine,
  1159. pLineCallInfo->ulAddressID,
  1160. &TapiAddr)) {
  1161. PXDEBUGP (PXD_WARNING, PXM_UTILS,
  1162. ("PxAfXyzTranslateNdisCallParams: Invalid AddrID %d on TapiLine %p\n",
  1163. pLineCallInfo->ulAddressID, TapiLine));
  1164. Status = NDIS_STATUS_RESOURCES;
  1165. break;
  1166. }
  1167. NdisReleaseSpinLock(&TapiLine->Lock);
  1168. NdisAcquireSpinLock(&pVc->Lock);
  1169. pVc->TapiAddr = TapiAddr;
  1170. pVc->TapiLine = TapiLine;
  1171. InterlockedIncrement((PLONG)&TapiAddr->CallCount);
  1172. InterlockedIncrement((PLONG)&TapiLine->DevStatus->ulNumActiveCalls);
  1173. //
  1174. // Allocate CallInfo and copy in the LINE_CALL_INFO structure.
  1175. //
  1176. Status =
  1177. AllocateTapiCallInfo(pVc, pLineCallInfo);
  1178. if (Status != NDIS_STATUS_SUCCESS) {
  1179. NdisReleaseSpinLock(&pVc->Lock);
  1180. break;
  1181. }
  1182. pVc->CallInfo->ulLineDeviceID = TapiLine->CmLineID;
  1183. pVc->CallInfo->ulAddressID = TapiAddr->AddrId;
  1184. pVc->CallInfo->ulBearerMode = pLineCallInfo->ulBearerMode;
  1185. pVc->CallInfo->ulMediaMode = pLineCallInfo->ulMediaMode;
  1186. pVc->CallInfo->ulOrigin = LINECALLORIGIN_INBOUND;
  1187. NdisReleaseSpinLock(&pVc->Lock);
  1188. }
  1189. while (FALSE);
  1190. if (pTranslateReq != NULL) {
  1191. PxFreeMem(pTranslateReq);
  1192. }
  1193. return (Status);
  1194. }
  1195. PPX_CL_SAP
  1196. PxAfXyzTranslateTapiSap(
  1197. IN PPX_CL_AF pClAf,
  1198. IN PPX_TAPI_LINE TapiLine
  1199. )
  1200. /*++
  1201. Routine Description:
  1202. Translate a SAP from TAPI-style (media modes) to a CO_SAP structure
  1203. suitable for use with a Non-CO_ADDRESS_FAMILY_TAPI Call Manager.
  1204. We actually request the call manager to do the translation. Theoretically
  1205. the CM could return a list of SAPs for this media modes setting.
  1206. For now, we assume the call manager returns one SAP. If this routine
  1207. completes successfully, it would have set the pCoSap pointer within the
  1208. AF Block to point to an appropriate SAP structure.
  1209. TBD: Support multiple returned SAPs.
  1210. Arguments:
  1211. Return Value:
  1212. NDIS_STATUS_SUCCESS if successful, else an appopriate NDIS error code.
  1213. --*/
  1214. {
  1215. ULONG SapLength;
  1216. ULONG RequestLength;
  1217. ULONG RetryCount;
  1218. ULONG MediaModes;
  1219. ULONG SizeNeeded;
  1220. PUCHAR pBuffer;
  1221. PPX_CL_SAP pClSap = NULL;
  1222. PCO_SAP pCoSap = NULL;
  1223. NDIS_STATUS Status;
  1224. PNDIS_REQUEST pNdisRequest;
  1225. CO_TAPI_TRANSLATE_SAP *pTranslateSap = NULL;
  1226. PX_REQUEST ProxyRequest;
  1227. PPX_REQUEST pProxyRequest = &ProxyRequest;
  1228. //
  1229. // Initialize.
  1230. //
  1231. Status = NDIS_STATUS_SUCCESS;
  1232. MediaModes = TapiLine->DevStatus->ulOpenMediaModes;
  1233. do {
  1234. //
  1235. // Compute an initial request length.
  1236. //
  1237. RequestLength =
  1238. sizeof(CO_TAPI_TRANSLATE_SAP) + sizeof(CO_SAP) + 100;
  1239. //
  1240. // Try this atmost twice. The second time is if the Call manager
  1241. // asks us to retry with more buffer space.
  1242. //
  1243. for (RetryCount = 0; RetryCount < 2; RetryCount++) {
  1244. //
  1245. // Allocate it.
  1246. //
  1247. PxAllocMem(pBuffer, RequestLength, PX_TRANSLATE_SAP);
  1248. if (pBuffer == NULL) {
  1249. Status = NDIS_STATUS_RESOURCES;
  1250. break;
  1251. }
  1252. NdisZeroMemory(pBuffer, RequestLength);
  1253. NdisZeroMemory(pProxyRequest, sizeof(PX_REQUEST));
  1254. //
  1255. // InformationBuffer points to this:
  1256. //
  1257. pTranslateSap = (CO_TAPI_TRANSLATE_SAP *)pBuffer;
  1258. pTranslateSap->ulLineID = TapiLine->CmLineID;
  1259. pTranslateSap->ulAddressID = CO_TAPI_ADDRESS_ID_UNSPECIFIED;
  1260. pTranslateSap->ulMediaModes = MediaModes;
  1261. pTranslateSap->Reserved = 0;
  1262. pNdisRequest =
  1263. &pProxyRequest->NdisRequest;
  1264. pNdisRequest->RequestType =
  1265. NdisRequestQueryInformation;
  1266. pNdisRequest->DATA.QUERY_INFORMATION.Oid =
  1267. OID_CO_TAPI_TRANSLATE_TAPI_SAP;
  1268. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =
  1269. pBuffer;
  1270. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength =
  1271. RequestLength;
  1272. //
  1273. // Do the request.
  1274. //
  1275. PxInitBlockStruc(&pProxyRequest->Block);
  1276. Status = NdisCoRequest(pClAf->Adapter->ClBindingHandle,
  1277. pClAf->NdisAfHandle,
  1278. NULL,
  1279. NULL,
  1280. pNdisRequest);
  1281. //
  1282. // Wait for it to complete if it pends.
  1283. //
  1284. if (Status == NDIS_STATUS_PENDING) {
  1285. Status = PxBlock(&pProxyRequest->Block);
  1286. }
  1287. //
  1288. // Did the translation succeed?
  1289. //
  1290. if (Status == NDIS_STATUS_SUCCESS) {
  1291. break;
  1292. }
  1293. //
  1294. // If the Call Manager needed more buffer, try again.
  1295. //
  1296. if ((Status == NDIS_STATUS_INVALID_LENGTH) ||
  1297. (Status == NDIS_STATUS_BUFFER_TOO_SHORT)) {
  1298. //
  1299. // Get the desired length.
  1300. //
  1301. RequestLength =
  1302. pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;
  1303. PxFreeMem(pTranslateSap);
  1304. }
  1305. }
  1306. if (Status != NDIS_STATUS_SUCCESS) {
  1307. break;
  1308. }
  1309. //
  1310. // Got the SAP information successfully. Make a copy and save it
  1311. // in the AF block.
  1312. //
  1313. PxAssert(pTranslateSap->NumberOfSaps == 1); // TBD: allow more
  1314. SapLength = pTranslateSap->NdisSapParams[0].Length;
  1315. SizeNeeded = sizeof(PX_CL_SAP) + SapLength + sizeof(PVOID);
  1316. PxAllocMem(pClSap, SizeNeeded, PX_CLSAP_TAG);
  1317. if (pClSap == NULL) {
  1318. Status = NDIS_STATUS_RESOURCES;
  1319. break;
  1320. }
  1321. NdisZeroMemory(pClSap, SizeNeeded);
  1322. pCoSap = (PCO_SAP)
  1323. ((PUCHAR)pClSap + sizeof(PX_CL_SAP) + sizeof(PVOID));
  1324. (ULONG_PTR)pCoSap &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1325. PXDEBUGP(PXD_INFO, PXM_UTILS, ("TranslateXyzSap: New ClSap %p , Copying in from %p\n",
  1326. pClSap,
  1327. (PUCHAR)((ULONG_PTR)&pTranslateSap->NdisSapParams[0] +
  1328. pTranslateSap->NdisSapParams[0].Offset)));
  1329. NdisMoveMemory(pCoSap,
  1330. (PUCHAR)((ULONG_PTR)&pTranslateSap->NdisSapParams[0] + pTranslateSap->NdisSapParams[0].Offset),
  1331. SapLength);
  1332. pClSap->CoSap = pCoSap;
  1333. InterlockedExchange((PLONG)&pClSap->State, PX_SAP_OPENING);
  1334. pClSap->ClAf = pClAf;
  1335. pClSap->MediaModes = MediaModes;
  1336. TapiLine->ClSap = pClSap;
  1337. pClSap->TapiLine = TapiLine;
  1338. } while (FALSE);
  1339. if (pTranslateSap != NULL) {
  1340. PxFreeMem(pTranslateSap);
  1341. }
  1342. PXDEBUGP(PXD_INFO, PXM_UTILS, ("TranslateXyzSap: pClAf %p, pCoSap %p, Status %x\n",
  1343. pClAf, pCoSap, Status));
  1344. return (pClSap);
  1345. }
  1346. NDIS_STATUS
  1347. PxAfTapiTranslateTapiCallParams(
  1348. IN PPX_VC pVc,
  1349. IN ULONG ulLineID,
  1350. IN ULONG ulAddressID,
  1351. IN ULONG ulFlags,
  1352. IN PNDIS_TAPI_MAKE_CALL pTapiParams,
  1353. OUT PCO_CALL_PARAMETERS * ppNdisCallParams
  1354. )
  1355. /*++
  1356. Routine Description:
  1357. Translate from TAPI-format to NDIS-format call parameters for an
  1358. outgoing call. This is for the CO_ADDRESS_FAMILY_TAPI address family,
  1359. so the translation involves encapsulating the TAPI parameters directly
  1360. into an NDIS CO_CALL_PARAMETERS structure.
  1361. Arguments:
  1362. pVc - the proxy VC to which the MakeCall will be directed
  1363. ulLineID - Line ID on which the call will be placed
  1364. ulAddressID - Address ID on which the call will be placed
  1365. ulFlags - should be CO_TAPI_FLAG_OUTGOING_CALL
  1366. pTapiParams - Points to TAPI call parameters
  1367. ppNdisCallParams - where we return a pointer to NDIS call parameters.
  1368. Return Value:
  1369. NDIS_STATUS_SUCCESS if successful, NDIS_STATUS_XXX error otherwise.
  1370. --*/
  1371. {
  1372. INT i;
  1373. NDIS_STATUS Status;
  1374. ULONG HdrSize, MediaSpecificSize, TotalSize;
  1375. ULONG BytesFilled;
  1376. ULONG DestAddrBytes;
  1377. PCO_CALL_PARAMETERS pNdisCallParams;
  1378. PCO_CALL_MANAGER_PARAMETERS pCallMgrParams;
  1379. PCO_MEDIA_PARAMETERS pMediaParams;
  1380. LINE_CALL_PARAMS *pInLineCallParams;
  1381. LINE_CALL_PARAMS *pOutLineCallParams;
  1382. CO_AF_TAPI_MAKE_CALL_PARAMETERS UNALIGNED *pCoTapiCallParams;
  1383. UCHAR *pDest;
  1384. //
  1385. // Initialize.
  1386. //
  1387. Status = NDIS_STATUS_SUCCESS;
  1388. pNdisCallParams = NULL;
  1389. *ppNdisCallParams = NULL;
  1390. pInLineCallParams = (LINE_CALL_PARAMS *)&pTapiParams->LineCallParams;
  1391. DestAddrBytes = sizeof(WCHAR)*(pTapiParams->ulDestAddressSize);
  1392. do
  1393. {
  1394. //
  1395. // Compute the total space required.
  1396. // The fixed header first:
  1397. //
  1398. HdrSize = sizeof(CO_CALL_PARAMETERS) +
  1399. sizeof(CO_MEDIA_PARAMETERS) +
  1400. sizeof(CO_CALL_MANAGER_PARAMETERS) +
  1401. 2*sizeof(PVOID);
  1402. //
  1403. // Next the structure that will be overlayed on the Media-specific
  1404. // parameters section.
  1405. //
  1406. MediaSpecificSize = sizeof(CO_AF_TAPI_MAKE_CALL_PARAMETERS);
  1407. //
  1408. // Space for Destination address from NDIS_TAPI_MAKE_CALL:
  1409. //
  1410. MediaSpecificSize += DestAddrBytes;
  1411. MediaSpecificSize += sizeof(PVOID);
  1412. //
  1413. // Add space for all the LINE_CALL_PARAMS components.
  1414. //
  1415. MediaSpecificSize += sizeof(LINE_CALL_PARAMS);
  1416. MediaSpecificSize += 2*sizeof(PVOID);
  1417. for (i = 0; i < PX_TCP_NUM_ENTRIES; i++) {
  1418. MediaSpecificSize += *(ULONG *)
  1419. ((PUCHAR)pInLineCallParams + PxTapiCallParamList[i].SizePointer);
  1420. MediaSpecificSize += sizeof(PVOID);
  1421. }
  1422. //
  1423. // Allocate all that we need.
  1424. //
  1425. TotalSize = HdrSize + MediaSpecificSize;
  1426. PxAllocMem(pNdisCallParams, TotalSize, PX_COCALLPARAMS_TAG);
  1427. if (pNdisCallParams == NULL) {
  1428. Status = NDIS_STATUS_RESOURCES;
  1429. break;
  1430. }
  1431. NdisZeroMemory(pNdisCallParams, TotalSize);
  1432. pCallMgrParams = (PCO_CALL_MANAGER_PARAMETERS)
  1433. ((ULONG_PTR)(pNdisCallParams + 1) + sizeof(PVOID));
  1434. (ULONG_PTR)pCallMgrParams &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1435. pMediaParams = (PCO_MEDIA_PARAMETERS)
  1436. ((ULONG_PTR)(pCallMgrParams + 1) + sizeof(PVOID));
  1437. (ULONG_PTR)pMediaParams &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1438. //
  1439. // Lay out the NDIS Call parameters.
  1440. //
  1441. pNdisCallParams->Flags = 0;
  1442. pNdisCallParams->CallMgrParameters = pCallMgrParams;
  1443. pNdisCallParams->MediaParameters = pMediaParams;
  1444. //
  1445. // These fields are in the FLOWSPEC sub-structure
  1446. //
  1447. //
  1448. // Have to convert bits per sec to Bytes per sec
  1449. //
  1450. pCallMgrParams->Transmit.TokenRate =
  1451. pCallMgrParams->Receive.TokenRate =
  1452. pCallMgrParams->Transmit.PeakBandwidth =
  1453. pCallMgrParams->Receive.PeakBandwidth = pInLineCallParams->ulMaxRate/8;
  1454. pCallMgrParams->Transmit.TokenBucketSize = 4096; //UNSPECIFIED_FLOWSPEC_VALUE;
  1455. pCallMgrParams->Receive.TokenBucketSize = 4096; //UNSPECIFIED_FLOWSPEC_VALUE;
  1456. pCallMgrParams->Transmit.MaxSduSize = 4096; //UNSPECIFIED_FLOWSPEC_VALUE;
  1457. pCallMgrParams->Receive.MaxSduSize = 4096; //UNSPECIFIED_FLOWSPEC_VALUE;
  1458. pMediaParams->Flags = TRANSMIT_VC|RECEIVE_VC;
  1459. pMediaParams->ReceivePriority = 0;
  1460. pMediaParams->ReceiveSizeHint = MAX_SDU_SIZE; // ToDo Guess!
  1461. pMediaParams->MediaSpecific.ParamType = 0;
  1462. pMediaParams->MediaSpecific.Length = MediaSpecificSize;
  1463. pCoTapiCallParams = (CO_AF_TAPI_MAKE_CALL_PARAMETERS UNALIGNED *)
  1464. &pMediaParams->MediaSpecific.Parameters[0];
  1465. //
  1466. // Prepare the CO_TAPI Call parameters.
  1467. //
  1468. pCoTapiCallParams->ulLineID = ulLineID;
  1469. pCoTapiCallParams->ulAddressID = ulAddressID;
  1470. pCoTapiCallParams->ulFlags = ulFlags;
  1471. //
  1472. // Destination Address follows the base CO_AF_TAPI_MAKE_CALL_PARAMETERS
  1473. // structure.
  1474. //
  1475. pDest = (UCHAR *)
  1476. ((ULONG_PTR)(pCoTapiCallParams + 1) + sizeof(PVOID));
  1477. (ULONG_PTR)pDest &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1478. pCoTapiCallParams->DestAddress.Length = // Same as MaximumLength below
  1479. pCoTapiCallParams->DestAddress.MaximumLength = (USHORT)DestAddrBytes;
  1480. pCoTapiCallParams->DestAddress.Offset =
  1481. (ULONG_PTR)pDest - (ULONG_PTR)&pCoTapiCallParams->DestAddress;
  1482. NdisMoveMemory(pDest,
  1483. (UCHAR*)((ULONG_PTR)pTapiParams + pTapiParams->ulDestAddressOffset),
  1484. DestAddrBytes);
  1485. pDest = (UCHAR*)
  1486. ((ULONG_PTR)(pDest + DestAddrBytes) + sizeof(PVOID));
  1487. (ULONG_PTR)pDest &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1488. //
  1489. // LINE_CALL_PARAMS next. We'll fill in the lengths at the end.
  1490. // Remember the start of this structure.
  1491. //
  1492. pOutLineCallParams = (LINE_CALL_PARAMS*)pDest;
  1493. pCoTapiCallParams->LineCallParams.Offset =
  1494. (ULONG_PTR)pDest - (ULONG_PTR)&pCoTapiCallParams->LineCallParams;
  1495. BytesFilled = PxCopyLineCallParams(pInLineCallParams,
  1496. pOutLineCallParams);
  1497. pOutLineCallParams->ulAddressMode = LINEADDRESSMODE_ADDRESSID;
  1498. pOutLineCallParams->ulAddressID = ulAddressID;
  1499. pCoTapiCallParams->LineCallParams.Length =
  1500. pCoTapiCallParams->LineCallParams.MaximumLength =
  1501. (USHORT)BytesFilled;
  1502. //
  1503. // Set up the return value.
  1504. //
  1505. *ppNdisCallParams = pNdisCallParams;
  1506. break;
  1507. }
  1508. while (FALSE);
  1509. if (Status != NDIS_STATUS_SUCCESS) {
  1510. //
  1511. // Clean up.
  1512. //
  1513. if (pNdisCallParams != NULL) {
  1514. PxFreeMem(pNdisCallParams);
  1515. }
  1516. }
  1517. PXDEBUGP(PXD_VERY_LOUD, PXM_UTILS, ("AfTapi: Tapi to Ndis: pCallParams: %x, Status %x\n",
  1518. *ppNdisCallParams, Status));
  1519. return (Status);
  1520. }
  1521. ULONG
  1522. PxCopyLineCallParams(
  1523. IN LINE_CALL_PARAMS *pSrcLineCallParams,
  1524. OUT LINE_CALL_PARAMS *pDstLineCallParams
  1525. )
  1526. /*++
  1527. Routine Description:
  1528. Utility routine to make a copy of LINE_CALL_PARAMS.
  1529. Arguments:
  1530. pSrcLineCallParams - Points to the copy source
  1531. pDstLineCallParams - Points to the copy destination. Assumed to
  1532. have sufficient room.
  1533. Return Value:
  1534. Number of bytes we copied in.
  1535. --*/
  1536. {
  1537. PUCHAR pDest;
  1538. PUCHAR pTemp;
  1539. ULONG BytesFilled = 0;
  1540. INT i;
  1541. //
  1542. // First copy the base structure.
  1543. //
  1544. pDest = (PUCHAR)pDstLineCallParams;
  1545. NdisMoveMemory(pDest,
  1546. pSrcLineCallParams,
  1547. sizeof(*pDstLineCallParams));
  1548. pTemp = pDest;
  1549. pDest = (PUCHAR)
  1550. ((ULONG_PTR)pDest + sizeof(*pDstLineCallParams) + sizeof(PVOID));
  1551. (ULONG_PTR)pDest &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1552. BytesFilled += (ULONG)((ULONG_PTR)pDest - (ULONG_PTR)pTemp);
  1553. //
  1554. // Move on to the variable part.
  1555. //
  1556. //
  1557. // Get all the variable-length parts in.
  1558. //
  1559. for (i = 0; i < PX_TCP_NUM_ENTRIES; i++)
  1560. {
  1561. ULONG Length;
  1562. ULONG SrcOffset;
  1563. Length = *(ULONG *)((ULONG_PTR)pSrcLineCallParams +
  1564. PxTapiCallParamList[i].SizePointer);
  1565. if (Length == 0)
  1566. {
  1567. continue;
  1568. }
  1569. //
  1570. // Get the source offset.
  1571. //
  1572. SrcOffset = *(ULONG *)((ULONG_PTR)pSrcLineCallParams +
  1573. PxTapiCallParamList[i].OffsetPointer);
  1574. //
  1575. // Fill in the destination offset.
  1576. //
  1577. *(ULONG *)((PUCHAR)pDstLineCallParams + PxTapiCallParamList[i].OffsetPointer) =
  1578. (ULONG)((ULONG_PTR)pDest - (ULONG_PTR)pDstLineCallParams);
  1579. //
  1580. // Copy this thing in.
  1581. //
  1582. NdisMoveMemory(pDest,
  1583. (PUCHAR)((ULONG_PTR)pSrcLineCallParams + SrcOffset),
  1584. Length);
  1585. pTemp = pDest;
  1586. pDest = (PUCHAR)((ULONG_PTR)pDest + Length + sizeof(PVOID));
  1587. (ULONG_PTR)pDest &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1588. BytesFilled += (ULONG)((ULONG_PTR)pDest - (ULONG_PTR)pTemp);
  1589. }
  1590. return (BytesFilled);
  1591. }
  1592. NDIS_STATUS
  1593. PxAfTapiTranslateNdisCallParams(
  1594. IN PPX_VC pVc,
  1595. IN PCO_CALL_PARAMETERS pNdisCallParams
  1596. )
  1597. /*++
  1598. Routine Description:
  1599. Translate from NDIS-format to TAPI-format call parameters for an
  1600. incoming call belonging to the CO_ADDRESS_FAMILY_TAPI AF. We expect
  1601. the NDIS call parameters to contain TAPI style parameters, and they
  1602. are copied directly into the DRVCALL structure.
  1603. Arguments:
  1604. pVc - the proxy VC on which the incoming call arrived.
  1605. pNdisCallParams - points to NDIS call parameters for the call
  1606. Return Value:
  1607. NDIS_STATUS_SUCCESS if successful, NDIS_STATUS_XXX error otherwise.
  1608. --*/
  1609. {
  1610. NDIS_STATUS Status;
  1611. CO_AF_TAPI_INCOMING_CALL_PARAMETERS UNALIGNED * pCoTapiParams;
  1612. LINE_CALL_INFO UNALIGNED * pReceivedCallInfo;
  1613. PPX_TAPI_PROVIDER TapiProvider;
  1614. PPX_TAPI_LINE TapiLine;
  1615. PPX_TAPI_ADDR TapiAddr;
  1616. //
  1617. // Initialize.
  1618. //
  1619. Status = NDIS_STATUS_SUCCESS;
  1620. TapiProvider = pVc->ClAf->TapiProvider;
  1621. do
  1622. {
  1623. pVc->pCallParameters =
  1624. PxCopyCallParameters(pNdisCallParams);
  1625. if (pVc->pCallParameters == NULL) {
  1626. PXDEBUGP(PXD_WARNING, PXM_CL,
  1627. ("PxAfTapiTranslateNdisCallParams: failed to allocate memory for callparams\n"));
  1628. Status = NDIS_STATUS_RESOURCES;
  1629. break;
  1630. }
  1631. //
  1632. // Some checks here. We might consider removing these and replacing them
  1633. // with asserts.
  1634. //
  1635. if ((pNdisCallParams == NULL) ||
  1636. (pNdisCallParams->MediaParameters == NULL) ||
  1637. (pNdisCallParams->MediaParameters->MediaSpecific.Length <
  1638. sizeof(CO_AF_TAPI_INCOMING_CALL_PARAMETERS)))
  1639. {
  1640. PXDEBUGP(PXD_FATAL, PXM_UTILS, ("AfTapiTranslateNdis: NULL/bad media params in %x\n",
  1641. pNdisCallParams));
  1642. Status = NDIS_STATUS_INVALID_DATA;
  1643. break;
  1644. }
  1645. pCoTapiParams = (CO_AF_TAPI_INCOMING_CALL_PARAMETERS UNALIGNED *)
  1646. &pNdisCallParams->MediaParameters->MediaSpecific.Parameters[0];
  1647. if (pCoTapiParams->LineCallInfo.Length < sizeof(LINE_CALL_INFO))
  1648. {
  1649. PXDEBUGP(PXD_FATAL, PXM_UTILS, ("AfTapiTranslateNdis: bad length (%d) in CoTapiParams %x\n",
  1650. pCoTapiParams->LineCallInfo.Length,
  1651. pCoTapiParams));
  1652. Status = NDIS_STATUS_INVALID_DATA;
  1653. break;
  1654. }
  1655. //
  1656. // Get at the received LINE_CALL_INFO structure.
  1657. //
  1658. pReceivedCallInfo = (LINE_CALL_INFO UNALIGNED *)
  1659. ((ULONG_PTR)&pCoTapiParams->LineCallInfo +
  1660. pCoTapiParams->LineCallInfo.Offset);
  1661. //
  1662. // Now that we have the Id's that this call came in on...
  1663. // validate and setup tapiline/tapiaddr
  1664. //
  1665. //
  1666. // Validate the lineid and get the line control block
  1667. //
  1668. if (!GetLineFromCmLineID(TapiProvider,
  1669. pReceivedCallInfo->ulLineDeviceID,
  1670. &TapiLine)) {
  1671. PXDEBUGP (PXD_WARNING, PXM_UTILS, ("PxAfTapiTranslateNdisCallParams: Invalid LineID %d on Provider %p\n",
  1672. pReceivedCallInfo->ulLineDeviceID, TapiProvider));
  1673. Status = NDIS_STATUS_RESOURCES;
  1674. break;
  1675. }
  1676. NdisAcquireSpinLock(&TapiLine->Lock);
  1677. //
  1678. // Validate the addressid and get the address control block
  1679. //
  1680. if (!IsAddressValid(TapiLine, pReceivedCallInfo->ulAddressID, &TapiAddr)) {
  1681. PXDEBUGP (PXD_WARNING, PXM_UTILS, ("PxAfTapiTranslateNdisCallParams: Invalid AddrID %d on TapiLine %p\n",
  1682. pReceivedCallInfo->ulAddressID, TapiLine));
  1683. Status = NDIS_STATUS_RESOURCES;
  1684. break;
  1685. }
  1686. NdisReleaseSpinLock(&TapiLine->Lock);
  1687. NdisAcquireSpinLock(&pVc->Lock);
  1688. Status =
  1689. AllocateTapiCallInfo(pVc, pReceivedCallInfo);
  1690. if (Status != NDIS_STATUS_SUCCESS) {
  1691. NdisReleaseSpinLock(&pVc->Lock);
  1692. break;
  1693. }
  1694. pVc->TapiLine = TapiLine;
  1695. pVc->TapiAddr = TapiAddr;
  1696. InterlockedIncrement((PLONG)&TapiAddr->CallCount);
  1697. InterlockedIncrement((PLONG)&TapiLine->DevStatus->ulNumActiveCalls);
  1698. pVc->CallInfo->ulLineDeviceID = TapiLine->CmLineID;
  1699. pVc->CallInfo->ulAddressID = TapiAddr->AddrId;
  1700. //pVc->CallInfo->ulBearerMode = TapiLine->DevCaps->ulBearerModes;
  1701. //pVc->CallInfo->ulMediaMode = TapiLine->DevCaps->ulMediaModes;
  1702. pVc->CallInfo->ulOrigin = LINECALLORIGIN_INBOUND;
  1703. NdisReleaseSpinLock(&pVc->Lock);
  1704. //
  1705. // Done.
  1706. //
  1707. break;
  1708. }
  1709. while (FALSE);
  1710. PXDEBUGP(PXD_VERY_LOUD, PXM_UTILS, ("AfTapi: Ndis to Tapi: Status %x\n", Status));
  1711. return (Status);
  1712. }
  1713. PPX_CL_SAP
  1714. PxAfTapiTranslateTapiSap(
  1715. IN PPX_CL_AF pClAf,
  1716. IN PPX_TAPI_LINE TapiLine
  1717. )
  1718. /*++
  1719. Routine Description:
  1720. Translate a SAP from TAPI-style (media modes) to a CO_SAP structure
  1721. suitable for use with a CO_ADDRESS_FAMILY_TAPI Call Manager. We actually
  1722. stick the prepared CO_SAP structure's pointer into the AF Block.
  1723. Arguments:
  1724. Return Value:
  1725. NDIS_STATUS_SUCCESS if successful, else an appopriate NDIS error code.
  1726. --*/
  1727. {
  1728. PCO_SAP pCoSap;
  1729. PPX_CL_SAP pClSap;
  1730. PCO_AF_TAPI_SAP pAfTapiSap;
  1731. ULONG SapLength;
  1732. ULONG MediaModes;
  1733. ULONG SizeNeeded;
  1734. do {
  1735. SapLength = sizeof(CO_SAP) + sizeof(CO_AF_TAPI_SAP);
  1736. SizeNeeded = sizeof(PX_CL_SAP) + sizeof(PVOID) + SapLength;
  1737. PxAllocMem(pClSap, SizeNeeded, PX_CLSAP_TAG);
  1738. if (pClSap == NULL) {
  1739. break;
  1740. }
  1741. NdisZeroMemory(pClSap, SizeNeeded);
  1742. pCoSap = (PCO_SAP)
  1743. ((PUCHAR)pClSap + sizeof(PX_CL_SAP) + sizeof(PVOID));
  1744. (ULONG_PTR)pCoSap &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1745. MediaModes = TapiLine->DevStatus->ulOpenMediaModes;
  1746. pCoSap->SapType = AF_TAPI_SAP_TYPE;
  1747. pCoSap->SapLength = sizeof(CO_AF_TAPI_SAP);
  1748. pAfTapiSap = (PCO_AF_TAPI_SAP)&pCoSap->Sap[0];
  1749. pAfTapiSap->ulLineID = TapiLine->CmLineID;
  1750. pAfTapiSap->ulAddressID = CO_TAPI_ADDRESS_ID_UNSPECIFIED;
  1751. pAfTapiSap->ulMediaModes = MediaModes;
  1752. pClSap->CoSap = pCoSap;
  1753. InterlockedExchange((PLONG)&pClSap->State, PX_SAP_OPENING);
  1754. pClSap->ClAf = pClAf;
  1755. pClSap->MediaModes = MediaModes;
  1756. TapiLine->ClSap = pClSap;
  1757. pClSap->TapiLine = TapiLine;
  1758. } while (FALSE);
  1759. return (pClSap);
  1760. }
  1761. VOID
  1762. PxAfTapiFreeNdisSap(
  1763. IN PPX_CL_AF pClAf,
  1764. IN PCO_SAP pCoSap
  1765. )
  1766. {
  1767. //
  1768. // We need to free the sap
  1769. //
  1770. }
  1771. PCO_CALL_PARAMETERS
  1772. PxCopyCallParameters(
  1773. IN PCO_CALL_PARAMETERS pCallParameters
  1774. )
  1775. {
  1776. ULONG Length;
  1777. ULONG CallMgrParamsLength = 0;
  1778. ULONG MediaParamsLength = 0;
  1779. PCO_CALL_PARAMETERS pProxyCallParams;
  1780. PUCHAR pBuf;
  1781. Length = sizeof(CO_CALL_PARAMETERS);
  1782. if (pCallParameters->CallMgrParameters){
  1783. CallMgrParamsLength = sizeof(CO_CALL_MANAGER_PARAMETERS) +
  1784. ROUND_UP(pCallParameters->CallMgrParameters->CallMgrSpecific.Length);
  1785. Length += CallMgrParamsLength;
  1786. }
  1787. if (pCallParameters->MediaParameters) {
  1788. MediaParamsLength = sizeof(CO_MEDIA_PARAMETERS) +
  1789. ROUND_UP(pCallParameters->MediaParameters->MediaSpecific.Length);
  1790. Length += MediaParamsLength;
  1791. }
  1792. PxAllocMem(pProxyCallParams, Length, PX_COCALLPARAMS_TAG);
  1793. if (pProxyCallParams)
  1794. {
  1795. NdisZeroMemory(pProxyCallParams, Length);
  1796. pProxyCallParams->Flags = pCallParameters->Flags;
  1797. pBuf = (PUCHAR)pProxyCallParams + sizeof(CO_CALL_PARAMETERS);
  1798. if (pCallParameters->CallMgrParameters)
  1799. {
  1800. pProxyCallParams->CallMgrParameters = (PCO_CALL_MANAGER_PARAMETERS)pBuf;
  1801. NdisMoveMemory(pProxyCallParams->CallMgrParameters,
  1802. pCallParameters->CallMgrParameters,
  1803. sizeof(*pCallParameters->CallMgrParameters));
  1804. NdisMoveMemory(&pProxyCallParams->CallMgrParameters->CallMgrSpecific.Parameters[0],
  1805. &pCallParameters->CallMgrParameters->CallMgrSpecific.Parameters[0],
  1806. pCallParameters->CallMgrParameters->CallMgrSpecific.Length);
  1807. pBuf += CallMgrParamsLength;
  1808. }
  1809. if (pCallParameters->MediaParameters)
  1810. {
  1811. pProxyCallParams->MediaParameters = (PCO_MEDIA_PARAMETERS)pBuf;
  1812. NdisMoveMemory(pProxyCallParams->MediaParameters,
  1813. pCallParameters->MediaParameters,
  1814. sizeof(*pCallParameters->MediaParameters));
  1815. NdisMoveMemory(&pProxyCallParams->MediaParameters->MediaSpecific.Parameters[0],
  1816. &pCallParameters->MediaParameters->MediaSpecific.Parameters[0],
  1817. pCallParameters->MediaParameters->MediaSpecific.Length);
  1818. }
  1819. }
  1820. return (pProxyCallParams);
  1821. }
  1822. ULONG
  1823. PxMapNdisStatusToTapiDisconnectMode(
  1824. IN NDIS_STATUS NdisStatus,
  1825. IN BOOLEAN bMakeCallStatus
  1826. )
  1827. /*++
  1828. Routine Description:
  1829. Maps an NDIS Status code passed to MakeCallComplete or IncomingCloseCall
  1830. to its corresponding TAPI LINEDISCONNECTMODE_XXX code.
  1831. Arguments:
  1832. NdisStatus - the NDIS Status to be mapped
  1833. bMakeCallStatus - TRUE iff MakeCallComplete status. FALSE iff
  1834. IncomingCloseCall status.
  1835. Return Value:
  1836. ULONG - the TAPI Disconnect Mode value.
  1837. --*/
  1838. {
  1839. ULONG ulDisconnectMode;
  1840. switch (NdisStatus)
  1841. {
  1842. case NDIS_STATUS_TAPI_DISCONNECTMODE_NORMAL:
  1843. ulDisconnectMode = LINEDISCONNECTMODE_NORMAL;
  1844. break;
  1845. case NDIS_STATUS_TAPI_DISCONNECTMODE_UNKNOWN:
  1846. case NDIS_STATUS_FAILURE:
  1847. ulDisconnectMode = LINEDISCONNECTMODE_UNKNOWN;
  1848. break;
  1849. case NDIS_STATUS_TAPI_DISCONNECTMODE_REJECT:
  1850. case NDIS_STATUS_NOT_ACCEPTED:
  1851. ulDisconnectMode = LINEDISCONNECTMODE_REJECT;
  1852. break;
  1853. case NDIS_STATUS_TAPI_DISCONNECTMODE_PICKUP:
  1854. ulDisconnectMode = LINEDISCONNECTMODE_PICKUP;
  1855. break;
  1856. case NDIS_STATUS_TAPI_DISCONNECTMODE_FORWARDED:
  1857. ulDisconnectMode = LINEDISCONNECTMODE_FORWARDED;
  1858. break;
  1859. case NDIS_STATUS_TAPI_DISCONNECTMODE_BUSY:
  1860. case NDIS_STATUS_SAP_IN_USE:
  1861. ulDisconnectMode = LINEDISCONNECTMODE_BUSY;
  1862. break;
  1863. case NDIS_STATUS_TAPI_DISCONNECTMODE_NOANSWER:
  1864. ulDisconnectMode = LINEDISCONNECTMODE_NOANSWER;
  1865. break;
  1866. case NDIS_STATUS_TAPI_DISCONNECTMODE_BADADDRESS:
  1867. case NDIS_STATUS_INVALID_ADDRESS:
  1868. ulDisconnectMode = LINEDISCONNECTMODE_BADADDRESS;
  1869. break;
  1870. case NDIS_STATUS_TAPI_DISCONNECTMODE_UNREACHABLE:
  1871. case NDIS_STATUS_NO_ROUTE_TO_DESTINATION:
  1872. ulDisconnectMode = LINEDISCONNECTMODE_UNREACHABLE;
  1873. break;
  1874. case NDIS_STATUS_TAPI_DISCONNECTMODE_CONGESTION:
  1875. case NDIS_STATUS_RESOURCES:
  1876. ulDisconnectMode = LINEDISCONNECTMODE_CONGESTION;
  1877. break;
  1878. case NDIS_STATUS_TAPI_DISCONNECTMODE_INCOMPATIBLE:
  1879. ulDisconnectMode = LINEDISCONNECTMODE_INCOMPATIBLE;
  1880. break;
  1881. case NDIS_STATUS_TAPI_DISCONNECTMODE_UNAVAIL:
  1882. case NDIS_STATUS_DEST_OUT_OF_ORDER:
  1883. ulDisconnectMode = LINEDISCONNECTMODE_UNAVAIL;
  1884. break;
  1885. case NDIS_STATUS_SUCCESS:
  1886. PxAssert(!bMakeCallStatus);
  1887. ulDisconnectMode = LINEDISCONNECTMODE_NORMAL;
  1888. break;
  1889. default:
  1890. ulDisconnectMode = LINEDISCONNECTMODE_UNKNOWN;
  1891. break;
  1892. }
  1893. return (ulDisconnectMode);
  1894. }
  1895. NTSTATUS
  1896. IntegerToChar (
  1897. IN ULONG Value,
  1898. IN LONG OutputLength,
  1899. OUT PSZ String
  1900. )
  1901. /*++
  1902. Routine Description:
  1903. Arguments:
  1904. Return Value:
  1905. --*/
  1906. {
  1907. CHAR IntegerChars[] = {'0', '1', '2', '3', '4', '5', '6', '7',
  1908. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  1909. CHAR Result[ 33 ], *s;
  1910. ULONG Shift, Mask, Digit, Length, Base;
  1911. Shift = 0;
  1912. Base = 10;
  1913. s = &Result[ 32 ];
  1914. *s = '\0';
  1915. do {
  1916. Digit = Value % Base;
  1917. Value = Value / Base;
  1918. *--s = IntegerChars[ Digit ];
  1919. } while (Value != 0);
  1920. Length = (ULONG)(&Result[ 32 ] - s);
  1921. if (OutputLength < 0) {
  1922. OutputLength = -OutputLength;
  1923. while ((LONG)Length < OutputLength) {
  1924. *--s = '0';
  1925. Length++;
  1926. }
  1927. }
  1928. if ((LONG)Length > OutputLength) {
  1929. return( STATUS_BUFFER_OVERFLOW );
  1930. } else {
  1931. RtlMoveMemory( String, s, Length );
  1932. if ((LONG)Length < OutputLength) {
  1933. String[ Length ] = '\0';
  1934. }
  1935. return( STATUS_SUCCESS );
  1936. }
  1937. }
  1938. NTSTATUS
  1939. IntegerToWChar (
  1940. IN ULONG Value,
  1941. IN LONG OutputLength,
  1942. OUT PWCHAR String
  1943. )
  1944. /*++
  1945. Routine Description:
  1946. Arguments:
  1947. Return Value:
  1948. --*/
  1949. {
  1950. WCHAR IntegerWChars[] = {L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
  1951. L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F'};
  1952. WCHAR Result[ 33 ], *s;
  1953. ULONG Shift, Mask, Digit, Length, Base;
  1954. Shift = 0;
  1955. Base = 10;
  1956. s = &Result[ 32 ];
  1957. *s = UNICODE_NULL;
  1958. do {
  1959. Digit = Value % Base;
  1960. Value = Value / Base;
  1961. *--s = IntegerWChars[ Digit ];
  1962. } while (Value != 0);
  1963. Length = (ULONG)(&Result[ 32 ] - s);
  1964. if (OutputLength < 0) {
  1965. OutputLength = -OutputLength;
  1966. while ((LONG)Length < OutputLength) {
  1967. *--s = L'0';
  1968. Length++;
  1969. }
  1970. }
  1971. if ((LONG)Length > OutputLength) {
  1972. return( STATUS_BUFFER_OVERFLOW );
  1973. } else {
  1974. RtlMoveMemory( (CHAR *)String, (CHAR *)s, Length * sizeof(WCHAR) );
  1975. if ((LONG)Length < OutputLength) {
  1976. String[ Length ] = UNICODE_NULL;
  1977. }
  1978. return( STATUS_SUCCESS );
  1979. }
  1980. }
  1981. BOOLEAN
  1982. PxAfAndSapFromDevClass(
  1983. PPX_ADAPTER pAdapter,
  1984. LPCWSTR DevClass,
  1985. PPX_CM_AF *pCmAf,
  1986. PPX_CM_SAP *pCmSap
  1987. )
  1988. {
  1989. PPX_CM_AF pAf;
  1990. PPX_CM_SAP pSap;
  1991. BOOLEAN SapFound;
  1992. NdisAcquireSpinLock(&pAdapter->Lock);
  1993. pAf = (PPX_CM_AF)pAdapter->CmAfList.Flink;
  1994. *pCmAf = NULL;
  1995. *pCmSap = NULL;
  1996. SapFound = FALSE;
  1997. while ((PVOID)pAf != (PVOID)&pAdapter->CmAfList) {
  1998. NdisAcquireSpinLock(&pAf->Lock);
  1999. pSap = (PPX_CM_SAP)pAf->CmSapList.Flink;
  2000. while ((PVOID)pSap != (PVOID)&pAf->CmSapList) {
  2001. if (_wcsicmp((CONST LPCWSTR)pSap->CoSap->Sap, DevClass) == 0) {
  2002. SapFound = TRUE;
  2003. *pCmAf = pAf;
  2004. *pCmSap = pSap;
  2005. REF_CM_AF(pAf);
  2006. break;
  2007. }
  2008. pSap = (PPX_CM_SAP)pSap->Linkage.Flink;
  2009. }
  2010. NdisReleaseSpinLock(&pAf->Lock);
  2011. if (SapFound) {
  2012. break;
  2013. }
  2014. pAf = (PPX_CM_AF)pAf->Linkage.Flink;
  2015. }
  2016. NdisReleaseSpinLock(&pAdapter->Lock);
  2017. return (SapFound);
  2018. }
  2019. VOID
  2020. GetAllDevClasses(
  2021. PPX_ADAPTER pAdapter,
  2022. LPCWSTR DevClass,
  2023. PULONG DevClassSize
  2024. )
  2025. {
  2026. PPX_CM_AF pAf;
  2027. PPX_CM_SAP pSap;
  2028. ULONG SizeLeft;
  2029. ULONG Size = 0;
  2030. NdisAcquireSpinLock(&pAdapter->Lock);
  2031. pAf = (PPX_CM_AF)pAdapter->CmAfList.Flink;
  2032. SizeLeft = *DevClassSize;
  2033. while ((PVOID)pAf != (PVOID)&pAdapter->CmAfList) {
  2034. NdisAcquireSpinLock(&pAf->Lock);
  2035. pSap = (PPX_CM_SAP)pAf->CmSapList.Flink;
  2036. while ((PVOID)pSap != (PVOID)&pAf->CmSapList) {
  2037. if (SizeLeft < pSap->CoSap->SapLength) {
  2038. break;
  2039. }
  2040. NdisMoveMemory((PUCHAR)DevClass,
  2041. pSap->CoSap->Sap,
  2042. pSap->CoSap->SapLength);
  2043. //
  2044. // Add the sizeof of the WCHAR for a WCHAR NULL
  2045. // between each class.
  2046. //
  2047. Size += pSap->CoSap->SapLength + sizeof(WCHAR);
  2048. (PUCHAR)DevClass += Size;
  2049. SizeLeft -= Size;
  2050. pSap = (PPX_CM_SAP)pSap->Linkage.Flink;
  2051. }
  2052. NdisReleaseSpinLock(&pAf->Lock);
  2053. pAf = (PPX_CM_AF)pAf->Linkage.Flink;
  2054. }
  2055. NdisReleaseSpinLock(&pAdapter->Lock);
  2056. *DevClassSize = Size;
  2057. }
  2058. VOID
  2059. PxStartIncomingCallTimeout(
  2060. IN PPX_VC pVc
  2061. )
  2062. {
  2063. PXDEBUGP(PXD_LOUD, PXM_UTILS,
  2064. ("PxStartIcomingCallTimeout: VC %p/%x, ClVcH %x, ulCallSt %x, ulCallStMode %x\n",
  2065. pVc, pVc->Flags,pVc->ClVcHandle,pVc->ulCallState,pVc->ulCallStateMode));
  2066. if (!(pVc->Flags & PX_VC_CALLTIMER_STARTED)) {
  2067. //
  2068. // We need to ref the Vc for the timer
  2069. // we are about to start
  2070. //
  2071. REF_VC(pVc);
  2072. pVc->Flags |= PX_VC_CALLTIMER_STARTED;
  2073. NdisSetTimer(&pVc->InCallTimer, 60000);
  2074. }
  2075. }
  2076. VOID
  2077. PxStopIncomingCallTimeout(
  2078. IN PPX_VC pVc
  2079. )
  2080. {
  2081. BOOLEAN bCancelled;
  2082. PXDEBUGP(PXD_LOUD, PXM_UTILS,
  2083. ("PxStopIcomingCallTimeout: VC %p/%x, ClVcH %x, ulCallSt %x, ulCallStMode %x\n",
  2084. pVc, pVc->Flags,pVc->ClVcHandle,pVc->ulCallState,pVc->ulCallStateMode));
  2085. ASSERT(pVc->Flags & PX_VC_CALLTIMER_STARTED);
  2086. NdisCancelTimer(&pVc->InCallTimer, &bCancelled);
  2087. pVc->Flags &= ~PX_VC_CALLTIMER_STARTED;
  2088. if (bCancelled) {
  2089. // We do not need the full deref code because of the ref applied before
  2090. // this routine is called
  2091. pVc->RefCount--;
  2092. }
  2093. }
  2094. VOID
  2095. PxIncomingCallTimeout(
  2096. IN PVOID SystemSpecific1,
  2097. IN PVOID FunctionContext,
  2098. IN PVOID SystemSpecific2,
  2099. IN PVOID SystemSpecific3
  2100. )
  2101. {
  2102. PPX_VC pVc;
  2103. pVc = (PPX_VC)FunctionContext;
  2104. NdisAcquireSpinLock(&pVc->Lock);
  2105. PXDEBUGP(PXD_WARNING, PXM_UTILS,
  2106. ("PxIncomingCallTimeout: VC %p/%x, ClVcH %x, ulCallSt %x, ulCallStMode %x\n",
  2107. pVc, pVc->Flags,pVc->ClVcHandle,pVc->ulCallState,pVc->ulCallStateMode));
  2108. pVc->Flags &= ~PX_VC_CALLTIMER_STARTED;
  2109. pVc->CloseFlags |= PX_VC_INCALL_TIMEOUT;
  2110. PxVcCleanup(pVc, 0);
  2111. DEREF_VC_LOCKED(pVc);
  2112. }
  2113. //
  2114. // Called with the pVc->Lock held
  2115. //
  2116. VOID
  2117. PxCloseCallWithCm(
  2118. PPX_VC pVc
  2119. )
  2120. {
  2121. NDIS_STATUS Status;
  2122. PXDEBUGP(PXD_LOUD, PXM_UTILS,
  2123. ("PxCloseCallWithCm: Vc %p, State: %x, HandoffState: %x Flags %x\n",
  2124. pVc, pVc->State, pVc->HandoffState, pVc->Flags));
  2125. ASSERT(pVc->State == PX_VC_DISCONNECTING);
  2126. pVc->Flags &= ~PX_VC_CLEANUP_CM;
  2127. pVc->CloseFlags |= PX_VC_CM_CLOSE_REQ;
  2128. NdisReleaseSpinLock(&pVc->Lock);
  2129. Status =
  2130. NdisClCloseCall(pVc->ClVcHandle, NULL, NULL, 0);
  2131. if (Status != NDIS_STATUS_PENDING) {
  2132. PxClCloseCallComplete(Status,
  2133. (NDIS_HANDLE)pVc->hdCall,
  2134. NULL);
  2135. }
  2136. NdisAcquireSpinLock(&pVc->Lock);
  2137. }
  2138. //
  2139. // Called with the pVc->Lock held
  2140. //
  2141. NDIS_STATUS
  2142. PxCloseCallWithCl(
  2143. PPX_VC pVc
  2144. )
  2145. {
  2146. NDIS_STATUS Status;
  2147. PXDEBUGP(PXD_LOUD, PXM_UTILS,
  2148. ("PxCloseCallWithCl: Vc %p, State: %x, HandoffState: %x Flags %x\n",
  2149. pVc, pVc->State, pVc->HandoffState, pVc->Flags));
  2150. Status = NDIS_STATUS_PENDING;
  2151. switch (pVc->HandoffState) {
  2152. case PX_VC_HANDOFF_IDLE:
  2153. //
  2154. // We do not have a connection with a client
  2155. // so just return.
  2156. //
  2157. Status = NDIS_STATUS_SUCCESS;
  2158. break;
  2159. case PX_VC_HANDOFF_OFFERING:
  2160. case PX_VC_HANDOFF_DISCONNECTING:
  2161. //
  2162. // We have a connection with a client but it
  2163. // is in a transient state. Cleanup will
  2164. // occur when the transient condition completes.
  2165. //
  2166. break;
  2167. case PX_VC_HANDOFF_CONNECTED:
  2168. //
  2169. // We have an active connection with a client
  2170. // so we need to tear it's part of the vc down now
  2171. //
  2172. pVc->HandoffState = PX_VC_HANDOFF_DISCONNECTING;
  2173. NdisReleaseSpinLock(&pVc->Lock);
  2174. NdisCmDispatchIncomingCloseCall(NDIS_STATUS_SUCCESS,
  2175. pVc->CmVcHandle,
  2176. NULL,
  2177. 0);
  2178. NdisAcquireSpinLock(&pVc->Lock);
  2179. break;
  2180. default:
  2181. break;
  2182. }
  2183. return (Status);
  2184. }
  2185. #ifdef CODELETEVC_FIXED
  2186. //
  2187. // Called with pVc->Lock held
  2188. //
  2189. VOID
  2190. DoDerefVcWork(
  2191. PPX_VC pVc
  2192. )
  2193. {
  2194. NDIS_HANDLE ClVcHandle;
  2195. BOOLEAN VcOwner;
  2196. if (pVc->Flags & PX_VC_IN_TABLE) {
  2197. ClVcHandle = pVc->ClVcHandle;
  2198. pVc->ClVcHandle = NULL;
  2199. VcOwner = (pVc->Flags & PX_VC_OWNER) ? TRUE : FALSE;
  2200. NdisReleaseSpinLock(&pVc->Lock);
  2201. if (VcOwner && ClVcHandle != NULL) {
  2202. NdisCoDeleteVc(ClVcHandle);
  2203. }
  2204. RemoveVcFromTable(pVc);
  2205. } else {
  2206. NdisReleaseSpinLock(&(pVc)->Lock);
  2207. }
  2208. PxFreeVc(pVc);
  2209. }
  2210. #else
  2211. //
  2212. // Called with pVc->Lock held
  2213. //
  2214. VOID
  2215. DoDerefVcWork(
  2216. PPX_VC pVc
  2217. )
  2218. {
  2219. NDIS_HANDLE ClVcHandle, CmVcHandle;
  2220. BOOLEAN VcOwner;
  2221. if (pVc->Flags & PX_VC_IN_TABLE) {
  2222. CmVcHandle = pVc->CmVcHandle;
  2223. pVc->CmVcHandle = NULL;
  2224. ClVcHandle = pVc->ClVcHandle;
  2225. pVc->ClVcHandle = NULL;
  2226. VcOwner = (pVc->Flags & PX_VC_OWNER) ? TRUE : FALSE;
  2227. NdisReleaseSpinLock(&pVc->Lock);
  2228. if (CmVcHandle != NULL) {
  2229. NdisCoDeleteVc(CmVcHandle);
  2230. }
  2231. if (VcOwner && ClVcHandle != NULL) {
  2232. NdisCoDeleteVc(ClVcHandle);
  2233. }
  2234. RemoveVcFromTable(pVc);
  2235. } else {
  2236. NdisReleaseSpinLock(&(pVc)->Lock);
  2237. }
  2238. PxFreeVc(pVc);
  2239. }
  2240. #endif
  2241. //
  2242. // Called with pClAf->Lock held
  2243. //
  2244. VOID
  2245. DoDerefClAfWork(
  2246. PPX_CL_AF pClAf
  2247. )
  2248. {
  2249. NDIS_STATUS _s;
  2250. ASSERT(pClAf->State == PX_AF_CLOSING);
  2251. NdisReleaseSpinLock(&pClAf->Lock);
  2252. _s = NdisClCloseAddressFamily(pClAf->NdisAfHandle);
  2253. if (_s != NDIS_STATUS_PENDING) {
  2254. PxClCloseAfComplete(_s, pClAf);
  2255. }
  2256. }
  2257. //
  2258. // Called with pCmAf->lock held
  2259. //
  2260. VOID
  2261. DoDerefCmAfWork(
  2262. PPX_CM_AF pCmAf
  2263. )
  2264. {
  2265. ASSERT(pCmAf->State == PX_AF_CLOSED);
  2266. NdisReleaseSpinLock(&pCmAf->Lock);
  2267. NdisCmCloseAddressFamilyComplete(NDIS_STATUS_SUCCESS,
  2268. pCmAf->NdisAfHandle);
  2269. PxFreeCmAf(pCmAf);
  2270. }