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.

865 lines
25 KiB

  1. /*
  2. (C) Copyright 1999
  3. All rights reserved.
  4. Portions of this software are:
  5. (C) Copyright 1995 TriplePoint, Inc. -- http://www.TriplePoint.com
  6. License to use this software is granted under the same terms
  7. outlined in the Microsoft Windows Device Driver Development Kit.
  8. (C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
  9. License to use this software is granted under the terms outlined in
  10. the Microsoft Windows Device Driver Development Kit.
  11. @doc INTERNAL DChannel DChannel_c
  12. @module DChannel.c |
  13. This module implements the interface to the <t DCHANNEL_OBJECT>.
  14. Supports the high-level channel control functions used by the CONDIS WAN
  15. Minport driver.
  16. @comm
  17. This module isolates most the vendor specific Call Control interfaces.
  18. It will require some changes to accomodate your hardware device's call
  19. control mechanism.
  20. @head3 Contents |
  21. @index class,mfunc,func,msg,mdata,struct,enum | DChannel_c
  22. @end
  23. */
  24. #define __FILEID__ DCHANNEL_OBJECT_TYPE
  25. // Unique file ID for error logging
  26. #include "Miniport.h" // Defines all the miniport objects
  27. #if defined(NDIS_LCODE)
  28. # pragma NDIS_LCODE // Windows 9x wants this code locked down!
  29. # pragma NDIS_LDATA
  30. #endif
  31. DBG_STATIC ULONG g_DChannelInstanceCounter // @globalv
  32. // Keeps track of how many <t DCHANNEL_OBJECT>s are created.
  33. = 0;
  34. /* @doc EXTERNAL INTERNAL DChannel DChannel_c g_DChannelParameters
  35. @topic 5.4 DChannel Parameters |
  36. This section describes the registry parameters read into the
  37. <t DCHANNEL_OBJECT>.
  38. @globalv PARAM_TABLE | g_DChannelParameters |
  39. This table defines the registry based parameters to be assigned to data
  40. members of the <t DCHANNEL_OBJECT>.
  41. <f Note>:
  42. If you add any registry based data members to <t DCHANNEL_OBJECT>
  43. you will need to modify <f DChannelReadParameters> and add the parameter
  44. definitions to the <f g_DChannelParameters> table.
  45. */
  46. DBG_STATIC PARAM_TABLE g_DChannelParameters[] =
  47. {
  48. PARAM_ENTRY(DCHANNEL_OBJECT,
  49. TODO, PARAM_TODO,
  50. FALSE, NdisParameterInteger, 0,
  51. 0, 0, 0),
  52. /* The last entry must be an empty string! */
  53. { { 0 } }
  54. };
  55. /* @doc INTERNAL DChannel DChannel_c DChannelReadParameters
  56. @func
  57. <f DChannelReadParameters> reads the DChannel parameters from the registry
  58. and initializes the associated data members. This should only be called
  59. by <f DChannelCreate>.
  60. <f Note>:
  61. If you add any registry based data members to <t DCHANNEL_OBJECT>
  62. you will need to modify <f DChannelReadParameters> and add the parameter
  63. definitions to the <f g_DChannelParameters> table.
  64. @rdesc
  65. <f DChannelReadParameters> returns zero if it is successful.<nl>
  66. Otherwise, a non-zero return value indicates an error condition.
  67. */
  68. DBG_STATIC NDIS_STATUS DChannelReadParameters(
  69. IN PDCHANNEL_OBJECT pDChannel // @parm
  70. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  71. )
  72. {
  73. DBG_FUNC("DChannelReadParameters")
  74. NDIS_STATUS Status;
  75. // Status result returned from an NDIS function call.
  76. PMINIPORT_ADAPTER_OBJECT pAdapter;
  77. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  78. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  79. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  80. DBG_ENTER(pAdapter);
  81. /*
  82. // Parse the registry parameters.
  83. */
  84. Status = ParamParseRegistry(
  85. pAdapter->MiniportAdapterHandle,
  86. pAdapter->WrapperConfigurationContext,
  87. (PUCHAR)pDChannel,
  88. g_DChannelParameters
  89. );
  90. if (Status == NDIS_STATUS_SUCCESS)
  91. {
  92. /*
  93. // Make sure the parameters are valid.
  94. */
  95. if (pDChannel->TODO)
  96. {
  97. DBG_ERROR(pAdapter,("Invalid parameter\n"
  98. ));
  99. NdisWriteErrorLogEntry(
  100. pAdapter->MiniportAdapterHandle,
  101. NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
  102. 3,
  103. pDChannel->TODO,
  104. __FILEID__,
  105. __LINE__
  106. );
  107. Status = NDIS_STATUS_FAILURE;
  108. }
  109. else
  110. {
  111. /*
  112. // Finish setting up data members based on registry settings.
  113. */
  114. }
  115. }
  116. DBG_RETURN(pAdapter, Status);
  117. return (Status);
  118. }
  119. /* @doc INTERNAL DChannel DChannel_c DChannelCreateObjects
  120. @func
  121. <f DChannelCreateObjects> calls the create routines for all the objects
  122. contained in <t DCHANNEL_OBJECT>. This should only be called
  123. by <f DChannelCreate>.
  124. <f Note>:
  125. If you add any new objects to <t DCHANNEL_OBJECT> you will need
  126. to modify <f DChannelCreateObjects> and <f DChannelDestroyObjects> so they
  127. will get created and destroyed properly.
  128. @rdesc
  129. <f DChannelCreateObjects> returns zero if it is successful.<nl>
  130. Otherwise, a non-zero return value indicates an error condition.
  131. */
  132. DBG_STATIC NDIS_STATUS DChannelCreateObjects(
  133. IN PDCHANNEL_OBJECT pDChannel // @parm
  134. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  135. )
  136. {
  137. DBG_FUNC("DChannelCreateObjects")
  138. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  139. // Holds the result code returned by this function.
  140. PMINIPORT_ADAPTER_OBJECT pAdapter;
  141. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  142. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  143. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  144. DBG_ENTER(pAdapter);
  145. // TODO - Add code here to allocate any sub-objects needed to support
  146. // your physical DChannels.
  147. DBG_RETURN(pAdapter, Result);
  148. return (Result);
  149. }
  150. /* @doc INTERNAL DChannel DChannel_c DChannelCreate
  151. @func
  152. <f DChannelCreate> allocates memory for a <t DCHANNEL_OBJECT> and then
  153. initializes the data members to their starting state.
  154. If successful, <p ppDChannel> will be set to point to the newly created
  155. <t DCHANNEL_OBJECT>. Otherwise, <p ppDChannel> will be set to NULL.
  156. @comm
  157. This function should be called only once when the Miniport is loaded.
  158. Before the Miniport is unloaded, <f DChannelDestroy> must be called to
  159. release the <t DCHANNEL_OBJECT> created by this function.
  160. @rdesc
  161. <f DChannelCreate> returns zero if it is successful.<nl>
  162. Otherwise, a non-zero return value indicates an error condition.
  163. */
  164. NDIS_STATUS DChannelCreate(
  165. OUT PDCHANNEL_OBJECT * ppDChannel, // @parm
  166. // Points to a caller-defined memory location to which this function
  167. // writes the virtual address of the allocated <t DCHANNEL_OBJECT>.
  168. IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
  169. // A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
  170. )
  171. {
  172. DBG_FUNC("DChannelCreate")
  173. PDCHANNEL_OBJECT pDChannel;
  174. // Pointer to our newly allocated object.
  175. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  176. // Holds the result code returned by this function.
  177. ASSERT(pAdapter && pAdapter->ObjectType == MINIPORT_ADAPTER_OBJECT_TYPE);
  178. DBG_ENTER(pAdapter);
  179. /*
  180. // Make sure the caller's object pointer is NULL to begin with.
  181. // It will be set later only if everything is successful.
  182. */
  183. *ppDChannel = NULL;
  184. /*
  185. // Allocate memory for the object.
  186. */
  187. Result = ALLOCATE_OBJECT(pDChannel, pAdapter->MiniportAdapterHandle);
  188. if (Result == NDIS_STATUS_SUCCESS)
  189. {
  190. /*
  191. // Zero everything to begin with.
  192. // Then set the object type and assign a unique ID .
  193. */
  194. pDChannel->ObjectType = DCHANNEL_OBJECT_TYPE;
  195. pDChannel->ObjectID = ++g_DChannelInstanceCounter;
  196. /*
  197. // Initialize the member variables to their default settings.
  198. */
  199. pDChannel->pAdapter = pAdapter;
  200. // TODO - Add code here to allocate any resources needed to support
  201. // your physical DChannels.
  202. /*
  203. // Parse the registry parameters.
  204. */
  205. Result = DChannelReadParameters(pDChannel);
  206. /*
  207. // If all goes well, we are ready to create the sub-components.
  208. */
  209. if (Result == NDIS_STATUS_SUCCESS)
  210. {
  211. Result = DChannelCreateObjects(pDChannel);
  212. }
  213. if (Result == NDIS_STATUS_SUCCESS)
  214. {
  215. /*
  216. // All is well, so return the object pointer to the caller.
  217. */
  218. *ppDChannel = pDChannel;
  219. }
  220. else
  221. {
  222. /*
  223. // Something went wrong, so let's make sure everything is
  224. // cleaned up.
  225. */
  226. DChannelDestroy(pDChannel);
  227. }
  228. }
  229. DBG_RETURN(pAdapter, Result);
  230. return (Result);
  231. }
  232. /* @doc INTERNAL DChannel DChannel_c DChannelDestroyObjects
  233. @func
  234. <f DChannelDestroyObjects> calls the destroy routines for all the objects
  235. contained in <t DCHANNEL_OBJECT>. This should only be called by
  236. <f DChannelDestroy>.
  237. <f Note>: If you add any new objects to <t PDCHANNEL_OBJECT> you will need to
  238. modify <f DChannelCreateObjects> and <f DChannelDestroyObjects> so they
  239. will get created and destroyed properly.
  240. */
  241. DBG_STATIC void DChannelDestroyObjects(
  242. IN PDCHANNEL_OBJECT pDChannel // @parm
  243. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  244. )
  245. {
  246. DBG_FUNC("DChannelDestroyObjects")
  247. PMINIPORT_ADAPTER_OBJECT pAdapter;
  248. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  249. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  250. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  251. DBG_ENTER(pAdapter);
  252. // TODO - Add code here to release any sub-objects allocated by
  253. // DChannelCreateObjects.
  254. DBG_LEAVE(pAdapter);
  255. }
  256. /* @doc INTERNAL DChannel DChannel_c DChannelDestroy
  257. @func
  258. <f DChannelDestroy> frees the memory for this <t DCHANNEL_OBJECT>.
  259. All memory allocated by <f DChannelCreate> will be released back to the
  260. OS.
  261. */
  262. void DChannelDestroy(
  263. IN PDCHANNEL_OBJECT pDChannel // @parm
  264. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  265. )
  266. {
  267. DBG_FUNC("DChannelDestroy")
  268. PMINIPORT_ADAPTER_OBJECT pAdapter;
  269. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  270. if (pDChannel)
  271. {
  272. ASSERT(pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  273. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  274. DBG_ENTER(pAdapter);
  275. // TODO - Add code here to release any resources allocated by
  276. // DChannelCreate.
  277. /*
  278. // Release all objects allocated within this object.
  279. */
  280. DChannelDestroyObjects(pDChannel);
  281. /*
  282. // Make sure we fail the ASSERT if we see this object again.
  283. */
  284. pDChannel->ObjectType = 0;
  285. FREE_OBJECT(pDChannel);
  286. DBG_LEAVE(pAdapter);
  287. }
  288. }
  289. /* @doc INTERNAL DChannel DChannel_c DChannelInitialize
  290. @func
  291. <f DChannelInitialize> resets all the internal data members contained
  292. in <t BCHANNEL_OBJECT> back to their initial state.
  293. <f Note>:
  294. If you add any new members to <t DCHANNEL_OBJECT> you will need to
  295. modify <f DChannelInitialize> to initialize your new data mamebers.
  296. */
  297. void DChannelInitialize(
  298. IN PDCHANNEL_OBJECT pDChannel // @parm
  299. // A pointer to the <t BCHANNEL_OBJECT> returned by <f DChannelCreate>.
  300. )
  301. {
  302. DBG_FUNC("DChannelInitialize")
  303. PMINIPORT_ADAPTER_OBJECT pAdapter;
  304. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  305. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  306. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  307. DBG_ENTER(pAdapter);
  308. // TODO - Add code here to initialize all the physical D-Channels on
  309. // your adapter.
  310. DBG_LEAVE(pAdapter);
  311. }
  312. /* @doc INTERNAL DChannel DChannel_c DChannelOpen
  313. @func
  314. <f DChannelOpen> establishes a communications path between the miniport
  315. and the DChannel.
  316. @rdesc
  317. <f DChannelOpen> returns zero if it is successful.<nl>
  318. Otherwise, a non-zero return value indicates an error condition.
  319. */
  320. NDIS_STATUS DChannelOpen(
  321. IN PDCHANNEL_OBJECT pDChannel // @parm
  322. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  323. )
  324. {
  325. DBG_FUNC("DChannelOpen")
  326. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  327. // Holds the result code returned by this function.
  328. PMINIPORT_ADAPTER_OBJECT pAdapter;
  329. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  330. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  331. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  332. DBG_ENTER(pAdapter);
  333. if (++pDChannel->IsOpen == 1)
  334. {
  335. DBG_NOTICE(pAdapter,("Opening DChannel #%d\n",
  336. pDChannel->ObjectID));
  337. // TODO - Add code here to open all the physical D-Channels on
  338. // your adapter.
  339. }
  340. else
  341. {
  342. DBG_NOTICE(pAdapter,("DChannel #%d already opened\n",
  343. pDChannel->ObjectID));
  344. }
  345. DBG_RETURN(pAdapter, Result);
  346. return (Result);
  347. }
  348. /* @doc INTERNAL DChannel DChannel_c DChannelClose
  349. @func
  350. <f DChannelClose> tears down the communications path between the miniport
  351. and the DChannel.
  352. */
  353. void DChannelClose(
  354. IN PDCHANNEL_OBJECT pDChannel // @parm
  355. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  356. )
  357. {
  358. DBG_FUNC("DChannelClose")
  359. PMINIPORT_ADAPTER_OBJECT pAdapter;
  360. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  361. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  362. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  363. DBG_ENTER(pAdapter);
  364. if (pDChannel->IsOpen == 1)
  365. {
  366. DBG_NOTICE(pAdapter,("Closing DChannel #%d\n",
  367. pDChannel->ObjectID));
  368. // TODO - Add code here to close all the physical D-Channels on
  369. // your adapter.
  370. pDChannel->IsOpen = 0;
  371. }
  372. else if (pDChannel->IsOpen == 0)
  373. {
  374. DBG_WARNING(pAdapter,("DChannel #%d already closed\n",
  375. pDChannel->ObjectID));
  376. }
  377. else
  378. {
  379. pDChannel->IsOpen--;
  380. }
  381. DBG_LEAVE(pAdapter);
  382. }
  383. /* @doc INTERNAL DChannel DChannel_c DChannelMakeCall
  384. @func
  385. <f DChannelMakeCall> places a call over the selected line device.
  386. @rdesc
  387. <f DChannelMakeCall> returns zero if it is successful.<nl>
  388. Otherwise, a non-zero return value indicates an error condition.
  389. */
  390. NDIS_STATUS DChannelMakeCall(
  391. IN PDCHANNEL_OBJECT pDChannel, // @parm
  392. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  393. IN PBCHANNEL_OBJECT pBChannel, // @parm
  394. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  395. IN PUCHAR DialString, // @parm
  396. // A pointer to an ASCII null-terminated string of digits.
  397. IN USHORT DialStringLength, // @parm
  398. // Number of bytes in dial string.
  399. IN PLINE_CALL_PARAMS pLineCallParams // @parm
  400. // A pointer to the TAPI <t LINE_CALL_PARAMS> to be used for this call.
  401. )
  402. {
  403. DBG_FUNC("DChannelMakeCall")
  404. NDIS_STATUS Result = NDIS_STATUS_RESOURCES;
  405. // Holds the result code returned by this function.
  406. PMINIPORT_ADAPTER_OBJECT pAdapter;
  407. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  408. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  409. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  410. DBG_ENTER(pAdapter);
  411. ASSERT(pDChannel->IsOpen);
  412. pDChannel->TotalMakeCalls++;
  413. pBChannel->Flags |= VCF_OUTGOING_CALL;
  414. pBChannel->CallState = LINECALLSTATE_DIALING;
  415. #if defined(SAMPLE_DRIVER)
  416. // This sample code uses the phone number to select one of the other
  417. // BChannels on which to complete the connection.
  418. {
  419. PBCHANNEL_OBJECT pPeerBChannel;
  420. PCARD_EVENT_OBJECT pEvent;
  421. pPeerBChannel = GET_BCHANNEL_FROM_PHONE_NUMBER(DialString);
  422. if (pPeerBChannel)
  423. {
  424. pEvent = CardEventAllocate(pPeerBChannel->pAdapter->pCard);
  425. if (pEvent)
  426. {
  427. pEvent->ulEventCode = CARD_EVENT_RING;
  428. pEvent->pSendingObject = pBChannel;
  429. pEvent->pReceivingObject = pPeerBChannel;
  430. pBChannel->pPeerBChannel = pPeerBChannel;
  431. CardNotifyEvent(pPeerBChannel->pAdapter->pCard, pEvent);
  432. Result = NDIS_STATUS_PENDING;
  433. }
  434. }
  435. else
  436. {
  437. DBG_ERROR(pAdapter,("Cannot map phone number '%s' to BChannel\n",
  438. DialString));
  439. }
  440. }
  441. #else // SAMPLE_DRIVER
  442. // TODO - Add code here to place a call.
  443. #endif // SAMPLE_DRIVER
  444. DBG_RETURN(pAdapter, Result);
  445. return (Result);
  446. }
  447. /* @doc INTERNAL DChannel DChannel_c DChannelAnswerCall
  448. @func
  449. <f DChannelAnswerCall> answers the incoming call so it can be connected.
  450. @rdesc
  451. <f DChannelAnswerCall> returns zero if it is successful.<nl>
  452. Otherwise, a non-zero return value indicates an error condition.
  453. */
  454. NDIS_STATUS DChannelAnswerCall(
  455. IN PDCHANNEL_OBJECT pDChannel, // @parm
  456. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  457. IN PBCHANNEL_OBJECT pBChannel // @parm
  458. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  459. )
  460. {
  461. DBG_FUNC("DChannelAnswerCall")
  462. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  463. // Holds the result code returned by this function.
  464. PMINIPORT_ADAPTER_OBJECT pAdapter;
  465. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  466. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  467. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  468. DBG_ENTER(pAdapter);
  469. ASSERT(pDChannel->IsOpen);
  470. pDChannel->TotalAnswers++;
  471. #if defined(SAMPLE_DRIVER)
  472. // This sample code sends a connect over to the calling BChannel.
  473. {
  474. PCARD_EVENT_OBJECT pEvent;
  475. PBCHANNEL_OBJECT pPeerBChannel = pBChannel->pPeerBChannel;
  476. if (pPeerBChannel)
  477. {
  478. pEvent = CardEventAllocate(pPeerBChannel->pAdapter->pCard);
  479. if (pEvent)
  480. {
  481. pEvent->ulEventCode = CARD_EVENT_CONNECT;
  482. pEvent->pSendingObject = pBChannel;
  483. pEvent->pReceivingObject = pPeerBChannel;
  484. CardNotifyEvent(pPeerBChannel->pAdapter->pCard, pEvent);
  485. }
  486. else
  487. {
  488. Result = NDIS_STATUS_RESOURCES;
  489. }
  490. }
  491. else
  492. {
  493. DBG_ERROR(pAdapter,("pPeerBChannel == NULL\n"));
  494. Result = NDIS_STATUS_RESOURCES;
  495. }
  496. }
  497. #else // SAMPLE_DRIVER
  498. // TODO - Add code here to answer a call.
  499. // If you return NDIS_STATUS_PENDING from here, you must perform the
  500. // following actions when the call is finally answered.
  501. // pBChannel->CallState = LINECALLSTATE_CONNECTED;
  502. // NdisMCmDispatchCallConnected(pBChannel->NdisVcHandle);
  503. // If you fail to answer for some reason you must call:
  504. // InitiateCallTeardown(pAdapter, pBChannel);
  505. #endif // SAMPLE_DRIVER
  506. DBG_RETURN(pAdapter, Result);
  507. return (Result);
  508. }
  509. /* @doc INTERNAL DChannel DChannel_c DChannelCloseCall
  510. @func
  511. <f DChannelCloseCall> closes a previously opened call instance as
  512. initiated from <f DChannelMakeCall> or <f DChannelAnswerCall>. After
  513. the call is closed, no one else should reference it.
  514. @rdesc
  515. <f DChannelCloseCall> returns zero if it is successful.<nl>
  516. Otherwise, a non-zero return value indicates an error condition.
  517. */
  518. NDIS_STATUS DChannelCloseCall(
  519. IN PDCHANNEL_OBJECT pDChannel, // @parm
  520. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  521. IN PBCHANNEL_OBJECT pBChannel // @parm
  522. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  523. )
  524. {
  525. DBG_FUNC("DChannelCloseCall")
  526. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  527. // Holds the result code returned by this function.
  528. PMINIPORT_ADAPTER_OBJECT pAdapter;
  529. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  530. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  531. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  532. DBG_ENTER(pAdapter);
  533. ASSERT(pDChannel->IsOpen);
  534. // This routine may be called several times during line/call cleanup.
  535. // If the call is already closed, just return success.
  536. if (pBChannel->CallState != 0 &&
  537. pBChannel->CallState != LINECALLSTATE_IDLE)
  538. {
  539. #if defined(SAMPLE_DRIVER)
  540. // This sample code sends a disconnect over to the connected BChannel.
  541. PCARD_EVENT_OBJECT pEvent;
  542. PBCHANNEL_OBJECT pPeerBChannel = pBChannel->pPeerBChannel;
  543. if (pPeerBChannel)
  544. {
  545. pEvent = CardEventAllocate(pPeerBChannel->pAdapter->pCard);
  546. if (pEvent)
  547. {
  548. // Indicate call disconnect to the other channel.
  549. pEvent->ulEventCode = CARD_EVENT_DISCONNECT;
  550. pEvent->pSendingObject = pBChannel;
  551. pEvent->pReceivingObject = pPeerBChannel;
  552. CardNotifyEvent(pPeerBChannel->pAdapter->pCard, pEvent);
  553. }
  554. pBChannel->pPeerBChannel = NULL;
  555. }
  556. else
  557. {
  558. DBG_WARNING(pAdapter,("#%d NO PEER CHANNEL - CALLSTATE=%X\n",
  559. pBChannel->ObjectID, pBChannel->CallState));
  560. }
  561. // Return any pending packets to the protocol stack.
  562. pBChannel->CallState = LINECALLSTATE_IDLE;
  563. #else // SAMPLE_DRIVER
  564. // TODO - Add code here to drop a call.
  565. #endif // SAMPLE_DRIVER
  566. // Make sure there are no packets left on this channel before it closes.
  567. FlushSendPackets(pAdapter, pBChannel);
  568. }
  569. else
  570. {
  571. DBG_NOTICE(pAdapter,("#%d ALREADY IDLE - CALLSTATE=%X\n",
  572. pBChannel->ObjectID, pBChannel->CallState));
  573. }
  574. DBG_RETURN(pAdapter, Result);
  575. return (Result);
  576. }
  577. /* @doc INTERNAL DChannel DChannel_c DChannelRejectCall
  578. @func
  579. <f DChannelRejectCall> rejects an incoming call on the specified
  580. channel.
  581. */
  582. VOID DChannelRejectCall(
  583. IN PDCHANNEL_OBJECT pDChannel, // @parm
  584. // A pointer to the <t DCHANNEL_OBJECT> returned by <f DChannelCreate>.
  585. IN PBCHANNEL_OBJECT pBChannel // @parm
  586. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  587. )
  588. {
  589. DBG_FUNC("DChannelRejectCall")
  590. PMINIPORT_ADAPTER_OBJECT pAdapter;
  591. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  592. ASSERT(pDChannel && pDChannel->ObjectType == DCHANNEL_OBJECT_TYPE);
  593. pAdapter = GET_ADAPTER_FROM_DCHANNEL(pDChannel);
  594. DBG_ENTER(pAdapter);
  595. if (pBChannel->CallState != 0 &&
  596. pBChannel->CallState != LINECALLSTATE_IDLE)
  597. {
  598. #if defined(SAMPLE_DRIVER)
  599. // This sample code sends a disconnect over to the connected BChannel.
  600. PCARD_EVENT_OBJECT pEvent;
  601. PBCHANNEL_OBJECT pPeerBChannel = pBChannel->pPeerBChannel;
  602. if (pPeerBChannel)
  603. {
  604. pEvent = CardEventAllocate(pPeerBChannel->pAdapter->pCard);
  605. if (pEvent)
  606. {
  607. // Indicate call disconnect to the other channel.
  608. pEvent->ulEventCode = CARD_EVENT_DISCONNECT;
  609. pEvent->pSendingObject = pBChannel;
  610. pEvent->pReceivingObject = pPeerBChannel;
  611. CardNotifyEvent(pPeerBChannel->pAdapter->pCard, pEvent);
  612. }
  613. pBChannel->pPeerBChannel = NULL;
  614. }
  615. else
  616. {
  617. DBG_WARNING(pAdapter,("#%d NO PEER CHANNEL - CALLSTATE=%X\n",
  618. pBChannel->ObjectID, pBChannel->CallState));
  619. }
  620. // Return any pending packets to the protocol stack.
  621. pBChannel->CallState = LINECALLSTATE_IDLE;
  622. #else // SAMPLE_DRIVER
  623. // TODO - Add code here to reject an incoming call.
  624. #endif // SAMPLE_DRIVER
  625. }
  626. DBG_LEAVE(pAdapter);
  627. }