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.

954 lines
31 KiB

  1. /*
  2. (C) Copyright 1998
  3. All rights reserved.
  4. Portions of this software are:
  5. (C) Copyright 1995, 1999 TriplePoint, Inc. -- http://www.TriplePoint.com
  6. License to use this software is granted under the terms outlined in
  7. the TriplePoint Software Services Agreement.
  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 TspiLine TspiLine_c
  12. @module TspiLine.c |
  13. This module implements the Telephony Service Provider Interface for
  14. Line objects (TapiLine).
  15. @head3 Contents |
  16. @index class,mfunc,func,msg,mdata,struct,enum | TspiLine_c
  17. @end
  18. */
  19. #define __FILEID__ TSPILINE_OBJECT_TYPE
  20. // Unique file ID for error logging
  21. #include "Miniport.h" // Defines all the miniport objects
  22. #include "string.h"
  23. #if defined(NDIS_LCODE)
  24. # pragma NDIS_LCODE // Windows 95 wants this code locked down!
  25. # pragma NDIS_LDATA
  26. #endif
  27. /* @doc INTERNAL TspiLine TspiLine_c TspiOpen
  28. @func
  29. This function opens the line device whose device ID is given, returning
  30. the miniport's handle for the device. The miniport must retain the
  31. Connection Wrapper's handle for the device for use in subsequent calls to
  32. the LINE_EVENT callback procedure.
  33. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  34. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  35. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  36. @parm IN PNDIS_TAPI_OPEN | Request |
  37. A pointer to the NDIS_TAPI request structure for this call.
  38. @iex
  39. typedef struct _NDIS_TAPI_OPEN
  40. {
  41. IN ULONG ulRequestID;
  42. IN ULONG ulDeviceID;
  43. IN HTAPI_LINE htLine;
  44. OUT HDRV_LINE hdLine;
  45. } NDIS_TAPI_OPEN, *PNDIS_TAPI_OPEN;
  46. @rdesc This routine returns one of the following values:
  47. @flag NDIS_STATUS_SUCCESS |
  48. If this function is successful.
  49. <f Note>: A non-zero return value indicates one of the following error codes:
  50. @iex
  51. NDIS_STATUS_PENDING
  52. NDIS_STATUS_TAPI_ALLOCATED
  53. NDIS_STATUS_TAPI_NODRIVER
  54. */
  55. NDIS_STATUS TspiOpen(
  56. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  57. IN PNDIS_TAPI_OPEN Request,
  58. OUT PULONG BytesWritten,
  59. OUT PULONG BytesNeeded
  60. )
  61. {
  62. DBG_FUNC("TspiOpen")
  63. PBCHANNEL_OBJECT pBChannel;
  64. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  65. DBG_ENTER(pAdapter);
  66. DBG_PARAMS(pAdapter,
  67. ("\n\tulDeviceID=%d\n"
  68. "\thtLine=0x%X\n",
  69. Request->ulDeviceID,
  70. Request->htLine
  71. ));
  72. /*
  73. // If there is no DChannel, we can't allow an open line.
  74. */
  75. if (pAdapter->pDChannel == NULL)
  76. {
  77. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_NODRIVER\n"));
  78. return (NDIS_STATUS_TAPI_NODRIVER);
  79. }
  80. /*
  81. // This request must be associated with a line device.
  82. */
  83. pBChannel = GET_BCHANNEL_FROM_DEVICEID(pAdapter, Request->ulDeviceID);
  84. if (pBChannel == NULL)
  85. {
  86. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_NODEVICE\n"));
  87. return (NDIS_STATUS_TAPI_NODEVICE);
  88. }
  89. /*
  90. // Make sure the requested line device is not already in use.
  91. */
  92. if (BChannelOpen(pBChannel, Request->htLine) != NDIS_STATUS_SUCCESS)
  93. {
  94. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_ALLOCATED\n"));
  95. return (NDIS_STATUS_TAPI_ALLOCATED);
  96. }
  97. /*
  98. // Tell the wrapper the line context and set the line/call state.
  99. */
  100. Request->hdLine = (HDRV_LINE) pBChannel;
  101. /*
  102. // Make sure the line is configured for dialing when we open up.
  103. */
  104. TspiLineDevStateHandler(pAdapter, pBChannel, LINEDEVSTATE_OPEN);
  105. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  106. return (NDIS_STATUS_SUCCESS);
  107. }
  108. /* @doc INTERNAL TspiLine TspiLine_c TspiClose
  109. @func
  110. This request closes the specified open line device after completing or
  111. aborting all outstanding calls and asynchronous requests on the device.
  112. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  113. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  114. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  115. @parm IN PNDIS_TAPI_CLOSE | Request |
  116. A pointer to the NDIS_TAPI request structure for this call.
  117. @iex
  118. typedef struct _NDIS_TAPI_CLOSE
  119. {
  120. IN ULONG ulRequestID;
  121. IN HDRV_LINE hdLine;
  122. } NDIS_TAPI_CLOSE, *PNDIS_TAPI_CLOSE;
  123. @rdesc This routine returns one of the following values:
  124. @flag NDIS_STATUS_SUCCESS |
  125. If this function is successful.
  126. <f Note>: A non-zero return value indicates one of the following error codes:
  127. @iex
  128. NDIS_STATUS_PENDING
  129. NDIS_STATUS_TAPI_INVALLINEHANDLE
  130. */
  131. NDIS_STATUS TspiClose(
  132. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  133. IN PNDIS_TAPI_CLOSE Request,
  134. OUT PULONG BytesRead,
  135. OUT PULONG BytesNeeded
  136. )
  137. {
  138. DBG_FUNC("TspiClose")
  139. PBCHANNEL_OBJECT pBChannel;
  140. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  141. NDIS_STATUS Result;
  142. // Holds the result code returned by this function.
  143. DBG_ENTER(pAdapter);
  144. DBG_PARAMS(pAdapter,
  145. ("\n\thdLine=0x%X\n",
  146. Request->hdLine
  147. ));
  148. /*
  149. // This request must be associated with a line device.
  150. // And it must not be called until all calls are closed or idle.
  151. */
  152. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  153. if (pBChannel == NULL ||
  154. (pBChannel->DevState & LINEDEVSTATE_OPEN) == 0)
  155. {
  156. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  157. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  158. }
  159. /*
  160. // Close the TAPI line device and release the channel.
  161. */
  162. BChannelClose(pBChannel);
  163. TspiLineDevStateHandler(pAdapter, pBChannel, LINEDEVSTATE_CLOSE);
  164. Result = NDIS_STATUS_SUCCESS;
  165. DBG_RETURN(pAdapter, Result);
  166. return (Result);
  167. }
  168. /* @doc INTERNAL TspiLine TspiLine_c TspiGetLineDevStatus
  169. @func
  170. This request queries the specified open line device for its current status.
  171. The information returned is global to all addresses on the line.
  172. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  173. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  174. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  175. @parm IN PNDIS_TAPI_GET_LINE_DEV_STATUS | Request |
  176. A pointer to the NDIS_TAPI request structure for this call.
  177. @iex
  178. typedef struct _NDIS_TAPI_GET_LINE_DEV_STATUS
  179. {
  180. IN ULONG ulRequestID;
  181. IN HDRV_LINE hdLine;
  182. OUT LINE_DEV_STATUS LineDevStatus;
  183. } NDIS_TAPI_GET_LINE_DEV_STATUS, *PNDIS_TAPI_GET_LINE_DEV_STATUS;
  184. typedef struct _LINE_DEV_STATUS
  185. {
  186. ULONG ulTotalSize;
  187. ULONG ulNeededSize;
  188. ULONG ulUsedSize;
  189. ULONG ulNumOpens;
  190. ULONG ulOpenMediaModes;
  191. ULONG ulNumActiveCalls;
  192. ULONG ulNumOnHoldCalls;
  193. ULONG ulNumOnHoldPendCalls;
  194. ULONG ulLineFeatures;
  195. ULONG ulNumCallCompletions;
  196. ULONG ulRingMode;
  197. ULONG ulSignalLevel;
  198. ULONG ulBatteryLevel;
  199. ULONG ulRoamMode;
  200. ULONG ulDevStatusFlags;
  201. ULONG ulTerminalModesSize;
  202. ULONG ulTerminalModesOffset;
  203. ULONG ulDevSpecificSize;
  204. ULONG ulDevSpecificOffset;
  205. } LINE_DEV_STATUS, *PLINE_DEV_STATUS;
  206. @rdesc This routine returns one of the following values:
  207. @flag NDIS_STATUS_SUCCESS |
  208. If this function is successful.
  209. <f Note>: A non-zero return value indicates one of the following error codes:
  210. @iex
  211. NDIS_STATUS_TAPI_INVALLINEHANDLE
  212. */
  213. NDIS_STATUS TspiGetLineDevStatus(
  214. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  215. IN PNDIS_TAPI_GET_LINE_DEV_STATUS Request,
  216. OUT PULONG BytesWritten,
  217. OUT PULONG BytesNeeded
  218. )
  219. {
  220. DBG_FUNC("TspiGetLineDevStatus")
  221. PBCHANNEL_OBJECT pBChannel;
  222. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  223. DBG_ENTER(pAdapter);
  224. DBG_PARAMS(pAdapter,
  225. ("\n\thdLine=0x%X\n",
  226. Request->hdLine
  227. ));
  228. /*
  229. // This request must be associated with a line device.
  230. */
  231. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  232. if (pBChannel == NULL)
  233. {
  234. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  235. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  236. }
  237. Request->LineDevStatus.ulNeededSize =
  238. Request->LineDevStatus.ulUsedSize = sizeof(Request->LineDevStatus);
  239. if (Request->LineDevStatus.ulNeededSize > Request->LineDevStatus.ulTotalSize)
  240. {
  241. DBG_PARAMS(pAdapter,
  242. ("STRUCTURETOOSMALL %d<%d\n",
  243. Request->LineDevStatus.ulTotalSize,
  244. Request->LineDevStatus.ulNeededSize));
  245. }
  246. /*
  247. // Return the current line status information.
  248. */
  249. Request->LineDevStatus.ulNumOpens = 1;
  250. Request->LineDevStatus.ulNumActiveCalls =
  251. pBChannel->CallState <= LINECALLSTATE_IDLE ? 0 : 1;
  252. Request->LineDevStatus.ulLineFeatures =
  253. pBChannel->CallState <= LINECALLSTATE_IDLE ?
  254. LINEFEATURE_MAKECALL : 0;
  255. Request->LineDevStatus.ulRingMode =
  256. pBChannel->CallState == LINECALLSTATE_OFFERING ? 1: 0;
  257. Request->LineDevStatus.ulDevStatusFlags =
  258. (pBChannel->DevState & LINEDEVSTATE_CONNECTED) ?
  259. LINEDEVSTATUSFLAGS_CONNECTED : 0;
  260. Request->LineDevStatus.ulDevStatusFlags |=
  261. (pBChannel->DevState & LINEDEVSTATE_INSERVICE) ?
  262. LINEDEVSTATUSFLAGS_INSERVICE : 0;
  263. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  264. return (NDIS_STATUS_SUCCESS);
  265. }
  266. /* @doc INTERNAL TspiLine TspiLine_c TspiSetDefaultMediaDetection
  267. @func
  268. This request informs the miniport of the new set of media modes to detect
  269. for the indicated line (replacing any previous set).
  270. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  271. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  272. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  273. @parm IN PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION | Request |
  274. A pointer to the NDIS_TAPI request structure for this call.
  275. @iex
  276. typedef struct _NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION
  277. {
  278. IN ULONG ulRequestID;
  279. IN HDRV_LINE hdLine;
  280. IN ULONG ulMediaModes;
  281. } NDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION, *PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION;
  282. @rdesc This routine returns one of the following values:
  283. @flag NDIS_STATUS_SUCCESS |
  284. If this function is successful.
  285. <f Note>: A non-zero return value indicates one of the following error codes:
  286. @iex
  287. NDIS_STATUS_TAPI_INVALLINEHANDLE
  288. @comm
  289. <f Note>:
  290. After a miniport NIC driver has received an OPEN request for a line, it
  291. may also receive one or more SET_DEFAULT_MEDIA_DETECTION requests. This
  292. latter request informs the NIC driver of the type(s) of incoming calls,
  293. with respect to media mode, it should indicate to the Connection Wrapper
  294. with the LINE_NEWCALL message. If an incoming call appears with a media
  295. mode type not specified in the last (successfully completed)
  296. SET_DEFAULT_MEDIA_DETECTION request for that line, the miniport should
  297. not indicate the new call to the Connection Wrapper. If a miniport does
  298. not receive a SET_DEFAULT_MEDIA_DETECTION request for a line, it should
  299. not indicate any incoming calls to the Connection Wrapper; that line is
  300. to be used only for outbound calls.
  301. */
  302. NDIS_STATUS TspiSetDefaultMediaDetection(
  303. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  304. IN PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION Request,
  305. OUT PULONG BytesRead,
  306. OUT PULONG BytesNeeded
  307. )
  308. {
  309. DBG_FUNC("TspiSetDefaultMediaDetection")
  310. PBCHANNEL_OBJECT pBChannel;
  311. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  312. DBG_ENTER(pAdapter);
  313. DBG_PARAMS(pAdapter,
  314. ("\n\thdLine=0x%X\n"
  315. "\tulMediaModes=0x%X\n",
  316. Request->hdLine,
  317. Request->ulMediaModes
  318. ));
  319. /*
  320. // This request must be associated with a line device.
  321. */
  322. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  323. if (pBChannel == NULL)
  324. {
  325. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  326. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  327. }
  328. /*
  329. // Don't accept the request for media modes we don't support.
  330. */
  331. if (Request->ulMediaModes & ~pBChannel->MediaModesCaps)
  332. {
  333. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALMEDIAMODE\n"));
  334. return (NDIS_STATUS_TAPI_INVALMEDIAMODE);
  335. }
  336. /*
  337. // Set the media modes mask and make sure the adapter is ready to
  338. // accept incoming calls. If you can detect different medias, you
  339. // will need to notify the approriate interface for the media detected.
  340. */
  341. pBChannel->MediaModesMask = Request->ulMediaModes & pBChannel->MediaModesCaps;
  342. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  343. return (NDIS_STATUS_SUCCESS);
  344. }
  345. /* @doc INTERNAL TspiLine TspiLine_c XXX
  346. @func
  347. This request is invoked by the Connection Wrapper whenever a client
  348. application uses LINEMAPPER as the dwDeviceID in the lineOpen function
  349. to request that lines be scanned to find one that supports the desired
  350. media mode(s) and call parameters. The Connection Wrapper scans based on
  351. the union of the desired media modes and the other media modes currently
  352. being monitored on the line, to give the miniport the opportunity to
  353. indicate if it cannot simultaneously monitor for all of the requested
  354. media modes. If the miniport can monitor for the indicated set of media
  355. modes AND support the capabilities indicated in CallParams, it replies
  356. with a success inidication. It leaves the active media monitoring modes
  357. for the line unchanged.
  358. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  359. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  360. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  361. @parm IN PNDIS_TAPI_CONDITIONAL_MEDIA_DETECTION | Request |
  362. A pointer to the NDIS_TAPI request structure for this call.
  363. @iex
  364. typedef struct _NDIS_TAPI_CONDITIONAL_MEDIA_DETECTION
  365. {
  366. IN ULONG ulRequestID;
  367. IN HDRV_LINE hdLine;
  368. IN ULONG ulMediaModes;
  369. IN LINE_CALL_PARAMS LineCallParams;
  370. } NDIS_TAPI_CONDITIONAL_MEDIA_DETECTION, *PNDIS_TAPI_CONDITIONAL_MEDIA_DETECTION;
  371. typedef struct _LINE_CALL_PARAMS // Defaults:
  372. {
  373. ULONG ulTotalSize; // ---------
  374. ULONG ulBearerMode; // voice
  375. ULONG ulMinRate; // (3.1kHz)
  376. ULONG ulMaxRate; // (3.1kHz)
  377. ULONG ulMediaMode; // interactiveVoice
  378. ULONG ulCallParamFlags; // 0
  379. ULONG ulAddressMode; // addressID
  380. ULONG ulAddressID; // (any available)
  381. LINE_DIAL_PARAMS DialParams; // (0, 0, 0, 0)
  382. ULONG ulOrigAddressSize; // 0
  383. ULONG ulOrigAddressOffset;
  384. ULONG ulDisplayableAddressSize;
  385. ULONG ulDisplayableAddressOffset;
  386. ULONG ulCalledPartySize; // 0
  387. ULONG ulCalledPartyOffset;
  388. ULONG ulCommentSize; // 0
  389. ULONG ulCommentOffset;
  390. ULONG ulUserUserInfoSize; // 0
  391. ULONG ulUserUserInfoOffset;
  392. ULONG ulHighLevelCompSize; // 0
  393. ULONG ulHighLevelCompOffset;
  394. ULONG ulLowLevelCompSize; // 0
  395. ULONG ulLowLevelCompOffset;
  396. ULONG ulDevSpecificSize; // 0
  397. ULONG ulDevSpecificOffset;
  398. } LINE_CALL_PARAMS, *PLINE_CALL_PARAMS;
  399. typedef struct _LINE_DIAL_PARAMS
  400. {
  401. ULONG ulDialPause;
  402. ULONG ulDialSpeed;
  403. ULONG ulDigitDuration;
  404. ULONG ulWaitForDialtone;
  405. } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS;
  406. @rdesc This routine returns one of the following values:
  407. @flag NDIS_STATUS_SUCCESS |
  408. If this function is successful.
  409. <f Note>: A non-zero return value indicates one of the following error codes:
  410. @iex
  411. NDIS_STATUS_TAPI_INVALLINEHANDLE
  412. */
  413. NDIS_STATUS TspiConditionalMediaDetection(
  414. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  415. IN PNDIS_TAPI_CONDITIONAL_MEDIA_DETECTION Request,
  416. OUT PULONG BytesRead,
  417. OUT PULONG BytesNeeded
  418. )
  419. {
  420. DBG_FUNC("TspiConditionalMediaDetection")
  421. PBCHANNEL_OBJECT pBChannel;
  422. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  423. DBG_ENTER(pAdapter);
  424. DBG_PARAMS(pAdapter,
  425. ("\n\thdLine=0x%X\n"
  426. "\tulMediaModes=0x%X\n"
  427. "\tLineCallParams=0x%X\n",
  428. Request->hdLine,
  429. Request->ulMediaModes,
  430. &Request->LineCallParams
  431. ));
  432. /*
  433. // This request must be associated with a line device.
  434. */
  435. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  436. if (pBChannel == NULL)
  437. {
  438. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  439. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  440. }
  441. /*
  442. // We don't expect user user info.
  443. */
  444. ASSERT(Request->LineCallParams.ulUserUserInfoSize == 0);
  445. /*
  446. // Don't accept the request for media modes we don't support.
  447. */
  448. if (Request->ulMediaModes & ~pBChannel->MediaModesCaps)
  449. {
  450. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALMEDIAMODE\n"));
  451. return (NDIS_STATUS_TAPI_INVALMEDIAMODE);
  452. }
  453. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  454. return (NDIS_STATUS_SUCCESS);
  455. }
  456. /* @doc INTERNAL TspiLine TspiLine_c TspiSetStatusMessages
  457. @func
  458. This request enables the Connection Wrapper to specify which notification
  459. messages the miniport should generate for events related to status changes
  460. for the specified line or any of its addresses. By default, address and
  461. line status reporting is initially disabled for a line.
  462. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  463. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  464. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  465. @parm IN PNDIS_TAPI_SET_STATUS_MESSAGES | Request |
  466. A pointer to the NDIS_TAPI request structure for this call.
  467. @iex
  468. typedef struct _NDIS_TAPI_SET_STATUS_MESSAGES
  469. {
  470. IN ULONG ulRequestID;
  471. IN HDRV_LINE hdLine;
  472. IN ULONG ulLineStates;
  473. IN ULONG ulAddressStates;
  474. } NDIS_TAPI_SET_STATUS_MESSAGES, *PNDIS_TAPI_SET_STATUS_MESSAGES;
  475. @rdesc This routine returns one of the following values:
  476. @flag NDIS_STATUS_SUCCESS |
  477. This function always returns success.
  478. */
  479. NDIS_STATUS TspiSetStatusMessages(
  480. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  481. IN PNDIS_TAPI_SET_STATUS_MESSAGES Request,
  482. OUT PULONG BytesRead,
  483. OUT PULONG BytesNeeded
  484. )
  485. {
  486. DBG_FUNC("TspiSetStatusMessages")
  487. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  488. // Holds the result code returned by this function.
  489. PBCHANNEL_OBJECT pBChannel;
  490. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  491. DBG_ENTER(pAdapter);
  492. DBG_PARAMS(pAdapter,
  493. ("\n\thdLine=0x%X\n"
  494. "\tulLineStates=0x%X\n"
  495. "\tulAddressStates=0x%X\n",
  496. Request->hdLine,
  497. Request->ulLineStates,
  498. Request->ulAddressStates
  499. ));
  500. /*
  501. // This request must be associated with a line device.
  502. */
  503. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  504. if (pBChannel == NULL)
  505. {
  506. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  507. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  508. }
  509. /*
  510. // TAPI may pass down more than we are capable of handling.
  511. // We have to accept the request, but can ignore the extras.
  512. */
  513. if (Request->ulLineStates & ~pBChannel->DevStatesCaps)
  514. {
  515. DBG_WARNING(pAdapter, ("ulLineStates=0x%X !< DevStatesCaps=0x%X\n",
  516. Request->ulLineStates, pBChannel->DevStatesCaps));
  517. Result = NDIS_STATUS_TAPI_INVALPARAM;
  518. }
  519. /*
  520. // TAPI may pass down more than we are capable of handling.
  521. // We have to accept the request, but can ignore the extras.
  522. */
  523. if (Request->ulAddressStates & ~pBChannel->AddressStatesCaps)
  524. {
  525. DBG_WARNING(pAdapter, ("ulAddressStates=0x%X !< AddressStatesCaps=0x%X\n",
  526. Request->ulAddressStates, pBChannel->AddressStatesCaps));
  527. Result = NDIS_STATUS_TAPI_INVALPARAM;
  528. }
  529. /*
  530. // Save the new event notification masks so we will only indicate the
  531. // appropriate events.
  532. */
  533. pBChannel->DevStatesMask = Request->ulLineStates & pBChannel->DevStatesCaps;
  534. pBChannel->AddressStatesMask = Request->ulAddressStates & pBChannel->AddressStatesCaps;
  535. DBG_RETURN(pAdapter, Result);
  536. return (Result);
  537. }
  538. /* @doc INTERNAL TspiLine TspiLine_c TspiLineDevStateHandler
  539. @func
  540. <f TspiLineDevStateHandler> will indicate the given LINEDEVSTATE to the
  541. Connection Wrapper if the event has been enabled by the wrapper.
  542. Otherwise the state information is saved, but no indication is made.
  543. */
  544. VOID TspiLineDevStateHandler(
  545. IN PMINIPORT_ADAPTER_OBJECT pAdapter, // @parm
  546. // A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
  547. IN PBCHANNEL_OBJECT pBChannel, // @parm
  548. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  549. IN ULONG LineDevState // @parm
  550. // The <t LINEDEVSTATE> event to be posted to TAPI/WAN.
  551. )
  552. {
  553. DBG_FUNC("TspiLineDevStateHandler")
  554. NDIS_TAPI_EVENT LineEvent;
  555. NDIS_TAPI_EVENT CallEvent;
  556. // The event structure passed to the Connection Wrapper.
  557. ULONG NewCallState = 0;
  558. ULONG StateParam = 0;
  559. // The line state change may cause a call state change as well.
  560. DBG_ENTER(pAdapter);
  561. DBG_PARAMS(pAdapter,
  562. ("#%d OldState=0x%X "
  563. "NewState=0x%X\n",
  564. pBChannel->BChannelIndex,
  565. pBChannel->DevState,
  566. LineDevState
  567. ));
  568. LineEvent.ulParam2 = 0;
  569. LineEvent.ulParam3 = 0;
  570. /*
  571. // Handle the line state transition as needed.
  572. */
  573. switch (LineDevState)
  574. {
  575. case LINEDEVSTATE_RINGING:
  576. /*
  577. // We have an incoming call, see if there's anyone who cares.
  578. */
  579. if (pBChannel->CallState == 0 &&
  580. pBChannel->MediaModesMask)
  581. {
  582. LineEvent.ulParam2 = 1; // only one RingMode
  583. NewCallState = LINECALLSTATE_OFFERING;
  584. }
  585. else
  586. {
  587. DChannelRejectCall(pAdapter->pDChannel, pBChannel);
  588. }
  589. break;
  590. case LINEDEVSTATE_CONNECTED:
  591. /*
  592. // The line has been connected, but we may already know this.
  593. */
  594. if ((pBChannel->DevState & LINEDEVSTATE_CONNECTED) == 0)
  595. {
  596. pBChannel->DevState |= LINEDEVSTATE_CONNECTED;
  597. }
  598. else
  599. {
  600. LineDevState = 0;
  601. }
  602. break;
  603. case LINEDEVSTATE_DISCONNECTED:
  604. /*
  605. // The line has been dis-connected, but we may already know this.
  606. // If not, this will effect any calls on the line.
  607. */
  608. if ((pBChannel->DevState & LINEDEVSTATE_CONNECTED) != 0)
  609. {
  610. pBChannel->DevState &= ~(LINEDEVSTATE_CONNECTED |
  611. LINEDEVSTATE_INSERVICE);
  612. NewCallState = LINECALLSTATE_DISCONNECTED;
  613. StateParam = LINEDISCONNECTMODE_NORMAL;
  614. }
  615. else
  616. {
  617. LineDevState = 0;
  618. }
  619. break;
  620. case LINEDEVSTATE_INSERVICE:
  621. /*
  622. // The line has been placed in service, but we may already know this.
  623. */
  624. if ((pBChannel->DevState & LINEDEVSTATE_INSERVICE) == 0)
  625. {
  626. pBChannel->DevState |= LINEDEVSTATE_INSERVICE;
  627. }
  628. else
  629. {
  630. LineDevState = 0;
  631. }
  632. break;
  633. case LINEDEVSTATE_OUTOFSERVICE:
  634. /*
  635. // The line has been taken out of service, but we may already know this.
  636. // If not, this will effect any calls on the line.
  637. */
  638. if ((pBChannel->DevState & LINEDEVSTATE_INSERVICE) != 0)
  639. {
  640. pBChannel->DevState &= ~LINEDEVSTATE_INSERVICE;
  641. NewCallState = LINECALLSTATE_DISCONNECTED;
  642. StateParam = LINEDISCONNECTMODE_UNKNOWN;
  643. }
  644. else
  645. {
  646. LineDevState = 0;
  647. }
  648. break;
  649. case LINEDEVSTATE_OPEN:
  650. pBChannel->DevState |= LINEDEVSTATE_OPEN;
  651. pAdapter->NumLineOpens++;
  652. break;
  653. case LINEDEVSTATE_CLOSE:
  654. pBChannel->DevState &= ~LINEDEVSTATE_OPEN;
  655. pAdapter->NumLineOpens--;
  656. break;
  657. }
  658. /*
  659. // If this is the first indication of an incoming call, we need to
  660. // let TAPI know about it so we can get a htCall handle associated
  661. // with it.
  662. */
  663. if (pBChannel->DevState & LINEDEVSTATE_OPEN)
  664. {
  665. if (NewCallState == LINECALLSTATE_OFFERING)
  666. {
  667. CallEvent.htLine = pBChannel->htLine;
  668. CallEvent.htCall = (HTAPI_CALL)0;
  669. CallEvent.ulMsg = LINE_NEWCALL;
  670. CallEvent.ulParam1 = (ULONG) (ULONG_PTR) pBChannel;
  671. CallEvent.ulParam2 = 0;
  672. CallEvent.ulParam3 = 0;
  673. NdisMIndicateStatus(
  674. pAdapter->MiniportAdapterHandle,
  675. NDIS_STATUS_TAPI_INDICATION,
  676. &CallEvent,
  677. sizeof(CallEvent)
  678. );
  679. pAdapter->NeedStatusCompleteIndication = TRUE;
  680. pBChannel->htCall = (HTAPI_CALL)CallEvent.ulParam2;
  681. DBG_FILTER(pAdapter, DBG_TAPICALL_ON,
  682. ("#%d Call=0x%X CallState=0x%X NEW_CALL\n",
  683. pBChannel->BChannelIndex,
  684. pBChannel->htCall, pBChannel->CallState));
  685. if (pBChannel->htCall == 0)
  686. {
  687. /*
  688. // TAPI won't accept the call, so toss it.
  689. */
  690. NewCallState = 0;
  691. LineDevState = 0;
  692. }
  693. }
  694. /*
  695. // Only send those line messages TAPI wants to hear about.
  696. */
  697. if (pBChannel->DevStatesMask & LineDevState)
  698. {
  699. LineEvent.htLine = pBChannel->htLine;
  700. LineEvent.htCall = pBChannel->htCall;
  701. LineEvent.ulMsg = LINE_LINEDEVSTATE;
  702. LineEvent.ulParam1 = LineDevState;
  703. NdisMIndicateStatus(
  704. pAdapter->MiniportAdapterHandle,
  705. NDIS_STATUS_TAPI_INDICATION,
  706. &LineEvent,
  707. sizeof(LineEvent)
  708. );
  709. pAdapter->NeedStatusCompleteIndication = TRUE;
  710. DBG_FILTER(pAdapter, DBG_TAPICALL_ON,
  711. ("#%d Line=0x%X LineState=0x%X\n",
  712. pBChannel->BChannelIndex,
  713. pBChannel->htLine, LineDevState));
  714. }
  715. else
  716. {
  717. DBG_NOTICE(pAdapter, ("#%d LINEDEVSTATE=0x%X EVENT NOT ENABLED\n",
  718. pBChannel->BChannelIndex, LineDevState));
  719. }
  720. if (NewCallState != 0)
  721. {
  722. /*
  723. // Check to see if we need to disconnect the call, but only
  724. // if there is one active.
  725. */
  726. if (NewCallState == LINECALLSTATE_DISCONNECTED)
  727. {
  728. if (pBChannel->CallState != 0 &&
  729. pBChannel->CallState != LINECALLSTATE_IDLE &&
  730. pBChannel->CallState != LINECALLSTATE_DISCONNECTED)
  731. {
  732. TspiCallStateHandler(pAdapter, pBChannel,
  733. NewCallState, StateParam);
  734. #if defined(NDIS40_MINIPORT)
  735. /*
  736. // NDISWAN_BUG
  737. // Under some conditions, NDISWAN does not do a CLOSE_CALL,
  738. // so the line would be left unusable if we don't timeout
  739. // and force a close call condition.
  740. */
  741. NdisMSetTimer(&pBChannel->CallTimer, CARD_NO_CLOSECALL_TIMEOUT);
  742. #endif // NDIS50_MINIPORT
  743. }
  744. }
  745. else
  746. {
  747. TspiCallStateHandler(pAdapter, pBChannel,
  748. NewCallState, StateParam);
  749. if (NewCallState == LINECALLSTATE_OFFERING)
  750. {
  751. /*
  752. // If an offered call is not accepted within N seconds, we
  753. // need to force the line back to an idle state.
  754. */
  755. NdisMSetTimer(&pBChannel->CallTimer, pAdapter->NoAcceptTimeOut);
  756. }
  757. }
  758. }
  759. }
  760. DBG_LEAVE(pAdapter);
  761. }