Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2909 lines
65 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. D:\nt\private\ntos\tdi\nultrans\atm\atmsp.c
  5. Abstract:
  6. ATM Specific support functions for Null Transport. These routines
  7. perform operations like converting between TDI and NDIS formats.
  8. Revision History:
  9. Who When What
  10. -------- -------- ----------------------------------------------
  11. arvindm 06-02-97 Created
  12. Notes:
  13. --*/
  14. #include <precomp.h>
  15. #define _FILENUMBER 'SMTA'
  16. //
  17. // Global data structures.
  18. //
  19. ATMSP_GLOBAL_INFO AtmSpGlobal;
  20. PATMSP_GLOBAL_INFO pAtmSpGlobal;
  21. RWAN_STATUS
  22. RWanAtmSpInitialize(
  23. VOID
  24. )
  25. /*++
  26. Routine Description:
  27. Initialize our interface with the core Null Transport.
  28. Step 1: Register all supported NDIS AF+Media combinations.
  29. Step 2: Register all supported TDI protocols.
  30. Arguments:
  31. None
  32. Return Value:
  33. RWAN_STATUS_SUCCESS if we initialized OK, error code otherwise.
  34. --*/
  35. {
  36. PRWAN_NDIS_AF_CHARS pAfChars;
  37. PRWAN_TDI_PROTOCOL_CHARS pTdiChars;
  38. RWAN_STATUS RWanStatus;
  39. NDIS_STRING DeviceName = NDIS_STRING_CONST("\\Device\\Atm");
  40. pAtmSpGlobal = &AtmSpGlobal;
  41. NdisGetCurrentSystemTime(&pAtmSpGlobal->StartTime);
  42. //
  43. // Allocate space for the device string.
  44. //
  45. ATMSP_ALLOC_MEM(pAtmSpGlobal->AtmSpDeviceName.Buffer, WCHAR, DeviceName.MaximumLength);
  46. if (pAtmSpGlobal->AtmSpDeviceName.Buffer == NULL)
  47. {
  48. return RWAN_STATUS_RESOURCES;
  49. }
  50. pAtmSpGlobal->AtmSpDeviceName.MaximumLength = DeviceName.MaximumLength;
  51. RtlCopyUnicodeString(&pAtmSpGlobal->AtmSpDeviceName, &DeviceName);
  52. ATMSP_INIT_LIST(&pAtmSpGlobal->AfList);
  53. pAfChars = &(pAtmSpGlobal->AfChars);
  54. ATMSP_ZERO_MEM(pAfChars, sizeof(RWAN_NDIS_AF_CHARS));
  55. pAfChars->Medium = NdisMediumAtm;
  56. pAfChars->AddressFamily.AddressFamily = CO_ADDRESS_FAMILY_Q2931;
  57. pAfChars->AddressFamily.MajorVersion = ATMSP_AF_MAJOR_VERSION;
  58. pAfChars->AddressFamily.MinorVersion = ATMSP_AF_MINOR_VERSION;
  59. pAfChars->MaxAddressLength = sizeof(ATMSP_SOCKADDR_ATM);
  60. pAfChars->pAfSpOpenAf = RWanAtmSpOpenAf;
  61. pAfChars->pAfSpCloseAf = RWanAtmSpCloseAf;
  62. #ifndef NO_CONN_CONTEXT
  63. pAfChars->pAfSpOpenAddress = RWanAtmSpOpenAddressObject;
  64. pAfChars->pAfSpCloseAddress = RWanAtmSpCloseAddressObject;
  65. pAfChars->pAfSpAssociateConnection = RWanAtmSpAssociateConnection;
  66. pAfChars->pAfSpDisassociateConnection = RWanAtmSpDisassociateConnection;
  67. #endif
  68. pAfChars->pAfSpTdi2NdisOptions = RWanAtmSpTdi2NdisOptions;
  69. pAfChars->pAfSpUpdateNdisOptions = RWanAtmSpUpdateNdisOptions;
  70. pAfChars->pAfSpReturnNdisOptions = RWanAtmSpReturnNdisOptions;
  71. pAfChars->pAfSpNdis2TdiOptions = RWanAtmSpNdis2TdiOptions;
  72. pAfChars->pAfSpUpdateTdiOptions = RWanAtmSpUpdateTdiOptions;
  73. pAfChars->pAfSpReturnTdiOptions = RWanAtmSpReturnTdiOptions;
  74. pAfChars->pAfSpGetValidTdiAddress = RWanAtmSpGetValidTdiAddress;
  75. pAfChars->pAfSpIsNullAddress = RWanAtmSpIsNullAddress;
  76. pAfChars->pAfSpTdi2NdisSap = RWanAtmSpTdi2NdisSap;
  77. pAfChars->pAfSpReturnNdisSap = RWanAtmSpReturnNdisSap;
  78. pAfChars->pAfSpDeregNdisAFComplete = RWanAtmSpDeregNdisAFComplete;
  79. pAfChars->pAfSpAdapterRequestComplete = RWanAtmSpAdapterRequestComplete;
  80. pAfChars->pAfSpAfRequestComplete = RWanAtmSpAfRequestComplete;
  81. pAfChars->pAfSpQueryGlobalInfo = RWanAtmSpQueryGlobalInfo;
  82. pAfChars->pAfSpSetGlobalInfo = RWanAtmSpSetGlobalInfo;
  83. pAfChars->pAfSpQueryConnInformation = RWanAtmSpQueryConnInfo;
  84. pAfChars->pAfSpSetAddrInformation = RWanAtmSpSetAddrInfo;
  85. RWanStatus = RWanAfSpRegisterNdisAF(
  86. pAfChars,
  87. (RWAN_HANDLE)&AtmSpGlobal,
  88. &AtmSpGlobal.RWanSpHandle
  89. );
  90. if (RWanStatus == RWAN_STATUS_SUCCESS)
  91. {
  92. //
  93. // Inform the core Null transport about the TDI protocols
  94. // we support.
  95. //
  96. pTdiChars = &(AtmSpGlobal.TdiChars);
  97. ATMSP_ZERO_MEM(pTdiChars, sizeof(RWAN_TDI_PROTOCOL_CHARS));
  98. pTdiChars->SockAddressFamily = ATMSP_AF_ATM;
  99. pTdiChars->TdiProtocol = ATMSP_ATMPROTO_AAL5;
  100. pTdiChars->SockProtocol = ATMSP_ATMPROTO_AAL5;
  101. pTdiChars->SockType = ATMSP_SOCK_TYPE;
  102. pTdiChars->bAllowConnObjects = TRUE;
  103. pTdiChars->bAllowAddressObjects = TRUE;
  104. pTdiChars->MaxAddressLength = sizeof(ATM_ADDRESS);
  105. pTdiChars->pAfSpDeregTdiProtocolComplete = RWanAtmSpDeregTdiProtocolComplete;
  106. //
  107. // TBD: Fill in ProviderInfo
  108. //
  109. pTdiChars->ProviderInfo.Version = 0; // TBD
  110. pTdiChars->ProviderInfo.MaxSendSize = 65535;
  111. pTdiChars->ProviderInfo.MaxConnectionUserData = 0;
  112. pTdiChars->ProviderInfo.MaxDatagramSize = 0;
  113. pTdiChars->ProviderInfo.ServiceFlags =
  114. TDI_SERVICE_CONNECTION_MODE |
  115. TDI_SERVICE_MULTICAST_SUPPORTED |
  116. TDI_SERVICE_DELAYED_ACCEPTANCE |
  117. TDI_SERVICE_NO_ZERO_LENGTH |
  118. TDI_SERVICE_MESSAGE_MODE |
  119. TDI_SERVICE_FORCE_ACCESS_CHECK
  120. ;
  121. pTdiChars->ProviderInfo.MinimumLookaheadData = 1;
  122. pTdiChars->ProviderInfo.MaximumLookaheadData = 65535;
  123. pTdiChars->ProviderInfo.NumberOfResources = 0;
  124. pTdiChars->ProviderInfo.StartTime = pAtmSpGlobal->StartTime;
  125. pTdiChars->pDeviceName = &pAtmSpGlobal->AtmSpDeviceName;
  126. RWanStatus = RWanAfSpRegisterTdiProtocol(
  127. AtmSpGlobal.RWanSpHandle,
  128. pTdiChars,
  129. &AtmSpGlobal.RWanProtHandle
  130. );
  131. ATMSP_ASSERT(RWanStatus != RWAN_STATUS_PENDING);
  132. if (RWanStatus != RWAN_STATUS_SUCCESS)
  133. {
  134. RWanStatus = RWanAfSpDeregisterNdisAF(pAtmSpGlobal->RWanSpHandle);
  135. if (RWanStatus != RWAN_STATUS_PENDING)
  136. {
  137. RWanAtmSpDeregNdisAFComplete(
  138. RWanStatus,
  139. (RWAN_HANDLE)pAtmSpGlobal
  140. );
  141. }
  142. //
  143. // Cook the return value.
  144. //
  145. RWanStatus = RWAN_STATUS_FAILURE;
  146. }
  147. }
  148. if (RWanStatus != RWAN_STATUS_SUCCESS)
  149. {
  150. //
  151. // Clean up.
  152. //
  153. ATMSP_FREE_MEM(pAtmSpGlobal->AtmSpDeviceName.Buffer);
  154. pAtmSpGlobal->AtmSpDeviceName.Buffer = NULL;
  155. }
  156. return (RWanStatus);
  157. }
  158. VOID
  159. RWanAtmSpShutdown(
  160. VOID
  161. )
  162. /*++
  163. Routine Description:
  164. This entry point is called by the core Null Transport when it
  165. wants us to shutdown.
  166. We deregister the TDI Protocol and NDIS AF that we had registered.
  167. Arguments:
  168. None
  169. Return Value:
  170. None
  171. --*/
  172. {
  173. RWAN_STATUS RWanStatus;
  174. if (pAtmSpGlobal->RWanProtHandle != NULL)
  175. {
  176. RWanAfSpDeregisterTdiProtocol(pAtmSpGlobal->RWanProtHandle);
  177. }
  178. if (pAtmSpGlobal->RWanSpHandle != NULL)
  179. {
  180. RWanStatus = RWanAfSpDeregisterNdisAF(pAtmSpGlobal->RWanSpHandle);
  181. if (RWanStatus != RWAN_STATUS_PENDING)
  182. {
  183. RWanAtmSpDeregNdisAFComplete(
  184. RWanStatus,
  185. (RWAN_HANDLE)pAtmSpGlobal
  186. );
  187. }
  188. }
  189. if (pAtmSpGlobal->AtmSpDeviceName.Buffer)
  190. {
  191. ATMSP_FREE_MEM(pAtmSpGlobal->AtmSpDeviceName.Buffer);
  192. pAtmSpGlobal->AtmSpDeviceName.Buffer = NULL;
  193. }
  194. return;
  195. }
  196. RWAN_STATUS
  197. RWanAtmSpOpenAf(
  198. IN RWAN_HANDLE AfSpContext,
  199. IN RWAN_HANDLE RWanAFHandle,
  200. OUT PRWAN_HANDLE pAfSpAFContext,
  201. OUT PULONG pMaxMsgSize
  202. )
  203. /*++
  204. Routine Description:
  205. This entry point is called to set up our context for an NDIS AF
  206. open on a supported adapter. We allocate an AF context block,
  207. and query the miniport for some basic info about the adapter.
  208. Arguments:
  209. AfSpContext - Points to our global context
  210. RWanAFHandle - Handle for this Open AF from the core Null Transport
  211. pAfSpAFContext - Place to return our context for this AF
  212. pMaxMsgSize - Place to return max message size for this AF
  213. Return Value:
  214. RWAN_STATUS_SUCCESS normally, if we allocated an AF block
  215. RWAN_STATUS_RESOURCES if allocation failed.
  216. --*/
  217. {
  218. PATMSP_AF_BLOCK pAfBlock;
  219. RWAN_STATUS RWanStatus;
  220. UNREFERENCED_PARAMETER(AfSpContext);
  221. do
  222. {
  223. ATMSP_ALLOC_MEM(pAfBlock, ATMSP_AF_BLOCK, sizeof(ATMSP_AF_BLOCK));
  224. if (pAfBlock == NULL)
  225. {
  226. RWanStatus = RWAN_STATUS_RESOURCES;
  227. break;
  228. }
  229. pAfBlock->RWanAFHandle = RWanAFHandle;
  230. ATMSP_INSERT_TAIL_LIST(&pAtmSpGlobal->AfList, &pAfBlock->AfBlockLink);
  231. pAtmSpGlobal->AfListSize++;
  232. //
  233. // Query the Adapter for some information we use to build a default
  234. // QOS structure.
  235. //
  236. (VOID)AtmSpDoAdapterRequest(
  237. pAfBlock,
  238. NdisRequestQueryInformation,
  239. OID_GEN_CO_LINK_SPEED,
  240. &(pAfBlock->LineRate),
  241. sizeof(pAfBlock->LineRate)
  242. );
  243. (VOID)AtmSpDoAdapterRequest(
  244. pAfBlock,
  245. NdisRequestQueryInformation,
  246. OID_ATM_MAX_AAL5_PACKET_SIZE,
  247. &(pAfBlock->MaxPacketSize),
  248. sizeof(pAfBlock->MaxPacketSize)
  249. );
  250. *pMaxMsgSize = pAfBlock->MaxPacketSize;
  251. //
  252. // Prepare default QOS parameters for outgoing calls on this adapter.
  253. //
  254. AtmSpPrepareDefaultQoS(pAfBlock);
  255. *pAfSpAFContext = (RWAN_HANDLE)pAfBlock;
  256. RWanStatus = RWAN_STATUS_SUCCESS;
  257. break;
  258. }
  259. while (FALSE);
  260. if (RWanStatus != RWAN_STATUS_SUCCESS)
  261. {
  262. //
  263. // Clean up.
  264. //
  265. if (pAfBlock != NULL)
  266. {
  267. ATMSP_FREE_MEM(pAfBlock);
  268. }
  269. }
  270. return (RWanStatus);
  271. }
  272. RWAN_STATUS
  273. RWanAtmSpCloseAf(
  274. IN RWAN_HANDLE AfSpAFContext
  275. )
  276. /*++
  277. Routine Description:
  278. This entry point is called just before the core Null Transport
  279. closes an NDIS AF. We free the context we had allocated for this AF.
  280. Arguments:
  281. AfSpAFContext - Pointer to our AF block.
  282. Return Value:
  283. RWAN_STATUS_SUCCESS always.
  284. --*/
  285. {
  286. PATMSP_AF_BLOCK pAfBlock;
  287. pAfBlock = (PATMSP_AF_BLOCK)AfSpAFContext;
  288. ATMSP_DELETE_FROM_LIST(&pAfBlock->AfBlockLink);
  289. pAtmSpGlobal->AfListSize--;
  290. ATMSP_FREE_MEM(pAfBlock);
  291. return (RWAN_STATUS_SUCCESS);
  292. }
  293. RWAN_STATUS
  294. RWanAtmSpOpenAddressObject(
  295. IN RWAN_HANDLE AfSpContext,
  296. IN RWAN_HANDLE RWanAddrHandle,
  297. OUT PRWAN_HANDLE pAfSpAddrContext
  298. )
  299. /*++
  300. Routine Description:
  301. We are notified that a new address object is created. We create
  302. our context for the addr object, store Rawwan's handle for the
  303. object and return our context.
  304. Arguments:
  305. AfSpContext - Points to our global context
  306. RWanAddrHandle - Handle for this Address from the core RawWan
  307. pAfSpAddrContext - Place to return our context for this addr object
  308. Return Value:
  309. RWAN_STATUS_SUCCESS normally, if we allocated an Address block
  310. RWAN_STATUS_RESOURCES if allocation failed.
  311. --*/
  312. {
  313. PATMSP_ADDR_BLOCK pAddrBlock;
  314. RWAN_STATUS RWanStatus;
  315. *pAfSpAddrContext = NULL;
  316. do
  317. {
  318. ATMSP_ALLOC_MEM(pAddrBlock, ATMSP_ADDR_BLOCK, sizeof(ATMSP_ADDR_BLOCK));
  319. if (pAddrBlock == NULL)
  320. {
  321. RWanStatus = RWAN_STATUS_RESOURCES;
  322. break;
  323. }
  324. ATMSP_ZERO_MEM(pAddrBlock, sizeof(ATMSP_ADDR_BLOCK));
  325. pAddrBlock->RWanAddrHandle = RWanAddrHandle;
  326. pAddrBlock->RefCount = 1; // Creation
  327. ATMSP_INIT_LIST(&pAddrBlock->ConnList);
  328. ATMSP_INIT_LOCK(&pAddrBlock->Lock);
  329. //
  330. // Return value.
  331. //
  332. *pAfSpAddrContext = (RWAN_HANDLE)pAddrBlock;
  333. RWanStatus = RWAN_STATUS_SUCCESS;
  334. break;
  335. }
  336. while (FALSE);
  337. return (RWanStatus);
  338. }
  339. VOID
  340. RWanAtmSpCloseAddressObject(
  341. IN RWAN_HANDLE AfSpAddrContext
  342. )
  343. /*++
  344. Routine Description:
  345. Our notification routine called by RawWan when an Address Object
  346. is destroyed. At this time, no connection objects should be
  347. associated with it. We simply deallocate our context for the
  348. address object.
  349. Arguments:
  350. AfSpAddrContext - Actually a pointer to our address block
  351. Return Value:
  352. None
  353. --*/
  354. {
  355. PATMSP_ADDR_BLOCK pAddrBlock;
  356. ULONG rc;
  357. pAddrBlock = (PATMSP_ADDR_BLOCK)AfSpAddrContext;
  358. ATMSP_ACQUIRE_LOCK(&pAddrBlock->Lock);
  359. rc = --pAddrBlock->RefCount;
  360. ATMSP_RELEASE_LOCK(&pAddrBlock->Lock);
  361. if (rc == 0)
  362. {
  363. ATMSP_ASSERT(ATMSP_IS_LIST_EMPTY(&pAddrBlock->ConnList));
  364. ATMSP_FREE_LOCK(&pAddrBlock->Lock);
  365. ATMSP_FREE_MEM(pAddrBlock);
  366. }
  367. return;
  368. }
  369. RWAN_STATUS
  370. RWanAtmSpAssociateConnection(
  371. IN RWAN_HANDLE AfSpAddrContext,
  372. IN RWAN_HANDLE RWanConnHandle,
  373. OUT PRWAN_HANDLE pAfSpConnContext
  374. )
  375. /*++
  376. Routine Description:
  377. Our notification routine that's called by RawWan when a Connection
  378. Object is associated with an address object.
  379. We create a Connection Block and link it with the specified
  380. address block.
  381. Arguments:
  382. AfSpAddrContext - Actually a pointer to our address block
  383. RWanConnHandle - RawWan's handle for this connection object
  384. pAfSpConnHandle - where we're supposed to return our context for the conn object
  385. Return Value:
  386. RWAN_STATUS_SUCCESS always.
  387. --*/
  388. {
  389. PATMSP_CONN_BLOCK pConnBlock;
  390. PATMSP_ADDR_BLOCK pAddrBlock;
  391. RWAN_STATUS RWanStatus;
  392. pAddrBlock = (PATMSP_ADDR_BLOCK)AfSpAddrContext;
  393. do
  394. {
  395. ATMSP_ALLOC_MEM(pConnBlock, ATMSP_CONN_BLOCK, sizeof(ATMSP_CONN_BLOCK));
  396. if (pConnBlock == NULL)
  397. {
  398. RWanStatus = RWAN_STATUS_RESOURCES;
  399. break;
  400. }
  401. pConnBlock->RWanConnHandle = RWanConnHandle;
  402. pConnBlock->pAddrBlock = pAddrBlock;
  403. //
  404. // Link to address block.
  405. //
  406. ATMSP_ACQUIRE_LOCK(&pAddrBlock->Lock);
  407. ATMSP_INSERT_TAIL_LIST(&pAddrBlock->ConnList, &pConnBlock->ConnLink);
  408. pAddrBlock->RefCount++;
  409. ATMSP_RELEASE_LOCK(&pAddrBlock->Lock);
  410. //
  411. // Return values.
  412. //
  413. *pAfSpConnContext = (RWAN_HANDLE)pConnBlock;
  414. RWanStatus = RWAN_STATUS_SUCCESS;
  415. break;
  416. }
  417. while (FALSE);
  418. return (RWanStatus);
  419. }
  420. VOID
  421. RWanAtmSpDisassociateConnection(
  422. IN RWAN_HANDLE AfSpConnContext
  423. )
  424. /*++
  425. Routine Description:
  426. Our notification routine that's called by RawWan when a Connection
  427. Object is disassociated from its address object.
  428. Arguments:
  429. AfSpConnContext - Our Conn context that we returned from the Associate
  430. Connection routine.
  431. Return Value:
  432. None
  433. --*/
  434. {
  435. PATMSP_CONN_BLOCK pConnBlock;
  436. PATMSP_ADDR_BLOCK pAddrBlock;
  437. ULONG rc;
  438. pConnBlock = (PATMSP_CONN_BLOCK)AfSpConnContext;
  439. pAddrBlock = pConnBlock->pAddrBlock;
  440. ATMSP_ASSERT(pAddrBlock != NULL);
  441. //
  442. // De-link from address block first.
  443. //
  444. ATMSP_ACQUIRE_LOCK(&pAddrBlock->Lock);
  445. ATMSP_DELETE_FROM_LIST(&pConnBlock->ConnLink);
  446. rc = --pAddrBlock->RefCount;
  447. ATMSP_RELEASE_LOCK(&pAddrBlock->Lock);
  448. if (rc == 0)
  449. {
  450. ATMSP_ASSERT(ATMSP_IS_LIST_EMPTY(&pAddrBlock->ConnList));
  451. ATMSP_FREE_MEM(pAddrBlock);
  452. }
  453. ATMSP_FREE_MEM(pConnBlock);
  454. return;
  455. }
  456. RWAN_STATUS
  457. RWanAtmSpTdi2NdisOptions(
  458. IN RWAN_HANDLE AfSpConnContext,
  459. IN ULONG CallFlags,
  460. IN PTDI_CONNECTION_INFORMATION pTdiInfo,
  461. IN PVOID pTdiQoS,
  462. IN ULONG TdiQoSLength,
  463. OUT PRWAN_HANDLE pRWanAfHandle OPTIONAL,
  464. OUT PCO_CALL_PARAMETERS * ppCallParameters
  465. )
  466. /*++
  467. Routine Description:
  468. This is called to convert Call parameters from TDI form to
  469. NDIS format. We allocate space for NDIS parameters, fill it
  470. and return it.
  471. We also return the AFHandle for the AFBlock on which the call
  472. should be placed.
  473. For ATM, the call parameters are presented as follows:
  474. pTdiInfo->RemoteAddress - Calling/Called ATM Address, BLLI and BHLI
  475. pTdiQoS - Send and receive Flowspec, and optionally, other info elements.
  476. Arguments:
  477. AfSpConnContext - Points to our Conn block
  478. CallFlags - Call direction and other info
  479. pTdiInfo - Points to generic TDI Connection Information
  480. pTdiQoS - Points to Winsock 2 style QoS structure
  481. TdiQoSLength - Length of the above
  482. pRWanAfHandle - Place to return AF Handle
  483. ppCallParameters - Place to return pointer to NDIS call parameters
  484. Return Value:
  485. RWAN_STATUS_SUCCESS if we did the conversion successfully, RWAN_STATUS_XXX
  486. error code otherwise.
  487. --*/
  488. {
  489. RWAN_STATUS RWanStatus;
  490. PATMSP_AF_BLOCK pAfBlock;
  491. PATMSP_CONN_BLOCK pConnBlock;
  492. PATMSP_ADDR_BLOCK pAddrBlock;
  493. PCO_CALL_PARAMETERS pCallParameters;
  494. Q2931_CALLMGR_PARAMETERS UNALIGNED * pAtmCallParameters;
  495. CO_CALL_MANAGER_PARAMETERS UNALIGNED * pCallMgrParameters;
  496. PATM_MEDIA_PARAMETERS pAtmMediaParameters;
  497. ULONG ParametersLength;
  498. Q2931_IE UNALIGNED * pIe;
  499. Q2931_IE UNALIGNED * pFirstIe;
  500. Q2931_IE UNALIGNED * pDstIe;
  501. ULONG IeLength;
  502. ATMSP_QOS * pQoS;
  503. ATMSP_SOCKADDR_ATM UNALIGNED * pRemoteAddr;
  504. BOOLEAN IsBhliPresent; // part of Remote addr
  505. BOOLEAN IsBlliPresent; // part of Remote addr
  506. INT TotalIeLength; // explicitly passed to us by user
  507. ULONG InfoElementCount; // explicit IE count
  508. BOOLEAN IsOutgoingCall;
  509. BOOLEAN IsPMPCall;
  510. BOOLEAN IsPVC;
  511. //
  512. // Initialize.
  513. //
  514. RWanStatus = RWAN_STATUS_SUCCESS;
  515. do
  516. {
  517. #ifndef NO_CONN_CONTEXT
  518. pConnBlock = (PATMSP_CONN_BLOCK)AfSpConnContext;
  519. ATMSP_ASSERT(pConnBlock != NULL);
  520. pAddrBlock = pConnBlock->pAddrBlock;
  521. ATMSP_ASSERT(pAddrBlock != NULL);
  522. IsPVC = (ATMSP_IS_BIT_SET(pAddrBlock->Flags, ATMSPF_ADDR_PVC_ID_SET));
  523. #else
  524. IsPVC = FALSE;
  525. #endif
  526. IsOutgoingCall = ((CallFlags & RWAN_CALLF_CALL_DIRECTION_MASK) == RWAN_CALLF_OUTGOING_CALL);
  527. IsPMPCall = ((CallFlags & RWAN_CALLF_CALL_TYPE_MASK) == RWAN_CALLF_POINT_TO_MULTIPOINT);
  528. if (IsPVC)
  529. {
  530. //
  531. // Locate the AF block corresponding to the device
  532. // number.
  533. //
  534. pAfBlock = AtmSpDeviceNumberToAfBlock(pAddrBlock->ConnectionId.DeviceNumber);
  535. if (pAfBlock == NULL)
  536. {
  537. RWanStatus = RWAN_STATUS_BAD_ADDRESS;
  538. break;
  539. }
  540. }
  541. else
  542. {
  543. if (ATMSP_IS_LIST_EMPTY(&pAtmSpGlobal->AfList))
  544. {
  545. RWanStatus = RWAN_STATUS_BAD_ADDRESS;
  546. break;
  547. }
  548. pAfBlock = CONTAINING_RECORD(pAtmSpGlobal->AfList.Flink, ATMSP_AF_BLOCK, AfBlockLink);
  549. }
  550. //
  551. // Validate.
  552. //
  553. if (IsOutgoingCall)
  554. {
  555. pRemoteAddr = AtmSpGetSockAtmAddress(pTdiInfo->RemoteAddress, pTdiInfo->RemoteAddressLength);
  556. if (pRemoteAddr == NULL)
  557. {
  558. RWanStatus = RWAN_STATUS_BAD_ADDRESS;
  559. break;
  560. }
  561. RWANDEBUGPATMADDR(DL_LOUD, DC_CONNECT,
  562. "AtmSpTdi2NdisOptions: remote addr: ", &pRemoteAddr->satm_number);
  563. }
  564. else
  565. {
  566. pRemoteAddr = NULL;
  567. }
  568. if (pTdiQoS == NULL)
  569. {
  570. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  571. ("AtmSpTdi2NdisOptions: NULL TDIQOS\n"));
  572. pQoS = &(pAfBlock->DefaultQoS);
  573. TdiQoSLength = pAfBlock->DefaultQoSLength;
  574. TotalIeLength = 0;
  575. InfoElementCount = 0;
  576. }
  577. else
  578. {
  579. if (TdiQoSLength < sizeof(ATMSP_QOS))
  580. {
  581. RWanStatus = RWAN_STATUS_BAD_PARAMETER;
  582. break;
  583. }
  584. pQoS = (ATMSP_QOS *)pTdiQoS;
  585. RWANDEBUGP(DL_FATAL, DC_WILDCARD,
  586. ("AtmSpTdi2NdisOptions: Send: ServiceType %d, Peak %d, Recv %d, %d\n",
  587. pQoS->SendingFlowSpec.ServiceType,
  588. pQoS->SendingFlowSpec.PeakBandwidth,
  589. pQoS->ReceivingFlowSpec.ServiceType,
  590. pQoS->ReceivingFlowSpec.PeakBandwidth));
  591. //
  592. // The provider-specific part is a list of Info Elements.
  593. // Get the total length of this list.
  594. //
  595. TotalIeLength = (INT)pQoS->ProviderSpecific.len;
  596. //
  597. // Get at the first Info element in the list.
  598. //
  599. pIe = (PQ2931_IE)((ULONG_PTR)pQoS + (ULONG_PTR)pQoS->ProviderSpecific.buf);
  600. pFirstIe = pIe;
  601. #if 0
  602. if (((pIe == NULL) && (TotalIeLength != 0)) ||
  603. ((pIe != NULL) && (TotalIeLength < sizeof(Q2931_IE))))
  604. {
  605. RWanStatus = RWAN_STATUS_BAD_PARAMETER;
  606. break;
  607. }
  608. #endif // 0
  609. //
  610. // Count the total number of Info Elements present.
  611. // XXX: should we check IE types?
  612. //
  613. InfoElementCount = 0;
  614. while (TotalIeLength >= sizeof(Q2931_IE))
  615. {
  616. ATMSP_AAL_PARAMETERS_IE UNALIGNED *pAalParamsIe;
  617. ATM_BROADBAND_BEARER_CAPABILITY_IE UNALIGNED *pBbcIe;
  618. if ((pIe->IELength == 0) ||
  619. (pIe->IELength > (ULONG)TotalIeLength))
  620. {
  621. RWanStatus = RWAN_STATUS_BAD_PARAMETER;
  622. break;
  623. }
  624. switch (pIe->IEType)
  625. {
  626. case IE_AALParameters:
  627. //
  628. // Map AAL Type.
  629. //
  630. pAalParamsIe = (ATMSP_AAL_PARAMETERS_IE UNALIGNED *)&pIe->IE[0];
  631. if (pIe->IELength >= sizeof(*pAalParamsIe))
  632. {
  633. switch (pAalParamsIe->AALType)
  634. {
  635. case ATMSP_AALTYPE_5:
  636. pAalParamsIe->AALType = AAL_TYPE_AAL5;
  637. break;
  638. case ATMSP_AALTYPE_USER:
  639. pAalParamsIe->AALType = AAL_TYPE_AAL0;
  640. break;
  641. default:
  642. break;
  643. }
  644. }
  645. break;
  646. case IE_BroadbandBearerCapability:
  647. //
  648. // Map BearerClass.
  649. //
  650. pBbcIe = (ATM_BROADBAND_BEARER_CAPABILITY_IE UNALIGNED *)&pIe->IE[0];
  651. if (pIe->IELength >= sizeof(*pBbcIe))
  652. {
  653. switch (pBbcIe->BearerClass)
  654. {
  655. case ATMSP_BCOB_A:
  656. pBbcIe->BearerClass = BCOB_A;
  657. break;
  658. case ATMSP_BCOB_C:
  659. pBbcIe->BearerClass = BCOB_C;
  660. break;
  661. case ATMSP_BCOB_X:
  662. pBbcIe->BearerClass = BCOB_X;
  663. break;
  664. default:
  665. break;
  666. }
  667. }
  668. break;
  669. default:
  670. break;
  671. }
  672. TotalIeLength -= (INT)pIe->IELength;
  673. pIe = (PQ2931_IE)((PUCHAR)pIe + pIe->IELength);
  674. InfoElementCount++;
  675. }
  676. if (RWanStatus != RWAN_STATUS_SUCCESS)
  677. {
  678. break;
  679. }
  680. TotalIeLength = (INT)pQoS->ProviderSpecific.len;
  681. pIe = pFirstIe;
  682. }
  683. //
  684. // Calculate the total length requirements.
  685. //
  686. ParametersLength = sizeof(CO_CALL_PARAMETERS) +
  687. sizeof(CO_CALL_MANAGER_PARAMETERS) +
  688. sizeof(Q2931_CALLMGR_PARAMETERS) +
  689. TotalIeLength;
  690. IsBlliPresent = (pRemoteAddr? ATMSP_BLLI_PRESENT(&pRemoteAddr->satm_blli): FALSE);
  691. if (IsBlliPresent)
  692. {
  693. ParametersLength += sizeof(ATM_BLLI_IE);
  694. }
  695. IsBhliPresent = (pRemoteAddr? ATMSP_BHLI_PRESENT(&pRemoteAddr->satm_bhli): FALSE);
  696. if (IsBhliPresent)
  697. {
  698. ParametersLength += sizeof(ATM_BHLI_IE);
  699. }
  700. #ifndef NO_CONN_CONTEXT
  701. //
  702. // If this is a PVC, we'll fill in the Media parameters too.
  703. //
  704. if (IsPVC)
  705. {
  706. ParametersLength += sizeof(CO_MEDIA_PARAMETERS) +
  707. sizeof(ATM_MEDIA_PARAMETERS);
  708. }
  709. #endif
  710. RWANDEBUGP(DL_EXTRA_LOUD, DC_CONNECT,
  711. ("AtmSpTdi2NdisOptions: BlliPresent %d, BhliPresent %d, TotalIeLen %d, ParamsLength %d\n",
  712. IsBlliPresent,
  713. IsBhliPresent,
  714. TotalIeLength,
  715. ParametersLength
  716. ));
  717. ATMSP_ALLOC_MEM(pCallParameters, CO_CALL_PARAMETERS, ParametersLength);
  718. if (pCallParameters == NULL)
  719. {
  720. RWanStatus = RWAN_STATUS_RESOURCES;
  721. break;
  722. }
  723. ATMSP_ZERO_MEM(pCallParameters, ParametersLength);
  724. pCallParameters->Flags = 0;
  725. if (IsPMPCall)
  726. {
  727. pCallParameters->Flags |= MULTIPOINT_VC;
  728. }
  729. if (IsPVC)
  730. {
  731. pCallParameters->Flags |= PERMANENT_VC;
  732. //
  733. // Start off with Media parameters, and then Call Mgr parameters.
  734. //
  735. pCallParameters->MediaParameters =
  736. (PCO_MEDIA_PARAMETERS)((PUCHAR)pCallParameters +
  737. sizeof(CO_CALL_PARAMETERS));
  738. pCallParameters->MediaParameters->MediaSpecific.ParamType = ATM_MEDIA_SPECIFIC;
  739. pCallParameters->MediaParameters->MediaSpecific.Length = sizeof(ATM_MEDIA_PARAMETERS);
  740. pAtmMediaParameters = (PATM_MEDIA_PARAMETERS)&pCallParameters->MediaParameters->MediaSpecific.Parameters[0];
  741. //
  742. // Get the VPI/VCI values.
  743. //
  744. pAtmMediaParameters->ConnectionId.Vpi = pAddrBlock->ConnectionId.Vpi;
  745. pAtmMediaParameters->ConnectionId.Vci = pAddrBlock->ConnectionId.Vci;
  746. //
  747. // Force the Call Manager to compute the rest of the ATM media
  748. // parameters from the generic QoS parameters or IEs.
  749. //
  750. pAtmMediaParameters->AALType = QOS_NOT_SPECIFIED;
  751. //
  752. // Allocate Call manager parameters space following the
  753. // media parameters.
  754. //
  755. pCallMgrParameters =
  756. pCallParameters->CallMgrParameters =
  757. (PCO_CALL_MANAGER_PARAMETERS)((PUCHAR)pCallParameters +
  758. sizeof(CO_MEDIA_PARAMETERS) +
  759. sizeof(ATM_MEDIA_PARAMETERS) +
  760. sizeof(CO_CALL_PARAMETERS));
  761. }
  762. else
  763. {
  764. pCallParameters->MediaParameters = NULL;
  765. pCallMgrParameters =
  766. pCallParameters->CallMgrParameters =
  767. (PCO_CALL_MANAGER_PARAMETERS)((PUCHAR)pCallParameters +
  768. sizeof(CO_CALL_PARAMETERS));
  769. }
  770. if (IsOutgoingCall)
  771. {
  772. pCallMgrParameters->Transmit = pQoS->SendingFlowSpec;
  773. pCallMgrParameters->Receive = pQoS->ReceivingFlowSpec;
  774. if (IsPMPCall)
  775. {
  776. pCallMgrParameters->Receive.ServiceType = SERVICETYPE_NOTRAFFIC;
  777. pCallMgrParameters->Receive.PeakBandwidth = 0;
  778. }
  779. }
  780. else
  781. {
  782. pCallMgrParameters->Transmit = pQoS->ReceivingFlowSpec;
  783. pCallMgrParameters->Receive = pQoS->SendingFlowSpec;
  784. if (IsPMPCall)
  785. {
  786. pCallMgrParameters->Transmit.ServiceType = SERVICETYPE_NOTRAFFIC;
  787. pCallMgrParameters->Transmit.PeakBandwidth = 0;
  788. }
  789. }
  790. pCallMgrParameters->CallMgrSpecific.ParamType = 0; // XXX?
  791. pAtmCallParameters = (PQ2931_CALLMGR_PARAMETERS)
  792. &(pCallMgrParameters->CallMgrSpecific.Parameters[0]);
  793. if (IsOutgoingCall)
  794. {
  795. ATMSP_ZERO_MEM(&pAtmCallParameters->CallingParty, sizeof(ATM_ADDRESS));
  796. pAtmCallParameters->CalledParty = pRemoteAddr->satm_number;
  797. if ((pRemoteAddr->satm_number.AddressType != SOCKATM_E164) &&
  798. (pRemoteAddr->satm_number.AddressType != SOCKATM_NSAP))
  799. {
  800. RWanStatus = RWAN_STATUS_BAD_ADDRESS;
  801. break;
  802. }
  803. pAtmCallParameters->CalledParty.AddressType =
  804. ((pRemoteAddr->satm_number.AddressType == SOCKATM_E164)?
  805. ATM_E164: ATM_NSAP);
  806. }
  807. else
  808. {
  809. ATMSP_ZERO_MEM(&pAtmCallParameters->CalledParty, sizeof(ATM_ADDRESS));
  810. if (pRemoteAddr != NULL)
  811. {
  812. pAtmCallParameters->CallingParty = pRemoteAddr->satm_number;
  813. pAtmCallParameters->CallingParty.AddressType =
  814. ((pRemoteAddr->satm_number.AddressType == SOCKATM_E164)?
  815. ATM_E164: ATM_NSAP);
  816. }
  817. }
  818. pAtmCallParameters->InfoElementCount = 0;
  819. pDstIe = (PQ2931_IE) &pAtmCallParameters->InfoElements[0];
  820. //
  821. // Copy in the BHLI and BLLI IEs.
  822. //
  823. if (IsBhliPresent)
  824. {
  825. ATM_BHLI_IE UNALIGNED * pBhliIe;
  826. pDstIe->IEType = IE_BHLI;
  827. pDstIe->IELength = ROUND_UP(sizeof(Q2931_IE) + sizeof(ATM_BHLI_IE));
  828. pBhliIe = (ATM_BHLI_IE UNALIGNED *)pDstIe->IE;
  829. pBhliIe->HighLayerInfoType = pRemoteAddr->satm_bhli.HighLayerInfoType;
  830. pBhliIe->HighLayerInfoLength = pRemoteAddr->satm_bhli.HighLayerInfoLength;
  831. ATMSP_COPY_MEM(pBhliIe->HighLayerInfo,
  832. pRemoteAddr->satm_bhli.HighLayerInfo,
  833. 8);
  834. pDstIe = (PQ2931_IE)((PUCHAR)pDstIe + pDstIe->IELength);
  835. pAtmCallParameters->InfoElementCount++;
  836. }
  837. if (IsBlliPresent)
  838. {
  839. ATM_BLLI_IE UNALIGNED * pBlliIe;
  840. pDstIe->IEType = IE_BLLI;
  841. pDstIe->IELength = ROUND_UP(sizeof(Q2931_IE) + sizeof(ATM_BLLI_IE));
  842. pBlliIe = (ATM_BLLI_IE UNALIGNED *)pDstIe->IE;
  843. pBlliIe->Layer2Protocol = pRemoteAddr->satm_blli.Layer2Protocol;
  844. pBlliIe->Layer2Mode = pBlliIe->Layer2WindowSize = 0;
  845. pBlliIe->Layer2UserSpecifiedProtocol = pRemoteAddr->satm_blli.Layer2UserSpecifiedProtocol;
  846. pBlliIe->Layer3Protocol = pRemoteAddr->satm_blli.Layer3Protocol;
  847. pBlliIe->Layer3Mode = 0;
  848. pBlliIe->Layer3DefaultPacketSize = 0;
  849. pBlliIe->Layer3PacketWindowSize = 0;
  850. pBlliIe->Layer3UserSpecifiedProtocol = pRemoteAddr->satm_blli.Layer3UserSpecifiedProtocol;
  851. pBlliIe->Layer3IPI = pRemoteAddr->satm_blli.Layer3IPI;
  852. ATMSP_COPY_MEM(pBlliIe->SnapId, pRemoteAddr->satm_blli.SnapId, 5);
  853. pDstIe = (PQ2931_IE)((PUCHAR)pDstIe + pDstIe->IELength);
  854. pAtmCallParameters->InfoElementCount++;
  855. RWANDEBUGP(DL_INFO, DC_CONNECT,
  856. ("AtmSpTdi2NdisOptions: BLLI: Layer2Prot x%x, Layer3Prot x%x\n",
  857. pBlliIe->Layer2Protocol, pBlliIe->Layer3Protocol));
  858. }
  859. //
  860. // Copy in the rest of the IEs.
  861. //
  862. if (InfoElementCount != 0)
  863. {
  864. pAtmCallParameters->InfoElementCount += InfoElementCount;
  865. ATMSP_COPY_MEM(pDstIe, pIe, TotalIeLength);
  866. pDstIe = (PQ2931_IE)((PUCHAR)pDstIe + TotalIeLength);
  867. }
  868. //
  869. // Compute the length of the Call manager specific part.
  870. //
  871. pCallMgrParameters->CallMgrSpecific.Length =
  872. (ULONG)((ULONG_PTR)pDstIe - (ULONG_PTR)pAtmCallParameters);
  873. //
  874. // We are done. Prepare return values.
  875. //
  876. *ppCallParameters = pCallParameters;
  877. if (pRWanAfHandle != NULL)
  878. {
  879. *pRWanAfHandle = pAfBlock->RWanAFHandle;
  880. }
  881. break;
  882. }
  883. while (FALSE);
  884. return (RWanStatus);
  885. }
  886. RWAN_STATUS
  887. RWanAtmSpUpdateNdisOptions(
  888. IN RWAN_HANDLE AfSpAFContext,
  889. IN RWAN_HANDLE AfSpConnContext,
  890. IN ULONG CallFlags,
  891. IN PTDI_CONNECTION_INFORMATION pTdiInfo,
  892. IN PVOID pTdiQoS,
  893. IN ULONG TdiQoSLength,
  894. IN OUT PCO_CALL_PARAMETERS * ppCallParameters
  895. )
  896. /*++
  897. Routine Description:
  898. This entry point is called in order to update NDIS Call parameters
  899. with values from TDI-style QoS and options. The most common case
  900. where this is called is when a called user negotiates parameters
  901. for an incoming call.
  902. For now, we simply note down the VPI/VCI values for the connection,
  903. in order to support SIO_GET_ATM_CONNECTION_ID
  904. Arguments:
  905. AfSpAFContext - Points to our AF block
  906. AfSpConnContext - Points to our Conn block
  907. CallFlags - Call direction and other info
  908. pTdiInfo - Generic TDI Connection information block
  909. pTdiQoS - Points to TDI-style QOS structure
  910. TdiQoSLength - Length of the above
  911. ppCallParameters - Points to pointer to NDIS Call Parameters to be updated
  912. Return Value:
  913. RWAN_STATUS_SUCCESS if we successfully updated NDIS parameters.
  914. --*/
  915. {
  916. RWAN_STATUS RWanStatus;
  917. PATMSP_AF_BLOCK pAfBlock;
  918. PATMSP_CONN_BLOCK pConnBlock;
  919. PATM_MEDIA_PARAMETERS pAtmMediaParameters;
  920. RWanStatus = RWAN_STATUS_SUCCESS;
  921. pAfBlock = (PATMSP_AF_BLOCK)AfSpAFContext;
  922. pConnBlock = (PATMSP_CONN_BLOCK)AfSpConnContext;
  923. ATMSP_ASSERT(pAfBlock != NULL);
  924. ATMSP_ASSERT(pConnBlock != NULL);
  925. ATMSP_ASSERT(ppCallParameters != NULL);
  926. ATMSP_ASSERT(*ppCallParameters != NULL);
  927. do
  928. {
  929. pAtmMediaParameters = (PATM_MEDIA_PARAMETERS)
  930. &((*ppCallParameters)->MediaParameters->MediaSpecific.Parameters[0]);
  931. pConnBlock->ConnectionId.DeviceNumber = AtmSpAfBlockToDeviceNumber(pAfBlock);
  932. pConnBlock->ConnectionId.Vpi = pAtmMediaParameters->ConnectionId.Vpi;
  933. pConnBlock->ConnectionId.Vci = pAtmMediaParameters->ConnectionId.Vci;
  934. RWANDEBUGP(DL_VERY_LOUD, DC_CONNECT,
  935. ("AtmSP: UpdateNdis: VPI %d, VCI %d\n",
  936. pConnBlock->ConnectionId.Vpi,
  937. pConnBlock->ConnectionId.Vci));
  938. break;
  939. }
  940. while (FALSE);
  941. return (RWanStatus);
  942. }
  943. VOID
  944. RWanAtmSpReturnNdisOptions(
  945. IN RWAN_HANDLE AfSpAFContext,
  946. IN PCO_CALL_PARAMETERS pCallParameters
  947. )
  948. /*++
  949. Routine Description:
  950. This entry point is called when core Null Transport is done with
  951. an NDIS options structure we'd given it via RWanAtmSpTdi2NdisOptions.
  952. We simply free the memory used for the structure.
  953. Arguments:
  954. AfSpAFContext - Points to our AF block
  955. pCallParameters - Points to NDIS options
  956. Return Value:
  957. None
  958. --*/
  959. {
  960. UNREFERENCED_PARAMETER(AfSpAFContext);
  961. ATMSP_FREE_MEM(pCallParameters);
  962. }
  963. RWAN_STATUS
  964. RWanAtmSpNdis2TdiOptions(
  965. IN RWAN_HANDLE AfSpAFContext,
  966. IN ULONG CallFlags,
  967. IN PCO_CALL_PARAMETERS pCallParameters,
  968. OUT PTDI_CONNECTION_INFORMATION *ppTdiInfo,
  969. OUT PVOID * ppTdiQoS,
  970. OUT PULONG pTdiQoSLength,
  971. OUT RWAN_HANDLE * pAfSpTdiOptionsContext
  972. )
  973. /*++
  974. Routine Description:
  975. Convert NDIS Call parameters to TDI options and QoS. We allocate space
  976. for the latter, fill them and return them.
  977. Arguments:
  978. AfSpAFContext - Points to our AF block
  979. CallFlags - Call direction and other flags
  980. pCallParameters - Pointer to NDIS Call Parameters
  981. ppTdiInfo - Place to return pointer to allocated TDI Connection info
  982. ppTdiQoS - Place to return pointer to allocated TDI QoS structure
  983. pTdiQoSLength - Place to return length of the above
  984. pAfSpTdiOptionsContext - Place to put our context for this allocated structure.
  985. Return Value:
  986. RWAN_STATUS_SUCCESS if we successfully converted NDIS to TDI parameters,
  987. RWAN_STATUS_XXX error otherwise.
  988. --*/
  989. {
  990. Q2931_CALLMGR_PARAMETERS UNALIGNED * pAtmCallParameters;
  991. CO_CALL_MANAGER_PARAMETERS UNALIGNED * pCallMgrParameters;
  992. Q2931_IE UNALIGNED * pIe;
  993. ATM_BLLI_IE UNALIGNED * pBlli;
  994. ATM_BHLI_IE UNALIGNED * pBhli;
  995. AAL_PARAMETERS_IE UNALIGNED * pAalIe;
  996. AAL5_PARAMETERS UNALIGNED * pAal5Params;
  997. ATM_BROADBAND_BEARER_CAPABILITY_IE UNALIGNED *pBbcIe;
  998. ULONG TotalLength;
  999. ULONG TotalIeLength;
  1000. ULONG i;
  1001. PATMSP_AF_BLOCK pAfBlock;
  1002. PTDI_CONNECTION_INFORMATION pTdiInfo;
  1003. PTRANSPORT_ADDRESS pTransportAddress;
  1004. PTA_ADDRESS pAddress;
  1005. ATMSP_SOCKADDR_ATM UNALIGNED * pSockAddrAtm;
  1006. ATM_ADDRESS UNALIGNED * pAtmAddress;
  1007. PVOID pTdiQoS;
  1008. ATMSP_QOS UNALIGNED * pQoS;
  1009. RWAN_STATUS RWanStatus;
  1010. BOOLEAN IsOutgoingCall;
  1011. pBlli = NULL;
  1012. pBhli = NULL;
  1013. pAfBlock = (PATMSP_AF_BLOCK)AfSpAFContext;
  1014. IsOutgoingCall = ((CallFlags & RWAN_CALLF_CALL_DIRECTION_MASK) == RWAN_CALLF_OUTGOING_CALL);
  1015. pCallMgrParameters = pCallParameters->CallMgrParameters;
  1016. pAtmCallParameters = (PQ2931_CALLMGR_PARAMETERS)
  1017. &(pCallMgrParameters->CallMgrSpecific.Parameters[0]);
  1018. //
  1019. // Compute space required:
  1020. // 1. TDI Connection Information
  1021. // 2. Remote address
  1022. // 3. Generic QoS
  1023. // 4. Provider-specific buffer containing IEs
  1024. //
  1025. TotalLength = sizeof(TDI_CONNECTION_INFORMATION)
  1026. + TA_HEADER_LENGTH + TA_ATM_ADDRESS_LENGTH
  1027. + sizeof(ATMSP_QOS)
  1028. ;
  1029. //
  1030. // Add space for IE list, and note down positions of BHLI and BLLI
  1031. // info elements - we need these for the SOCKADDR_ATM.
  1032. //
  1033. pIe = (PQ2931_IE)&(pAtmCallParameters->InfoElements[0]);
  1034. TotalIeLength = 0;
  1035. for (i = 0; i < pAtmCallParameters->InfoElementCount; i++)
  1036. {
  1037. TotalIeLength += pIe->IELength;
  1038. switch (pIe->IEType)
  1039. {
  1040. case IE_BLLI:
  1041. if (pBlli == NULL)
  1042. {
  1043. pBlli = (PATM_BLLI_IE) &(pIe->IE[0]);
  1044. }
  1045. break;
  1046. case IE_BHLI:
  1047. if (pBhli == NULL)
  1048. {
  1049. pBhli = (PATM_BHLI_IE) &(pIe->IE[0]);
  1050. }
  1051. break;
  1052. case IE_AALParameters:
  1053. pAalIe = (AAL_PARAMETERS_IE UNALIGNED *)&pIe->IE[0];
  1054. switch (pAalIe->AALType)
  1055. {
  1056. case AAL_TYPE_AAL5:
  1057. pAalIe->AALType = ATMSP_AALTYPE_5;
  1058. pAal5Params = &pAalIe->AALSpecificParameters.AAL5Parameters;
  1059. if (pAal5Params->ForwardMaxCPCSSDUSize > pAfBlock->MaxPacketSize)
  1060. {
  1061. pAal5Params->ForwardMaxCPCSSDUSize = pAfBlock->MaxPacketSize;
  1062. }
  1063. if (pAal5Params->BackwardMaxCPCSSDUSize > pAfBlock->MaxPacketSize)
  1064. {
  1065. pAal5Params->BackwardMaxCPCSSDUSize = pAfBlock->MaxPacketSize;
  1066. }
  1067. break;
  1068. case AAL_TYPE_AAL0:
  1069. pAalIe->AALType = ATMSP_AALTYPE_USER;
  1070. break;
  1071. default:
  1072. ATMSP_ASSERT(FALSE);
  1073. break;
  1074. }
  1075. break;
  1076. case IE_BroadbandBearerCapability:
  1077. pBbcIe = (ATM_BROADBAND_BEARER_CAPABILITY_IE UNALIGNED *)&pIe->IE[0];
  1078. switch (pBbcIe->BearerClass)
  1079. {
  1080. case BCOB_A:
  1081. pBbcIe->BearerClass = ATMSP_BCOB_A;
  1082. break;
  1083. case BCOB_C:
  1084. pBbcIe->BearerClass = ATMSP_BCOB_C;
  1085. break;
  1086. case BCOB_X:
  1087. pBbcIe->BearerClass = ATMSP_BCOB_X;
  1088. break;
  1089. default:
  1090. break;
  1091. }
  1092. break;
  1093. default:
  1094. break;
  1095. }
  1096. pIe = (PQ2931_IE)((PUCHAR)pIe + pIe->IELength);
  1097. }
  1098. TotalLength += TotalIeLength;
  1099. RWanStatus = RWAN_STATUS_SUCCESS;
  1100. do
  1101. {
  1102. ATMSP_ALLOC_MEM(pTdiInfo, TDI_CONNECTION_INFORMATION, TotalLength);
  1103. if (pTdiInfo == NULL)
  1104. {
  1105. RWanStatus = RWAN_STATUS_RESOURCES;
  1106. break;
  1107. }
  1108. pTdiInfo->UserDataLength = 0;
  1109. pTdiInfo->UserData = NULL;
  1110. pTdiInfo->OptionsLength = 0;
  1111. pTdiInfo->Options = 0;
  1112. pTdiInfo->RemoteAddressLength = TA_HEADER_LENGTH + TA_ATM_ADDRESS_LENGTH;
  1113. pTdiInfo->RemoteAddress =
  1114. (PVOID) ((PUCHAR)pTdiInfo + sizeof(TDI_CONNECTION_INFORMATION));
  1115. pTdiQoS = (PVOID) ((PUCHAR)pTdiInfo->RemoteAddress + pTdiInfo->RemoteAddressLength);
  1116. //
  1117. // Fill in the Remote address.
  1118. //
  1119. ATMSP_ZERO_MEM(pTdiInfo->RemoteAddress, pTdiInfo->RemoteAddressLength);
  1120. pTransportAddress = (PTRANSPORT_ADDRESS)pTdiInfo->RemoteAddress;
  1121. pTransportAddress->TAAddressCount = 1;
  1122. pAddress = (PTA_ADDRESS)&(pTransportAddress->Address[0]);
  1123. pAddress->AddressLength = TA_ATM_ADDRESS_LENGTH; // sizeof(ATMSP_SOCKADDR_ATM);
  1124. pAddress->AddressType = TDI_ADDRESS_TYPE_ATM;
  1125. #if 0
  1126. pSockAddrAtm = (ATMSP_SOCKADDR_ATM *)&(pAddress->Address[0]);
  1127. #else
  1128. pSockAddrAtm = TA_POINTER_TO_ATM_ADDR_POINTER(pAddress->Address);
  1129. #endif
  1130. pAtmAddress = &(pSockAddrAtm->satm_number);
  1131. if (IsOutgoingCall)
  1132. {
  1133. *pAtmAddress = pAtmCallParameters->CalledParty;
  1134. pAtmAddress->AddressType =
  1135. ((pAtmCallParameters->CalledParty.AddressType == ATM_E164)?
  1136. SOCKATM_E164: SOCKATM_NSAP);
  1137. }
  1138. else
  1139. {
  1140. *pAtmAddress = pAtmCallParameters->CallingParty;
  1141. pAtmAddress->AddressType =
  1142. ((pAtmCallParameters->CallingParty.AddressType == ATM_E164)?
  1143. SOCKATM_E164: SOCKATM_NSAP);
  1144. }
  1145. RWANDEBUGP(DL_VERY_LOUD, DC_CONNECT,
  1146. ("AtmSpNdis2TdiOptions: pAddress %x, pSockAddrAtm %x, pAtmAddress %x, pAddress dump:\n",
  1147. pAddress, pSockAddrAtm, pAtmAddress));
  1148. RWANDEBUGPDUMP(DL_VERY_LOUD, DC_CONNECT, (PUCHAR)pAddress, sizeof(TA_ADDRESS) + sizeof(*pSockAddrAtm));
  1149. RWANDEBUGPATMADDR(DL_LOUD, DC_CONNECT,
  1150. "AtmSpNdis2TdiOptions: remote addr: ", pAtmAddress);
  1151. //
  1152. // Fill in BHLI and BLLI elements.
  1153. //
  1154. if (pBhli == NULL)
  1155. {
  1156. pSockAddrAtm->satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT;
  1157. }
  1158. else
  1159. {
  1160. pSockAddrAtm->satm_bhli.HighLayerInfoType = pBhli->HighLayerInfoType;
  1161. pSockAddrAtm->satm_bhli.HighLayerInfoLength = pBhli->HighLayerInfoLength;
  1162. ATMSP_COPY_MEM(pSockAddrAtm->satm_bhli.HighLayerInfo,
  1163. pBhli->HighLayerInfo,
  1164. 8);
  1165. }
  1166. if (pBlli == NULL)
  1167. {
  1168. pSockAddrAtm->satm_blli.Layer2Protocol = SAP_FIELD_ABSENT;
  1169. pSockAddrAtm->satm_blli.Layer3Protocol = SAP_FIELD_ABSENT;
  1170. }
  1171. else
  1172. {
  1173. pSockAddrAtm->satm_blli.Layer2Protocol = pBlli->Layer2Protocol;
  1174. pSockAddrAtm->satm_blli.Layer2UserSpecifiedProtocol = pBlli->Layer2UserSpecifiedProtocol;
  1175. pSockAddrAtm->satm_blli.Layer3Protocol = pBlli->Layer3Protocol;
  1176. pSockAddrAtm->satm_blli.Layer3UserSpecifiedProtocol = pBlli->Layer3UserSpecifiedProtocol;
  1177. pSockAddrAtm->satm_blli.Layer3IPI = pBlli->Layer3IPI;
  1178. ATMSP_COPY_MEM(pSockAddrAtm->satm_blli.SnapId,
  1179. pBlli->SnapId,
  1180. 5);
  1181. }
  1182. //
  1183. // Fill in generic QoS.
  1184. //
  1185. pQoS = (ATMSP_QOS *)pTdiQoS;
  1186. if (IsOutgoingCall)
  1187. {
  1188. pQoS->SendingFlowSpec = pCallMgrParameters->Transmit;
  1189. pQoS->ReceivingFlowSpec = pCallMgrParameters->Receive;
  1190. }
  1191. else
  1192. {
  1193. pQoS->SendingFlowSpec = pCallMgrParameters->Transmit;
  1194. pQoS->ReceivingFlowSpec = pCallMgrParameters->Receive;
  1195. }
  1196. //
  1197. // Fill in the provider-specific part with other Info Elements.
  1198. //
  1199. pQoS->ProviderSpecific.buf = (CHAR *)((PUCHAR)pQoS + sizeof(ATMSP_QOS));
  1200. pQoS->ProviderSpecific.len = TotalIeLength;
  1201. ATMSP_COPY_MEM(pQoS->ProviderSpecific.buf, &(pAtmCallParameters->InfoElements[0]), TotalIeLength);
  1202. //
  1203. // All done. Fill in return values.
  1204. //
  1205. *ppTdiInfo = pTdiInfo;
  1206. *ppTdiQoS = pTdiQoS;
  1207. *pTdiQoSLength = sizeof(ATMSP_QOS) + TotalIeLength;
  1208. *pAfSpTdiOptionsContext = pTdiInfo;
  1209. RWANDEBUGP(DL_LOUD, DC_CONNECT,
  1210. ("pCallMgrParams %x, TotalIeLength %d\n", pCallMgrParameters, TotalIeLength));
  1211. RWANDEBUGP(DL_LOUD, DC_CONNECT,
  1212. ("Transmit: SvcType %d, MaxSdu %d, Peak %d, TokenRt %d\n",
  1213. pQoS->SendingFlowSpec.ServiceType,
  1214. pQoS->SendingFlowSpec.MaxSduSize,
  1215. pQoS->SendingFlowSpec.PeakBandwidth,
  1216. pQoS->SendingFlowSpec.TokenRate));
  1217. RWANDEBUGP(DL_LOUD, DC_CONNECT,
  1218. ("Receive: SvcType %d, MaxSdu %d, Peak %d, TokenRt %d\n",
  1219. pQoS->ReceivingFlowSpec.ServiceType,
  1220. pQoS->ReceivingFlowSpec.MaxSduSize,
  1221. pQoS->ReceivingFlowSpec.PeakBandwidth,
  1222. pQoS->ReceivingFlowSpec.TokenRate));
  1223. break;
  1224. }
  1225. while (FALSE);
  1226. return (RWanStatus);
  1227. }
  1228. RWAN_STATUS
  1229. RWanAtmSpUpdateTdiOptions(
  1230. IN RWAN_HANDLE AfSpAFContext,
  1231. IN RWAN_HANDLE AfSpConnContext,
  1232. IN ULONG CallFlags,
  1233. IN PCO_CALL_PARAMETERS pCallParameters,
  1234. IN OUT PTDI_CONNECTION_INFORMATION * ppTdiInfo,
  1235. IN OUT PUCHAR pTdiQoS,
  1236. IN OUT PULONG pTdiQoSLength
  1237. )
  1238. /*++
  1239. Routine Description:
  1240. Entry point called to update TDI call parameters from NDIS parameters.
  1241. This is typically on completion of an outgoing call.
  1242. Right now, all we do is save the VPI/VCI for the connection to support
  1243. SIO_GET_ATM_CONNECTION_ID.
  1244. Arguments:
  1245. AfSpAFContext - Points to our AF block
  1246. AfSpConnContext - Points to our CONN block
  1247. CallFlags - Call direction and other info
  1248. pCallParameters - Points to NDIS style Call parameters
  1249. ppTdiInfo - Points to pointer to generic TDI Connection Information
  1250. pTdiQoS - Points to generic TDI QOS structure
  1251. pTdiQoSLength - length of the above
  1252. Return Value:
  1253. RWAN_STATUS_SUCCESS if the update was successful, RWAN_STATUS_XXX
  1254. error code otherwise.
  1255. --*/
  1256. {
  1257. RWAN_STATUS RWanStatus;
  1258. PATMSP_AF_BLOCK pAfBlock;
  1259. PATMSP_CONN_BLOCK pConnBlock;
  1260. PATM_MEDIA_PARAMETERS pAtmMediaParameters;
  1261. ATMSP_QOS * pQoS;
  1262. RWanStatus = RWAN_STATUS_SUCCESS;
  1263. pAfBlock = (PATMSP_AF_BLOCK)AfSpAFContext;
  1264. pConnBlock = (PATMSP_CONN_BLOCK)AfSpConnContext;
  1265. ATMSP_ASSERT(pAfBlock != NULL);
  1266. ATMSP_ASSERT(pConnBlock != NULL);
  1267. ATMSP_ASSERT(pCallParameters != NULL);
  1268. do
  1269. {
  1270. if (pCallParameters->MediaParameters)
  1271. {
  1272. pAtmMediaParameters = (PATM_MEDIA_PARAMETERS)
  1273. &(pCallParameters->MediaParameters->MediaSpecific.Parameters[0]);
  1274. pConnBlock->ConnectionId.DeviceNumber = AtmSpAfBlockToDeviceNumber(pAfBlock);
  1275. pConnBlock->ConnectionId.Vpi = pAtmMediaParameters->ConnectionId.Vpi;
  1276. pConnBlock->ConnectionId.Vci = pAtmMediaParameters->ConnectionId.Vci;
  1277. RWANDEBUGP(DL_VERY_LOUD, DC_CONNECT,
  1278. ("AtmSP: UpdateTdi: VPI %d, VCI %d\n",
  1279. pConnBlock->ConnectionId.Vpi,
  1280. pConnBlock->ConnectionId.Vci));
  1281. }
  1282. if (pTdiQoS && (*pTdiQoSLength >= sizeof(ATMSP_QOS)))
  1283. {
  1284. pQoS = (PATMSP_QOS)pTdiQoS;
  1285. pQoS->SendingFlowSpec = pCallParameters->CallMgrParameters->Transmit;
  1286. pQoS->ReceivingFlowSpec = pCallParameters->CallMgrParameters->Receive;
  1287. pQoS->ProviderSpecific.len = 0; // for now
  1288. }
  1289. break;
  1290. }
  1291. while (FALSE);
  1292. return (RWanStatus);
  1293. }
  1294. VOID
  1295. RWanAtmSpReturnTdiOptions(
  1296. IN RWAN_HANDLE AfSpAFContext,
  1297. IN RWAN_HANDLE AfSpTdiOptionsContext
  1298. )
  1299. /*++
  1300. Routine Description:
  1301. This entry point is called when core Null Transport is done with
  1302. a TDI QOS structure we'd given it via RWanAtmSpNdis2TdiOptions.
  1303. We simply free the memory used for the structure.
  1304. Arguments:
  1305. AfSpAFContext - Points to our AF block
  1306. AfSpTdiOptionsContext - Points to the structure we had allocated
  1307. Return Value:
  1308. None
  1309. --*/
  1310. {
  1311. UNREFERENCED_PARAMETER(AfSpAFContext);
  1312. ATMSP_FREE_MEM(AfSpTdiOptionsContext);
  1313. }
  1314. TA_ADDRESS *
  1315. RWanAtmSpGetValidTdiAddress(
  1316. IN RWAN_HANDLE AfSpContext,
  1317. IN TRANSPORT_ADDRESS UNALIGNED * pAddressList,
  1318. IN ULONG AddrListLength
  1319. )
  1320. /*++
  1321. Routine Description:
  1322. Go through the list of transport addresses given, and return the
  1323. first valid address found.
  1324. Arguments:
  1325. Return Value:
  1326. Pointer to the first valid address if found, else NULL.
  1327. --*/
  1328. {
  1329. TA_ADDRESS * pTransportAddress;
  1330. INT i;
  1331. BOOLEAN Found;
  1332. ULONG_PTR EndOfAddrList;
  1333. Found = FALSE;
  1334. EndOfAddrList = (ULONG_PTR)pAddressList + AddrListLength;
  1335. RWANDEBUGP(DL_LOUD, DC_WILDCARD,
  1336. ("AtmSpGetValidAddr: pAddrList x%x, Length %d\n",
  1337. pAddressList, AddrListLength));
  1338. do
  1339. {
  1340. if (AddrListLength < sizeof(*pAddressList))
  1341. {
  1342. break;
  1343. }
  1344. pTransportAddress = (TA_ADDRESS *) pAddressList->Address;
  1345. for (i = 0; i < pAddressList->TAAddressCount; i++)
  1346. {
  1347. ULONG_PTR EndOfAddress;
  1348. //
  1349. // Check that we aren't falling off the end of the supplied
  1350. // buffer.
  1351. //
  1352. if ((ULONG_PTR)pTransportAddress < (ULONG_PTR)pAddressList ||
  1353. (ULONG_PTR)pTransportAddress >= EndOfAddrList)
  1354. {
  1355. break;
  1356. }
  1357. EndOfAddress = (ULONG_PTR)pTransportAddress +
  1358. sizeof(TA_ADDRESS) - 1 +
  1359. sizeof(ATMSP_SOCKADDR_ATM);
  1360. if (EndOfAddress < (ULONG_PTR)pAddressList ||
  1361. EndOfAddress >= EndOfAddrList)
  1362. {
  1363. RWANDEBUGP(DL_ERROR, DC_WILDCARD,
  1364. ("AtmSpGetValidAddr: EndOfAddr x%x, EndOfAddrList x%x\n",
  1365. EndOfAddress, EndOfAddrList));
  1366. break;
  1367. }
  1368. if (pTransportAddress->AddressType == TDI_ADDRESS_TYPE_ATM)
  1369. {
  1370. if (pTransportAddress->AddressLength >= sizeof(ATMSP_SOCKADDR_ATM))
  1371. {
  1372. Found = TRUE;
  1373. break;
  1374. }
  1375. }
  1376. pTransportAddress = (TA_ADDRESS *)
  1377. ((PUCHAR)pTransportAddress +
  1378. sizeof(TA_ADDRESS) - 1 +
  1379. pTransportAddress->AddressLength);
  1380. }
  1381. }
  1382. while (FALSE);
  1383. if (!Found)
  1384. {
  1385. pTransportAddress = NULL;
  1386. }
  1387. RWANDEBUGP(DL_LOUD, DC_WILDCARD,
  1388. ("AtmSpGetValidAddr returning x%x\n", pTransportAddress));
  1389. return (pTransportAddress);
  1390. }
  1391. BOOLEAN
  1392. RWanAtmSpIsNullAddress(
  1393. IN RWAN_HANDLE AfSpContext,
  1394. IN TA_ADDRESS * pTransportAddress
  1395. )
  1396. /*++
  1397. Routine Description:
  1398. Check if the given transport address contains a NULL ATM address.
  1399. A NULL ATM address is one that cannot be used in an NDIS SAP.
  1400. Arguments:
  1401. AfSpContext - Points to our Global context
  1402. pTransportAddress - Points to a TDI transport address
  1403. Return Value:
  1404. TRUE if the given address is a NULL ATM address, FALSE otherwise.
  1405. --*/
  1406. {
  1407. ATMSP_SOCKADDR_ATM UNALIGNED * pSockAddrAtm;
  1408. ATM_ADDRESS UNALIGNED * pAtmAddress;
  1409. BOOLEAN IsNullAddress;
  1410. UNREFERENCED_PARAMETER(AfSpContext);
  1411. ATMSP_ASSERT(pTransportAddress->AddressLength >= sizeof(ATMSP_SOCKADDR_ATM));
  1412. pSockAddrAtm = TA_POINTER_TO_ATM_ADDR_POINTER(pTransportAddress->Address);
  1413. pAtmAddress = &pSockAddrAtm->satm_number;
  1414. return (pAtmAddress->AddressType == SAP_FIELD_ABSENT);
  1415. }
  1416. RWAN_STATUS
  1417. RWanAtmSpTdi2NdisSap(
  1418. IN RWAN_HANDLE AfSpContext,
  1419. IN USHORT TdiAddressType,
  1420. IN USHORT TdiAddressLength,
  1421. IN PVOID pTdiAddress,
  1422. OUT PCO_SAP * ppCoSap
  1423. )
  1424. /*++
  1425. Routine Description:
  1426. Convert an ATM SAP in TDI format to NDIS format.
  1427. Arguments:
  1428. AfSpContext - Points to our Global context
  1429. TdiAddressType - Should be TDI_ADDRESS_TYPE_ATM
  1430. TdiAddressLength - Should be enough to hold SOCKADDR_ATM
  1431. pTdiAddress - Points to TDI address.
  1432. ppCoSap - Place to return pointer to allocated CO_SAP structure.
  1433. Return Value:
  1434. RWAN_STATUS_SUCCESS if an NDIS ATM SAP was filled in successfully,
  1435. RWAN_STATUS_XXX error code otherwise.
  1436. --*/
  1437. {
  1438. RWAN_STATUS RWanStatus;
  1439. PCO_SAP pCoSap;
  1440. PATM_SAP pAtmSap;
  1441. ATMSP_SOCKADDR_ATM UNALIGNED *pSockAddrAtm;
  1442. ATM_ADDRESS UNALIGNED * pTdiAtmAddress;
  1443. ULONG SapSize;
  1444. UNREFERENCED_PARAMETER(AfSpContext);
  1445. ATMSP_ASSERT(TdiAddressType == TDI_ADDRESS_TYPE_ATM);
  1446. ATMSP_ASSERT(TdiAddressLength >= sizeof(ATMSP_SOCKADDR_ATM));
  1447. pSockAddrAtm = TA_POINTER_TO_ATM_ADDR_POINTER(pTdiAddress);
  1448. pTdiAtmAddress = &(pSockAddrAtm->satm_number);
  1449. RWANDEBUGPATMADDR(DL_LOUD, DC_CONNECT,
  1450. "AtmSpTdi2NdisSap: remote addr: ", pTdiAtmAddress);
  1451. SapSize = sizeof(CO_SAP) + sizeof(ATM_SAP) + sizeof(ATM_ADDRESS);
  1452. ATMSP_ALLOC_MEM(pCoSap, CO_SAP, sizeof(CO_SAP) + sizeof(ATM_SAP) + sizeof(ATM_ADDRESS));
  1453. if (pCoSap != NULL)
  1454. {
  1455. ATMSP_ZERO_MEM(pCoSap, SapSize);
  1456. pCoSap->SapType = SAP_TYPE_NSAP;
  1457. pCoSap->SapLength = sizeof(ATM_SAP) + sizeof(ATM_ADDRESS);
  1458. pAtmSap = (PATM_SAP)&(pCoSap->Sap[0]);
  1459. //
  1460. // Copy in the BLLI part. We can't use a simple mem copy because
  1461. // the Winsock 2 definition of BLLI in sockaddr_atm is different
  1462. // from the complete BLLI IE.
  1463. //
  1464. pAtmSap->Blli.Layer2Protocol = pSockAddrAtm->satm_blli.Layer2Protocol;
  1465. pAtmSap->Blli.Layer2UserSpecifiedProtocol = pSockAddrAtm->satm_blli.Layer2UserSpecifiedProtocol;
  1466. pAtmSap->Blli.Layer3Protocol = pSockAddrAtm->satm_blli.Layer3Protocol;
  1467. pAtmSap->Blli.Layer3UserSpecifiedProtocol = pSockAddrAtm->satm_blli.Layer3UserSpecifiedProtocol;
  1468. pAtmSap->Blli.Layer3IPI = pSockAddrAtm->satm_blli.Layer3IPI;
  1469. ATMSP_COPY_MEM(pAtmSap->Blli.SnapId,
  1470. pSockAddrAtm->satm_blli.SnapId,
  1471. 5);
  1472. //
  1473. // Copy in the BHLI part.
  1474. //
  1475. pAtmSap->Bhli.HighLayerInfoType = pSockAddrAtm->satm_bhli.HighLayerInfoType;
  1476. pAtmSap->Bhli.HighLayerInfoLength = pSockAddrAtm->satm_bhli.HighLayerInfoLength;
  1477. ATMSP_COPY_MEM(pAtmSap->Bhli.HighLayerInfo,
  1478. pSockAddrAtm->satm_bhli.HighLayerInfo,
  1479. 8);
  1480. pAtmSap->NumberOfAddresses = 1;
  1481. ATMSP_COPY_MEM(pAtmSap->Addresses, pTdiAtmAddress, sizeof(ATM_ADDRESS));
  1482. //
  1483. // Convert the Address type from Winsock 2 definition to NDIS definitions
  1484. //
  1485. {
  1486. ATM_ADDRESS UNALIGNED * pNdisAtmAddress;
  1487. pNdisAtmAddress = (ATM_ADDRESS UNALIGNED *)pAtmSap->Addresses;
  1488. switch (pTdiAtmAddress->AddressType)
  1489. {
  1490. case SOCKATM_E164:
  1491. pNdisAtmAddress->AddressType = ATM_E164;
  1492. break;
  1493. case SOCKATM_NSAP:
  1494. pNdisAtmAddress->AddressType = ATM_NSAP;
  1495. break;
  1496. default:
  1497. //
  1498. // Possibly SAP_FIELD_XXX; leave it as it is.
  1499. //
  1500. break;
  1501. }
  1502. }
  1503. RWanStatus = RWAN_STATUS_SUCCESS;
  1504. }
  1505. else
  1506. {
  1507. RWanStatus = RWAN_STATUS_RESOURCES;
  1508. }
  1509. *ppCoSap = pCoSap;
  1510. return (RWanStatus);
  1511. }
  1512. VOID
  1513. RWanAtmSpReturnNdisSap(
  1514. IN RWAN_HANDLE AfSpContext,
  1515. IN PCO_SAP pCoSap
  1516. )
  1517. /*++
  1518. Routine Description:
  1519. This entry point is called to return an NDIS SAP structure we'd
  1520. allocated in RWanAtmSpTdi2NdisSap
  1521. Arguments:
  1522. AfSpContext - Points to our Global context
  1523. pCoSap - Points to CO_SAP structure to be freed.
  1524. Return Value:
  1525. None
  1526. --*/
  1527. {
  1528. UNREFERENCED_PARAMETER(AfSpContext);
  1529. ATMSP_FREE_MEM(pCoSap);
  1530. return;
  1531. }
  1532. VOID
  1533. RWanAtmSpDeregNdisAFComplete(
  1534. IN RWAN_STATUS RWanStatus,
  1535. IN RWAN_HANDLE AfSpContext
  1536. )
  1537. /*++
  1538. Routine Description:
  1539. Entry point to complete a previous call we had made to
  1540. RWanAfSpDeregisterNdisAF that had pended.
  1541. Arguments:
  1542. RWanStatus - Completion status
  1543. AfSpContext - Points to our Global context
  1544. Return Value:
  1545. None
  1546. --*/
  1547. {
  1548. UNREFERENCED_PARAMETER(RWanStatus);
  1549. UNREFERENCED_PARAMETER(AfSpContext);
  1550. // XXX: Do more
  1551. return;
  1552. }
  1553. VOID
  1554. RWanAtmSpDeregTdiProtoComplete(
  1555. IN RWAN_STATUS RWanStatus,
  1556. IN RWAN_HANDLE AfSpContext
  1557. )
  1558. /*++
  1559. Routine Description:
  1560. Entry point to complete a previous call we had made to
  1561. RWanAfSpDeregisterTdiProtocol that had pended.
  1562. Arguments:
  1563. RWanStatus - Completion status
  1564. AfSpContext - Points to our Global context
  1565. Return Value:
  1566. None
  1567. --*/
  1568. {
  1569. UNREFERENCED_PARAMETER(RWanStatus);
  1570. UNREFERENCED_PARAMETER(AfSpContext);
  1571. ATMSP_ASSERT(FALSE); // XXX: Do more
  1572. return;
  1573. }
  1574. PATMSP_AF_BLOCK
  1575. AtmSpDeviceNumberToAfBlock(
  1576. IN UINT DeviceNumber
  1577. )
  1578. /*++
  1579. Routine Description:
  1580. Return the AF Block corresponding to the given Device Number.
  1581. The AF blocks are assumed to be numbered 0, 1, 2 ...
  1582. Arguments:
  1583. DeviceNumber - what we are looking for
  1584. Return Value:
  1585. Pointer to AF Block if found, else NULL.
  1586. --*/
  1587. {
  1588. PATMSP_AF_BLOCK pAfBlock;
  1589. PLIST_ENTRY pAfEntry;
  1590. pAfBlock = NULL;
  1591. for (pAfEntry = pAtmSpGlobal->AfList.Flink;
  1592. pAfEntry != &(pAtmSpGlobal->AfList);
  1593. pAfEntry = pAfEntry->Flink)
  1594. {
  1595. if (DeviceNumber == 0)
  1596. {
  1597. pAfBlock = CONTAINING_RECORD(pAfEntry, ATMSP_AF_BLOCK, AfBlockLink);
  1598. break;
  1599. }
  1600. DeviceNumber--;
  1601. }
  1602. return (pAfBlock);
  1603. }
  1604. UINT
  1605. AtmSpAfBlockToDeviceNumber(
  1606. IN PATMSP_AF_BLOCK pAfBlock
  1607. )
  1608. /*++
  1609. Routine Description:
  1610. Return the device number corresponding to the specified AF block.
  1611. Arguments:
  1612. pAfBlock - Pointer to AF block
  1613. Return Value:
  1614. 0-based device number.
  1615. --*/
  1616. {
  1617. PLIST_ENTRY pAfEntry;
  1618. PATMSP_AF_BLOCK pAfBlockEntry;
  1619. UINT DeviceNumber = (UINT)-1;
  1620. for (pAfEntry = pAtmSpGlobal->AfList.Flink;
  1621. pAfEntry != &(pAtmSpGlobal->AfList);
  1622. pAfEntry = pAfEntry->Flink)
  1623. {
  1624. DeviceNumber++;
  1625. pAfBlockEntry = CONTAINING_RECORD(pAfEntry, ATMSP_AF_BLOCK, AfBlockLink);
  1626. if (pAfBlockEntry == pAfBlock)
  1627. {
  1628. break;
  1629. }
  1630. }
  1631. return (DeviceNumber);
  1632. }
  1633. RWAN_STATUS
  1634. AtmSpDoAdapterRequest(
  1635. IN PATMSP_AF_BLOCK pAfBlock,
  1636. IN NDIS_REQUEST_TYPE RequestType,
  1637. IN NDIS_OID Oid,
  1638. IN PVOID pBuffer,
  1639. IN ULONG BufferLength
  1640. )
  1641. /*++
  1642. Routine Description:
  1643. Send an NDIS Request to the adapter and wait till it completes.
  1644. Arguments:
  1645. pAfBlock - Points to our NDIS AF open context block
  1646. RequestType - Set/Query
  1647. Oid - Object under question
  1648. pBuffer - Pointer to buffer that contains/is to contain info.
  1649. BufferLength - Length of above
  1650. Return Value:
  1651. RWAN_STATUS - RWAN_STATUS_SUCCESS if we succeeded, RWAN_STATUS_FAILURE if not.
  1652. --*/
  1653. {
  1654. PATMSP_EVENT pEvent;
  1655. RWAN_STATUS RWanStatus;
  1656. ATMSP_ALLOC_MEM(pEvent, ATMSP_EVENT, sizeof(ATMSP_EVENT));
  1657. if (pEvent == NULL)
  1658. {
  1659. return (RWAN_STATUS_RESOURCES);
  1660. }
  1661. ATMSP_INIT_EVENT_STRUCT(pEvent);
  1662. RWanStatus = RWanAfSpSendAdapterRequest(
  1663. pAfBlock->RWanAFHandle,
  1664. (RWAN_HANDLE)pEvent,
  1665. RequestType,
  1666. Oid,
  1667. pBuffer,
  1668. BufferLength
  1669. );
  1670. if (RWanStatus == RWAN_STATUS_PENDING)
  1671. {
  1672. RWanStatus = ATMSP_WAIT_ON_EVENT_STRUCT(pEvent);
  1673. }
  1674. ATMSP_FREE_MEM(pEvent);
  1675. return (RWanStatus);
  1676. }
  1677. RWAN_STATUS
  1678. AtmSpDoCallManagerRequest(
  1679. IN PATMSP_AF_BLOCK pAfBlock,
  1680. IN NDIS_REQUEST_TYPE RequestType,
  1681. IN NDIS_OID Oid,
  1682. IN PVOID pBuffer,
  1683. IN ULONG BufferLength
  1684. )
  1685. /*++
  1686. Routine Description:
  1687. Send an NDIS Request to the Call Manager and wait till it completes.
  1688. Arguments:
  1689. pAfBlock - Points to our NDIS AF open context block
  1690. RequestType - Set/Query
  1691. Oid - Object under question
  1692. pBuffer - Pointer to buffer that contains/is to contain info.
  1693. BufferLength - Length of above
  1694. Return Value:
  1695. RWAN_STATUS - RWAN_STATUS_SUCCESS if we succeeded, RWAN_STATUS_FAILURE if not.
  1696. --*/
  1697. {
  1698. PATMSP_EVENT pEvent;
  1699. RWAN_STATUS RWanStatus;
  1700. ATMSP_ALLOC_MEM(pEvent, ATMSP_EVENT, sizeof(ATMSP_EVENT));
  1701. if (pEvent == NULL)
  1702. {
  1703. return (RWAN_STATUS_RESOURCES);
  1704. }
  1705. ATMSP_INIT_EVENT_STRUCT(pEvent);
  1706. RWanStatus = RWanAfSpSendAfRequest(
  1707. pAfBlock->RWanAFHandle,
  1708. (RWAN_HANDLE)pEvent,
  1709. RequestType,
  1710. Oid,
  1711. pBuffer,
  1712. BufferLength
  1713. );
  1714. if (RWanStatus == RWAN_STATUS_PENDING)
  1715. {
  1716. RWanStatus = ATMSP_WAIT_ON_EVENT_STRUCT(pEvent);
  1717. }
  1718. ATMSP_FREE_MEM(pEvent);
  1719. return (RWanStatus);
  1720. }
  1721. ATMSP_SOCKADDR_ATM UNALIGNED *
  1722. AtmSpGetSockAtmAddress(
  1723. IN PVOID pTdiAddressList,
  1724. IN ULONG AddrListLength
  1725. )
  1726. /*++
  1727. Routine Description:
  1728. Look for a valid SOCKADDR_ATM address in the given TDI address list.
  1729. Arguments:
  1730. pTdiAddressList - Points to list of TDI addresses.
  1731. AddrListLength - Length of list
  1732. Return Value:
  1733. Pointer to valid address if it exists, else NULL.
  1734. --*/
  1735. {
  1736. TA_ADDRESS * pTransportAddress;
  1737. ATMSP_SOCKADDR_ATM UNALIGNED * pSockAddrAtm;
  1738. pTransportAddress = RWanAtmSpGetValidTdiAddress(
  1739. (RWAN_HANDLE)&AtmSpGlobal,
  1740. pTdiAddressList,
  1741. AddrListLength
  1742. );
  1743. if (pTransportAddress != NULL)
  1744. {
  1745. pSockAddrAtm = TA_POINTER_TO_ATM_ADDR_POINTER(pTransportAddress->Address);
  1746. }
  1747. else
  1748. {
  1749. pSockAddrAtm = NULL;
  1750. }
  1751. return (pSockAddrAtm);
  1752. }
  1753. VOID
  1754. RWanAtmSpAdapterRequestComplete(
  1755. IN NDIS_STATUS Status,
  1756. IN RWAN_HANDLE AfSpAFContext,
  1757. IN RWAN_HANDLE AfSpReqContext,
  1758. IN NDIS_REQUEST_TYPE RequestType,
  1759. IN NDIS_OID Oid,
  1760. IN PVOID pBuffer,
  1761. IN ULONG BufferLength
  1762. )
  1763. /*++
  1764. Routine Description:
  1765. This entry point is called to signify completion of a previous
  1766. NDIS request we'd sent to the miniport by calling RWanAfSpSendAdapterRequest.
  1767. Arguments:
  1768. Status - Status of the query
  1769. AfSpAFContext - Points to our NDIS AF open context block
  1770. AfSpReqContext - Points to Event structure
  1771. RequestType - Query/Set
  1772. Oid - Object that we were querying/setting
  1773. pBuffer - Pointer to object value
  1774. BufferLength - Length of the above
  1775. Return Value:
  1776. None
  1777. --*/
  1778. {
  1779. PATMSP_EVENT pEvent;
  1780. RWAN_STATUS RWanStatus;
  1781. pEvent = (PATMSP_EVENT) AfSpReqContext;
  1782. RWanStatus = ((Status == NDIS_STATUS_SUCCESS)? RWAN_STATUS_SUCCESS: RWAN_STATUS_FAILURE);
  1783. ATMSP_SIGNAL_EVENT_STRUCT(pEvent, RWanStatus);
  1784. return;
  1785. }
  1786. VOID
  1787. RWanAtmSpAfRequestComplete(
  1788. IN NDIS_STATUS Status,
  1789. IN RWAN_HANDLE AfSpAFContext,
  1790. IN RWAN_HANDLE AfSpReqContext,
  1791. IN NDIS_REQUEST_TYPE RequestType,
  1792. IN NDIS_OID Oid,
  1793. IN PVOID pBuffer,
  1794. IN ULONG BufferLength
  1795. )
  1796. /*++
  1797. Routine Description:
  1798. This entry point is called to signify completion of a previous
  1799. NDIS request we'd sent to the Call Mgr by calling RWanAfSpSendAfRequest.
  1800. Arguments:
  1801. Status - Status of the query
  1802. AfSpAFContext - Points to our NDIS AF open context block
  1803. AfSpReqContext - Points to Event structure
  1804. RequestType - Query/Set
  1805. Oid - Object that we were querying/setting
  1806. pBuffer - Pointer to object value
  1807. BufferLength - Length of the above
  1808. Return Value:
  1809. None
  1810. --*/
  1811. {
  1812. PATMSP_EVENT pEvent;
  1813. RWAN_STATUS RWanStatus;
  1814. pEvent = (PATMSP_EVENT) AfSpReqContext;
  1815. RWanStatus = ((Status == NDIS_STATUS_SUCCESS)? RWAN_STATUS_SUCCESS: RWAN_STATUS_FAILURE);
  1816. ATMSP_SIGNAL_EVENT_STRUCT(pEvent, RWanStatus);
  1817. return;
  1818. }
  1819. VOID
  1820. RWanAtmSpDeregTdiProtocolComplete(
  1821. IN RWAN_STATUS RWanStatus,
  1822. IN RWAN_HANDLE AfSpTdiProtocolContext
  1823. )
  1824. /*++
  1825. Routine Description:
  1826. Completion of our pended call to RWanAfSpDeregisterTdiProtocol.
  1827. Not expected because we don't call this.
  1828. Arguments:
  1829. RWanStatus - Final status of deregistering the TDI protocol.
  1830. AfSpTdiProtocolContext - Points to our global struct.
  1831. Return Value:
  1832. None
  1833. --*/
  1834. {
  1835. ATMSP_ASSERT(FALSE);
  1836. return;
  1837. }
  1838. VOID
  1839. AtmSpPrepareDefaultQoS(
  1840. IN PATMSP_AF_BLOCK pAfBlock
  1841. )
  1842. /*++
  1843. Routine Description:
  1844. Prepare the default QOS structure to be used for outgoing calls
  1845. on this AF.
  1846. Arguments:
  1847. pAfBlock - Points to our NDIS AF open context block
  1848. Return Value:
  1849. None
  1850. --*/
  1851. {
  1852. ATMSP_QOS * pQoS;
  1853. FLOWSPEC * pSendFlowSpec;
  1854. FLOWSPEC * pRecvFlowSpec;
  1855. pQoS = &pAfBlock->DefaultQoS;
  1856. ATMSP_ZERO_MEM(pQoS, sizeof(ATMSP_QOS));
  1857. pSendFlowSpec = &pQoS->SendingFlowSpec;
  1858. pRecvFlowSpec = &pQoS->ReceivingFlowSpec;
  1859. pRecvFlowSpec->ServiceType =
  1860. pSendFlowSpec->ServiceType = SERVICETYPE_BESTEFFORT;
  1861. //
  1862. // The line rates are in units of 100s of bits/second.
  1863. // Convert to bytes/second.
  1864. //
  1865. pRecvFlowSpec->TokenRate = (pAfBlock->LineRate.Inbound * 100) / 8;
  1866. pSendFlowSpec->TokenRate = (pAfBlock->LineRate.Outbound * 100) / 8;
  1867. pRecvFlowSpec->PeakBandwidth = pRecvFlowSpec->TokenRate;
  1868. pSendFlowSpec->PeakBandwidth = pSendFlowSpec->TokenRate;
  1869. pRecvFlowSpec->MaxSduSize =
  1870. pSendFlowSpec->MaxSduSize = pAfBlock->MaxPacketSize;
  1871. pAfBlock->DefaultQoSLength = sizeof(ATMSP_QOS);
  1872. return;
  1873. }
  1874. RWAN_STATUS
  1875. RWanAtmSpQueryGlobalInfo(
  1876. IN RWAN_HANDLE AfSpContext,
  1877. IN PVOID pInputBuffer,
  1878. IN ULONG InputBufferLength,
  1879. IN PVOID pOutputBuffer,
  1880. IN OUT PULONG pOutputBufferLength
  1881. )
  1882. /*++
  1883. Routine Description:
  1884. Process a media-specific IOCTL to query information from the helper DLL.
  1885. Arguments:
  1886. AfSpContext - Points to our Global context
  1887. pInputBuffer - Input information
  1888. InputBufferLength - Length of the above
  1889. pOutputBuffer - Points to buffer for output
  1890. pOutputBufferLength - On entry, contains size of output buffer. On return,
  1891. we fill this with the actual bytes returned.
  1892. Return Value:
  1893. RWAN_STATUS_SUCCESS if we processed the IOCTL successfully
  1894. RWAN_STATUS_XXX to indicate any failure.
  1895. --*/
  1896. {
  1897. PATM_QUERY_INFORMATION_EX pQueryInfo;
  1898. RWAN_STATUS RWanStatus;
  1899. ULONG Info;
  1900. PUCHAR pSrcBuffer = (PUCHAR)&Info;
  1901. ULONG BufferLength;
  1902. PATMSP_AF_BLOCK pAfBlock;
  1903. UINT DeviceNumber;
  1904. PCO_ADDRESS_LIST pAddrList = NULL;
  1905. RWANDEBUGP(DL_LOUD, DC_DISPATCH,
  1906. ("AtmSpQueryInfo: InBuf x%x/%d, OutBuf x%x/%d\n",
  1907. pInputBuffer,
  1908. InputBufferLength,
  1909. pOutputBuffer,
  1910. *pOutputBufferLength));
  1911. RWanStatus = RWAN_STATUS_SUCCESS;
  1912. do
  1913. {
  1914. //
  1915. // See if the input buffer is big enough.
  1916. //
  1917. if (InputBufferLength < sizeof(ATM_QUERY_INFORMATION_EX))
  1918. {
  1919. RWanStatus = RWAN_STATUS_RESOURCES;
  1920. break;
  1921. }
  1922. pQueryInfo = (PATM_QUERY_INFORMATION_EX)pInputBuffer;
  1923. switch (pQueryInfo->ObjectId)
  1924. {
  1925. case ATMSP_OID_NUMBER_OF_DEVICES:
  1926. BufferLength = sizeof(ULONG);
  1927. Info = pAtmSpGlobal->AfListSize;
  1928. break;
  1929. case ATMSP_OID_ATM_ADDRESS:
  1930. //
  1931. // Get the device number being queried.
  1932. //
  1933. if (pQueryInfo->ContextLength < sizeof(UINT))
  1934. {
  1935. RWanStatus = RWAN_STATUS_RESOURCES;
  1936. break;
  1937. }
  1938. DeviceNumber = *((PUINT)&pQueryInfo->Context[0]);
  1939. //
  1940. // Get the AF block for the device # being queried.
  1941. //
  1942. pAfBlock = AtmSpDeviceNumberToAfBlock(DeviceNumber);
  1943. if (pAfBlock == NULL)
  1944. {
  1945. RWanStatus = RWAN_STATUS_BAD_ADDRESS;
  1946. break;
  1947. }
  1948. ATMSP_ALLOC_MEM(pAddrList,
  1949. CO_ADDRESS_LIST,
  1950. sizeof(CO_ADDRESS_LIST)+sizeof(CO_ADDRESS)+sizeof(ATM_ADDRESS));
  1951. if (pAddrList == NULL)
  1952. {
  1953. RWanStatus = RWAN_STATUS_RESOURCES;
  1954. break;
  1955. }
  1956. RWanStatus = AtmSpDoCallManagerRequest(
  1957. pAfBlock,
  1958. NdisRequestQueryInformation,
  1959. OID_CO_GET_ADDRESSES,
  1960. pAddrList,
  1961. sizeof(CO_ADDRESS_LIST)+sizeof(CO_ADDRESS)+sizeof(ATM_ADDRESS)
  1962. );
  1963. if ((RWanStatus == RWAN_STATUS_SUCCESS) &&
  1964. (pAddrList->NumberOfAddresses > 0))
  1965. {
  1966. ATM_ADDRESS UNALIGNED * pAtmAddress;
  1967. pSrcBuffer = (PUCHAR)&pAddrList->AddressList.Address[0];
  1968. //
  1969. // Fix the address type for Winsock2.
  1970. //
  1971. pAtmAddress = (ATM_ADDRESS UNALIGNED *)pSrcBuffer;
  1972. pAtmAddress->AddressType = ((pAtmAddress->AddressType == ATM_E164)?
  1973. SOCKATM_E164: SOCKATM_NSAP);
  1974. BufferLength = sizeof(ATM_ADDRESS);
  1975. }
  1976. else
  1977. {
  1978. if (RWanStatus == RWAN_STATUS_SUCCESS)
  1979. {
  1980. RWanStatus = RWAN_STATUS_FAILURE;
  1981. }
  1982. }
  1983. RWANDEBUGP(DL_LOUD, DC_DISPATCH,
  1984. ("AtmSpQueryInfo: GetAddr: Status %x, pSrc %x, BufLen %d\n",
  1985. RWanStatus, pSrcBuffer, BufferLength));
  1986. break;
  1987. default:
  1988. //
  1989. // Unknown OID
  1990. //
  1991. RWANDEBUGP(DL_ERROR, DC_DISPATCH,
  1992. ("AtmSpQueryInfo: Unknown OID x%x\n", pQueryInfo->ObjectId));
  1993. RWanStatus = RWAN_STATUS_BAD_PARAMETER;
  1994. break;
  1995. }
  1996. break;
  1997. }
  1998. while (FALSE);
  1999. //
  2000. // Fill in the output buffer now.
  2001. //
  2002. if (RWanStatus == RWAN_STATUS_SUCCESS)
  2003. {
  2004. if (BufferLength <= *pOutputBufferLength)
  2005. {
  2006. RWANDEBUGP(DL_LOUD, DC_DISPATCH,
  2007. ("AtmSpQueryInfo: Copying %d bytes from %x to %x\n",
  2008. BufferLength, pSrcBuffer, pOutputBuffer));
  2009. ATMSP_COPY_MEM(pOutputBuffer, pSrcBuffer, BufferLength);
  2010. }
  2011. else
  2012. {
  2013. RWanStatus = RWAN_STATUS_RESOURCES;
  2014. }
  2015. *pOutputBufferLength = BufferLength;
  2016. }
  2017. if (pAddrList != NULL)
  2018. {
  2019. ATMSP_FREE_MEM(pAddrList);
  2020. }
  2021. RWANDEBUGP(DL_LOUD, DC_DISPATCH,
  2022. ("AtmSpQueryInfo: returning x%x\n", RWanStatus));
  2023. return (RWanStatus);
  2024. }
  2025. RWAN_STATUS
  2026. RWanAtmSpSetGlobalInfo(
  2027. IN RWAN_HANDLE AfSpContext,
  2028. IN PVOID pInputBuffer,
  2029. IN ULONG InputBufferLength
  2030. )
  2031. /*++
  2032. Routine Description:
  2033. Process a media-specific IOCTL to set information from the helper DLL.
  2034. Arguments:
  2035. AfSpContext - Points to our Global context
  2036. pInputBuffer - Input information
  2037. InputBufferLength - Length of the above
  2038. Return Value:
  2039. RWAN_STATUS_SUCCESS if we processed the IOCTL successfully
  2040. RWAN_STATUS_XXX to indicate any failure.
  2041. --*/
  2042. {
  2043. RWANDEBUGP(DL_LOUD, DC_CONNECT,
  2044. ("AtmSpSetInfo: InBuf x%x/%d\n",
  2045. pInputBuffer,
  2046. InputBufferLength));
  2047. return (RWAN_STATUS_FAILURE);
  2048. }
  2049. #ifndef NO_CONN_CONTEXT
  2050. RWAN_STATUS
  2051. RWanAtmSpSetAddrInfo(
  2052. IN RWAN_HANDLE AfSpAddrContext,
  2053. IN PVOID pInputBuffer,
  2054. IN ULONG InputBufferLength
  2055. )
  2056. /*++
  2057. Routine Description:
  2058. Process a media-specific IOCTL to set information on an address object
  2059. from the helper DLL.
  2060. Arguments:
  2061. AfSpAddrContext - Points to our Address Block
  2062. pInputBuffer - Input information
  2063. InputBufferLength - Length of the above
  2064. Return Value:
  2065. RWAN_STATUS_SUCCESS if we processed the IOCTL successfully
  2066. RWAN_STATUS_XXX to indicate any failure.
  2067. --*/
  2068. {
  2069. RWAN_STATUS RWanStatus;
  2070. PATM_SET_INFORMATION_EX pSetInfo;
  2071. PATMSP_ADDR_BLOCK pAddrBlock;
  2072. PATMSP_CONNECTION_ID pConnectionId;
  2073. RWanStatus = RWAN_STATUS_SUCCESS;
  2074. pAddrBlock = (PATMSP_ADDR_BLOCK)AfSpAddrContext;
  2075. ATMSP_ASSERT(pAddrBlock != NULL);
  2076. do
  2077. {
  2078. //
  2079. // See if the input buffer is big enough.
  2080. //
  2081. if (InputBufferLength < sizeof(ATM_SET_INFORMATION_EX))
  2082. {
  2083. RWanStatus = RWAN_STATUS_RESOURCES;
  2084. break;
  2085. }
  2086. pSetInfo = (PATM_SET_INFORMATION_EX)pInputBuffer;
  2087. switch (pSetInfo->ObjectId)
  2088. {
  2089. case ATMSP_OID_PVC_ID:
  2090. if (pSetInfo->BufferSize < sizeof(ATMSP_CONNECTION_ID))
  2091. {
  2092. RWanStatus = RWAN_STATUS_RESOURCES;
  2093. break;
  2094. }
  2095. //
  2096. // Copy in the connection Id.
  2097. //
  2098. try
  2099. {
  2100. pConnectionId = (PATMSP_CONNECTION_ID)&(pSetInfo->Buffer[0]);
  2101. pAddrBlock->ConnectionId = *pConnectionId;
  2102. }
  2103. except (EXCEPTION_EXECUTE_HANDLER)
  2104. {
  2105. RWanStatus = RWAN_STATUS_FAILURE;
  2106. }
  2107. if (RWanStatus != RWAN_STATUS_SUCCESS)
  2108. {
  2109. break;
  2110. }
  2111. //
  2112. // Mark this address object.
  2113. //
  2114. ATMSP_SET_BIT(pAddrBlock->Flags, ATMSPF_ADDR_PVC_ID_SET);
  2115. RWANDEBUGP(DL_LOUD, DC_BIND,
  2116. ("AtmSpSetAddrInfo: Set PVC Id: AddrBlock x%x, Vpi %d, Vci %d\n",
  2117. pAddrBlock,
  2118. pAddrBlock->ConnectionId.Vpi,
  2119. pAddrBlock->ConnectionId.Vci));
  2120. break;
  2121. default:
  2122. //
  2123. // Unknown OID
  2124. //
  2125. RWANDEBUGP(DL_ERROR, DC_DISPATCH,
  2126. ("AtmSpSetAddrInfo: Unknown OID x%x\n", pSetInfo->ObjectId));
  2127. RWanStatus = RWAN_STATUS_BAD_PARAMETER;
  2128. break;
  2129. }
  2130. break;
  2131. }
  2132. while (FALSE);
  2133. return (RWanStatus);
  2134. }
  2135. RWAN_STATUS
  2136. RWanAtmSpQueryConnInfo(
  2137. IN RWAN_HANDLE AfSpConnContext,
  2138. IN PVOID pInputBuffer,
  2139. IN ULONG InputBufferLength,
  2140. OUT PVOID pOutputBuffer,
  2141. IN OUT PULONG pOutputBufferLength
  2142. )
  2143. /*++
  2144. Routine Description:
  2145. Handle a request to query information for a connection.
  2146. Arguments:
  2147. AfSpConnContext - Points to our Connection Block
  2148. pInputBuffer - Input information
  2149. InputBufferLength - Length of the above
  2150. pOutputBuffer - Place to return information
  2151. pOutputBufferLength - where we return bytes-written
  2152. Return Value:
  2153. RWAN_STATUS_SUCCESS if we processed the query successfully,
  2154. RWAN_STATUS_XXX error code otherwise.
  2155. --*/
  2156. {
  2157. RWAN_STATUS RWanStatus;
  2158. PATM_QUERY_INFORMATION_EX pQueryInfo;
  2159. PATMSP_CONN_BLOCK pConnBlock;
  2160. PATMSP_CONNECTION_ID pConnectionId;
  2161. RWanStatus = RWAN_STATUS_SUCCESS;
  2162. pConnBlock = (PATMSP_CONN_BLOCK)AfSpConnContext;
  2163. ATMSP_ASSERT(pConnBlock != NULL);
  2164. do
  2165. {
  2166. //
  2167. // See if the input buffer is big enough.
  2168. //
  2169. if (InputBufferLength < sizeof(ATM_QUERY_INFORMATION_EX))
  2170. {
  2171. RWanStatus = RWAN_STATUS_RESOURCES;
  2172. break;
  2173. }
  2174. pQueryInfo = (PATM_QUERY_INFORMATION_EX)pInputBuffer;
  2175. switch (pQueryInfo->ObjectId)
  2176. {
  2177. case ATMSP_OID_CONNECTION_ID:
  2178. if (*pOutputBufferLength < sizeof(ATMSP_CONNECTION_ID))
  2179. {
  2180. RWanStatus = RWAN_STATUS_RESOURCES;
  2181. break;
  2182. }
  2183. //
  2184. // Copy in the connection Id.
  2185. //
  2186. pConnectionId = pOutputBuffer;
  2187. *pConnectionId = pConnBlock->ConnectionId;
  2188. *pOutputBufferLength = sizeof(pConnBlock->ConnectionId);
  2189. break;
  2190. default:
  2191. //
  2192. // Unknown OID
  2193. //
  2194. RWANDEBUGP(DL_ERROR, DC_DISPATCH,
  2195. ("AtmSpQueryConnInfo: Unknown OID x%x\n", pQueryInfo->ObjectId));
  2196. RWanStatus = RWAN_STATUS_BAD_PARAMETER;
  2197. break;
  2198. }
  2199. break;
  2200. }
  2201. while (FALSE);
  2202. return (RWanStatus);
  2203. }
  2204. #endif // NO_CONN_CONTEXT