Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

630 lines
19 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 BChannel BChannel_c
  12. @module BChannel.c |
  13. This module implements the interface to the <t BCHANNEL_OBJECT>.
  14. Supports the high-level channel control functions used by the CONDIS WAN
  15. Miniport driver.
  16. @comm
  17. This module isolates most the channel specific interfaces. It will require
  18. some changes to accomodate your hardware device's channel access methods.
  19. @head3 Contents |
  20. @index class,mfunc,func,msg,mdata,struct,enum | BChannel_c
  21. @end
  22. */
  23. #define __FILEID__ BCHANNEL_OBJECT_TYPE
  24. // Unique file ID for error logging
  25. #include "Miniport.h" // Defines all the miniport objects
  26. #if defined(NDIS_LCODE)
  27. # pragma NDIS_LCODE // Windows 9x wants this code locked down!
  28. # pragma NDIS_LDATA
  29. #endif
  30. DBG_STATIC ULONG g_BChannelInstanceCounter // @globalv
  31. // Keeps track of how many <t BCHANNEL_OBJECT>s are created.
  32. = 0;
  33. /* @doc EXTERNAL INTERNAL BChannel BChannel_c g_BChannelParameters
  34. @topic 5.3 BChannel Parameters |
  35. This section describes the registry parameters read into the
  36. <t BCHANNEL_OBJECT>.
  37. @globalv PARAM_TABLE | g_BChannelParameters |
  38. This table defines the registry based parameters to be assigned to data
  39. members of the <t BCHANNEL_OBJECT>.
  40. <f Note>:
  41. If you add any registry based data members to <t BCHANNEL_OBJECT>
  42. you will need to modify <f BChannelReadParameters> and add the parameter
  43. definitions to the <f g_BChannelParameters> table.
  44. */
  45. DBG_STATIC PARAM_TABLE g_BChannelParameters[] =
  46. {
  47. PARAM_ENTRY(BCHANNEL_OBJECT,
  48. TODO, PARAM_TODO,
  49. FALSE, NdisParameterInteger, 0,
  50. 0, 0, 0),
  51. /* The last entry must be an empty string! */
  52. { { 0 } }
  53. };
  54. /* @doc INTERNAL BChannel BChannel_c BChannelReadParameters
  55. @func
  56. <f BChannelReadParameters> reads the BChannel parameters from the registry
  57. and initializes the associated data members. This should only be called
  58. by <f BChannelCreate>.
  59. @rdesc
  60. <f BChannelReadParameters> returns zero if it is successful.<nl>
  61. Otherwise, a non-zero return value indicates an error condition.
  62. <f Note>:
  63. If you add any registry based data members to <t BCHANNEL_OBJECT>
  64. you will need to modify <f BChannelReadParameters> and add the parameter
  65. definitions to the <f g_BChannelParameters> table.
  66. */
  67. DBG_STATIC NDIS_STATUS BChannelReadParameters(
  68. IN PBCHANNEL_OBJECT pBChannel // @parm
  69. // A pointer to the <t BCHANNEL_OBJECT> instance returned by
  70. // <f BChannelCreate>.
  71. )
  72. {
  73. DBG_FUNC("BChannelReadParameters")
  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(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  79. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  80. DBG_ENTER(pAdapter);
  81. /*
  82. // Parse the registry parameters.
  83. */
  84. Status = ParamParseRegistry(
  85. pAdapter->MiniportAdapterHandle,
  86. pAdapter->WrapperConfigurationContext,
  87. (PUCHAR)pBChannel,
  88. g_BChannelParameters
  89. );
  90. if (Status == NDIS_STATUS_SUCCESS)
  91. {
  92. /*
  93. // Make sure the parameters are valid.
  94. */
  95. if (pBChannel->TODO)
  96. {
  97. DBG_ERROR(pAdapter,("Invalid parameter\n"
  98. ));
  99. NdisWriteErrorLogEntry(
  100. pAdapter->MiniportAdapterHandle,
  101. NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
  102. 3,
  103. pBChannel->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 BChannel BChannel_c BChannelCreateObjects
  120. @func
  121. <f BChannelCreateObjects> calls the create routines for all the objects
  122. contained in <t BCHANNEL_OBJECT>. This should only be called
  123. by <f BChannelCreate>.
  124. <f Note>:
  125. If you add any new objects to <t BCHANNEL_OBJECT> you will need
  126. to modify <f BChannelCreateObjects> and <f BChannelDestroyObjects> so they
  127. will get created and destroyed properly.
  128. @rdesc
  129. <f BChannelCreateObjects> returns zero if it is successful.<nl>
  130. Otherwise, a non-zero return value indicates an error condition.
  131. */
  132. DBG_STATIC NDIS_STATUS BChannelCreateObjects(
  133. IN PBCHANNEL_OBJECT pBChannel // @parm
  134. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  135. )
  136. {
  137. DBG_FUNC("BChannelCreateObjects")
  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(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  143. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  144. DBG_ENTER(pAdapter);
  145. // TODO - Add code here
  146. DBG_RETURN(pAdapter, Result);
  147. return (Result);
  148. }
  149. /* @doc INTERNAL BChannel BChannel_c BChannelCreate
  150. @func
  151. <f BChannelCreate> allocates memory for a <t BCHANNEL_OBJECT> and then
  152. initializes the data members to their starting state.
  153. If successful, <p ppBChannel> will be set to point to the newly created
  154. <t BCHANNEL_OBJECT>. Otherwise, <p ppBChannel> will be set to NULL.
  155. @comm
  156. This function should be called only once when the Miniport is loaded.
  157. Before the Miniport is unloaded, <f BChannelDestroy> must be called to
  158. release the <t BCHANNEL_OBJECT> created by this function.
  159. @rdesc
  160. <f BChannelCreate> returns zero if it is successful.<nl>
  161. Otherwise, a non-zero return value indicates an error condition.
  162. */
  163. NDIS_STATUS BChannelCreate(
  164. OUT PBCHANNEL_OBJECT * ppBChannel, // @parm
  165. // Points to a caller-defined memory location to which this function
  166. // writes the virtual address of the allocated <t BCHANNEL_OBJECT>.
  167. IN ULONG BChannelIndex, // @parm
  168. // Index into the pBChannelArray.
  169. IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
  170. // A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance return by
  171. // <f AdapterCreate>.
  172. )
  173. {
  174. DBG_FUNC("BChannelCreate")
  175. PBCHANNEL_OBJECT pBChannel;
  176. // Pointer to our newly allocated object.
  177. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  178. // Holds the result code returned by this function.
  179. ASSERT(pAdapter && pAdapter->ObjectType == MINIPORT_ADAPTER_OBJECT_TYPE);
  180. DBG_ENTER(pAdapter);
  181. /*
  182. // Make sure the caller's object pointer is NULL to begin with.
  183. // It will be set later only if everything is successful.
  184. */
  185. *ppBChannel = NULL;
  186. /*
  187. // Allocate memory for the object.
  188. */
  189. Result = ALLOCATE_OBJECT(pBChannel, pAdapter->MiniportAdapterHandle);
  190. if (Result == NDIS_STATUS_SUCCESS)
  191. {
  192. /*
  193. // Zero everything to begin with.
  194. // Then set the object type and assign a unique ID .
  195. */
  196. pBChannel->ObjectType = BCHANNEL_OBJECT_TYPE;
  197. pBChannel->ObjectID = ++g_BChannelInstanceCounter;
  198. /*
  199. // Initialize the member variables to their default settings.
  200. */
  201. pBChannel->pAdapter = pAdapter;
  202. pBChannel->BChannelIndex = BChannelIndex;
  203. // TODO - Add code here
  204. /*
  205. // Parse the registry parameters.
  206. */
  207. Result = BChannelReadParameters(pBChannel);
  208. /*
  209. // If all goes well, we are ready to create the sub-components.
  210. */
  211. if (Result == NDIS_STATUS_SUCCESS)
  212. {
  213. Result = BChannelCreateObjects(pBChannel);
  214. }
  215. if (Result == NDIS_STATUS_SUCCESS)
  216. {
  217. /*
  218. // All is well, so return the object pointer to the caller.
  219. */
  220. InitializeListHead(&pBChannel->LinkList);
  221. *ppBChannel = pBChannel;
  222. }
  223. else
  224. {
  225. /*
  226. // Something went wrong, so let's make sure everything is
  227. // cleaned up.
  228. */
  229. BChannelDestroy(pBChannel);
  230. }
  231. }
  232. DBG_RETURN(pAdapter, Result);
  233. return (Result);
  234. }
  235. /* @doc INTERNAL BChannel BChannel_c BChannelDestroyObjects
  236. @func
  237. <f BChannelDestroyObjects> calls the destroy routines for all the objects
  238. contained in <t BCHANNEL_OBJECT>. This should only be called by
  239. <f BChannelDestroy>.
  240. <f Note>:
  241. If you add any new objects to <t PBCHANNEL_OBJECT> you will need to
  242. modify <f BChannelCreateObjects> and <f BChannelDestroyObjects> so they
  243. will get created and destroyed properly.
  244. */
  245. DBG_STATIC void BChannelDestroyObjects(
  246. IN PBCHANNEL_OBJECT pBChannel // @parm
  247. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  248. )
  249. {
  250. DBG_FUNC("BChannelDestroyObjects")
  251. PMINIPORT_ADAPTER_OBJECT pAdapter;
  252. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  253. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  254. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  255. DBG_ENTER(pAdapter);
  256. // TODO - Add code here
  257. if (pBChannel->pInCallParms != NULL)
  258. {
  259. FREE_MEMORY(pBChannel->pInCallParms, pBChannel->CallParmsSize);
  260. pBChannel->pInCallParms = NULL;
  261. }
  262. DBG_LEAVE(pAdapter);
  263. }
  264. /* @doc INTERNAL BChannel BChannel_c BChannelDestroy
  265. @func
  266. <f BChannelDestroy> frees the memory for this <t BCHANNEL_OBJECT>.
  267. All memory allocated by <f BChannelCreate> will be released back to the
  268. OS.
  269. */
  270. void BChannelDestroy(
  271. IN PBCHANNEL_OBJECT pBChannel // @parm
  272. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  273. )
  274. {
  275. DBG_FUNC("BChannelDestroy")
  276. PMINIPORT_ADAPTER_OBJECT pAdapter;
  277. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  278. if (pBChannel)
  279. {
  280. ASSERT(pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  281. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  282. DBG_ENTER(pAdapter);
  283. // TODO - Add code here
  284. /*
  285. // Release all objects allocated within this object.
  286. */
  287. BChannelDestroyObjects(pBChannel);
  288. /*
  289. // Make sure we fail the ASSERT if we see this object again.
  290. */
  291. pBChannel->ObjectType = 0;
  292. FREE_OBJECT(pBChannel);
  293. DBG_LEAVE(pAdapter);
  294. }
  295. }
  296. /* @doc INTERNAL BChannel BChannel_c BChannelInitialize
  297. @func
  298. <f BChannelInitialize> resets all the internal data members contained
  299. in <t BCHANNEL_OBJECT> back to their initial state.
  300. <f Note>:
  301. If you add any new members to <t BCHANNEL_OBJECT> you will need to
  302. modify <f BChannelInitialize> to initialize your new data mamebers.
  303. */
  304. void BChannelInitialize(
  305. IN PBCHANNEL_OBJECT pBChannel // @parm
  306. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  307. )
  308. {
  309. DBG_FUNC("BChannelInitialize")
  310. PMINIPORT_ADAPTER_OBJECT pAdapter;
  311. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  312. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  313. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  314. DBG_ENTER(pAdapter);
  315. /*
  316. // Initially, the BChannel is not allocated to anyone and these fields
  317. // must be reset.
  318. */
  319. ASSERT(pBChannel->NdisVcHandle == NULL);
  320. /*
  321. // Setup the static features of the link.
  322. */
  323. pBChannel->LinkSpeed = _64KBPS;
  324. pBChannel->BearerModesCaps = LINEBEARERMODE_DATA
  325. // | LINEBEARERMODE_VOICE
  326. ;
  327. pBChannel->MediaModesCaps = LINEMEDIAMODE_DIGITALDATA
  328. | LINEMEDIAMODE_UNKNOWN
  329. // | LINEMEDIAMODE_DATAMODEM
  330. ;
  331. /*
  332. // Initialize the TAPI event capabilities supported by the link.
  333. */
  334. pBChannel->DevStatesCaps = LINEDEVSTATE_RINGING
  335. | LINEDEVSTATE_CONNECTED
  336. | LINEDEVSTATE_DISCONNECTED
  337. | LINEDEVSTATE_INSERVICE
  338. | LINEDEVSTATE_OUTOFSERVICE
  339. | LINEDEVSTATE_OPEN
  340. | LINEDEVSTATE_CLOSE
  341. | LINEDEVSTATE_REINIT
  342. ;
  343. pBChannel->AddressStatesCaps = 0;
  344. pBChannel->CallStatesCaps = LINECALLSTATE_IDLE
  345. | LINECALLSTATE_DIALING
  346. | LINECALLSTATE_OFFERING
  347. | LINECALLSTATE_CONNECTED
  348. | LINECALLSTATE_DISCONNECTED
  349. ;
  350. /*
  351. // Set the TransmitBusyList and ReceivePendingList to empty.
  352. */
  353. InitializeListHead(&pBChannel->TransmitBusyList);
  354. InitializeListHead(&pBChannel->ReceivePendingList);
  355. // TODO - Add code here
  356. DBG_LEAVE(pAdapter);
  357. }
  358. /* @doc INTERNAL BChannel BChannel_c BChannelOpen
  359. @func
  360. <f BChannelOpen> makes the BChannel connection ready to transmit and
  361. receive data.
  362. @rdesc
  363. <f BChannelOpen> returns zero if it is successful.<nl>
  364. Otherwise, a non-zero return value indicates an error condition.
  365. */
  366. NDIS_STATUS BChannelOpen(
  367. IN PBCHANNEL_OBJECT pBChannel, // @parm
  368. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  369. IN NDIS_HANDLE NdisVcHandle // @parm
  370. // Handle by which NDIS wrapper will refer to this BChannel.
  371. )
  372. {
  373. DBG_FUNC("BChannelOpen")
  374. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  375. // Holds the result code returned by this function.
  376. PMINIPORT_ADAPTER_OBJECT pAdapter;
  377. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  378. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  379. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  380. DBG_ENTER(pAdapter);
  381. if (!pBChannel->IsOpen)
  382. {
  383. DBG_NOTICE(pAdapter,("Opening BChannel #%d\n",
  384. pBChannel->ObjectID));
  385. /*
  386. // The NdisVcHandle field is used to associate this BChannel with
  387. // the CoNdis Wrapper. Reset all the state information for
  388. // this BChannel.
  389. */
  390. pBChannel->NdisVcHandle = NdisVcHandle;
  391. pBChannel->CallClosing = FALSE;
  392. pBChannel->CallState = 0;
  393. pBChannel->MediaMode = 0;
  394. pBChannel->TotalRxPackets = 0;
  395. /*
  396. // Initialize the default BChannel information structure. It may be
  397. // changed later by MiniportCoRequest.
  398. */
  399. pBChannel->WanLinkInfo.MaxSendFrameSize = pAdapter->WanInfo.MaxFrameSize;
  400. pBChannel->WanLinkInfo.MaxRecvFrameSize = pAdapter->WanInfo.MaxFrameSize;
  401. pBChannel->WanLinkInfo.SendFramingBits = pAdapter->WanInfo.FramingBits;
  402. pBChannel->WanLinkInfo.RecvFramingBits = pAdapter->WanInfo.FramingBits;
  403. pBChannel->WanLinkInfo.SendCompressionBits = 0;
  404. pBChannel->WanLinkInfo.RecvCompressionBits = 0;
  405. pBChannel->WanLinkInfo.SendACCM = pAdapter->WanInfo.DesiredACCM;
  406. pBChannel->WanLinkInfo.RecvACCM = pAdapter->WanInfo.DesiredACCM;
  407. #if defined(SAMPLE_DRIVER)
  408. // Sample just tells tapi that the line is connected and in service.
  409. #else // SAMPLE_DRIVER
  410. // TODO - Add code here
  411. #endif // SAMPLE_DRIVER
  412. pBChannel->IsOpen = TRUE;
  413. }
  414. else
  415. {
  416. Result = NDIS_STATUS_FAILURE;
  417. DBG_ERROR(pAdapter,("BChannel #%d already opened\n",
  418. pBChannel->ObjectID));
  419. }
  420. DBG_RETURN(pAdapter, Result);
  421. return (Result);
  422. }
  423. /* @doc INTERNAL BChannel BChannel_c BChannelClose
  424. @func
  425. <f BChannelClose> closes the given B-channel.
  426. */
  427. void BChannelClose(
  428. IN PBCHANNEL_OBJECT pBChannel // @parm
  429. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  430. )
  431. {
  432. DBG_FUNC("BChannelClose")
  433. PMINIPORT_ADAPTER_OBJECT pAdapter;
  434. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  435. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  436. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  437. DBG_ENTER(pAdapter);
  438. if (pBChannel->IsOpen)
  439. {
  440. DBG_NOTICE(pAdapter,("Closing BChannel #%d\n",
  441. pBChannel->ObjectID));
  442. /*
  443. // Make sure call is cleared and B channel is disabled.
  444. */
  445. DChannelCloseCall(pAdapter->pDChannel, pBChannel);
  446. // TODO - Add code here
  447. pBChannel->Flags = 0;
  448. pBChannel->CallState = 0;
  449. pBChannel->NdisVcHandle = NULL;
  450. pBChannel->IsOpen = FALSE;
  451. }
  452. else
  453. {
  454. DBG_ERROR(pAdapter,("BChannel #%d already closed\n",
  455. pBChannel->ObjectID));
  456. }
  457. DBG_LEAVE(pAdapter);
  458. }