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.

1613 lines
51 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 TspiCall TspiCall_c
  12. @module TspiCall.c |
  13. This module implements the Telephony Service Provider Interface for
  14. Call objects (TspiCall).
  15. @head3 Contents |
  16. @index class,mfunc,func,msg,mdata,struct,enum | TspiCall_c
  17. @end
  18. */
  19. #define __FILEID__ TSPICALL_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 TspiCall TspiCall_c TspiMakeCall
  28. @func
  29. This request places a call on the specified line to the specified
  30. destination address. Optionally, call parameters can be specified if
  31. anything but default call setup parameters are requested.
  32. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  33. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  34. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  35. @parm IN PNDIS_TAPI_MAKE_CALL | Request |
  36. A pointer to the NDIS_TAPI request structure for this call.
  37. @iex
  38. typedef struct _NDIS_TAPI_MAKE_CALL
  39. {
  40. IN ULONG ulRequestID;
  41. IN HDRV_LINE hdLine;
  42. IN HTAPI_CALL htCall;
  43. OUT HDRV_CALL hdCall;
  44. IN ULONG ulDestAddressSize;
  45. IN ULONG ulDestAddressOffset;
  46. IN BOOLEAN bUseDefaultLineCallParams;
  47. IN LINE_CALL_PARAMS LineCallParams;
  48. } NDIS_TAPI_MAKE_CALL, *PNDIS_TAPI_MAKE_CALL;
  49. typedef struct _LINE_CALL_PARAMS // Defaults:
  50. {
  51. ULONG ulTotalSize; // ---------
  52. ULONG ulBearerMode; // voice
  53. ULONG ulMinRate; // (3.1kHz)
  54. ULONG ulMaxRate; // (3.1kHz)
  55. ULONG ulMediaMode; // interactiveVoice
  56. ULONG ulCallParamFlags; // 0
  57. ULONG ulAddressMode; // addressID
  58. ULONG ulAddressID; // (any available)
  59. LINE_DIAL_PARAMS DialParams; // (0, 0, 0, 0)
  60. ULONG ulOrigAddressSize; // 0
  61. ULONG ulOrigAddressOffset;
  62. ULONG ulDisplayableAddressSize;
  63. ULONG ulDisplayableAddressOffset;
  64. ULONG ulCalledPartySize; // 0
  65. ULONG ulCalledPartyOffset;
  66. ULONG ulCommentSize; // 0
  67. ULONG ulCommentOffset;
  68. ULONG ulUserUserInfoSize; // 0
  69. ULONG ulUserUserInfoOffset;
  70. ULONG ulHighLevelCompSize; // 0
  71. ULONG ulHighLevelCompOffset;
  72. ULONG ulLowLevelCompSize; // 0
  73. ULONG ulLowLevelCompOffset;
  74. ULONG ulDevSpecificSize; // 0
  75. ULONG ulDevSpecificOffset;
  76. } LINE_CALL_PARAMS, *PLINE_CALL_PARAMS;
  77. typedef struct _LINE_DIAL_PARAMS
  78. {
  79. ULONG ulDialPause;
  80. ULONG ulDialSpeed;
  81. ULONG ulDigitDuration;
  82. ULONG ulWaitForDialtone;
  83. } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS;
  84. @rdesc This routine returns one of the following values:
  85. @flag NDIS_STATUS_SUCCESS |
  86. If this function is successful.
  87. <f Note>: A non-zero return value indicates one of the following error codes:
  88. @iex
  89. NDIS_STATUS_TAPI_ADDRESSBLOCKED
  90. NDIS_STATUS_TAPI_BEARERMODEUNAVAIL
  91. NDIS_STATUS_TAPI_CALLUNAVAIL
  92. NDIS_STATUS_TAPI_DIALBILLING
  93. NDIS_STATUS_TAPI_DIALQUIET
  94. NDIS_STATUS_TAPI_DIALDIALTONE
  95. NDIS_STATUS_TAPI_DIALPROMPT
  96. NDIS_STATUS_TAPI_INUSE
  97. NDIS_STATUS_TAPI_INVALADDRESSMODE
  98. NDIS_STATUS_TAPI_INVALBEARERMODE
  99. NDIS_STATUS_TAPI_INVALMEDIAMODE
  100. NDIS_STATUS_TAPI_INVALLINESTATE
  101. NDIS_STATUS_TAPI_INVALRATE
  102. NDIS_STATUS_TAPI_INVALLINEHANDLE
  103. NDIS_STATUS_TAPI_INVALADDRESS
  104. NDIS_STATUS_TAPI_INVALADDRESSID
  105. NDIS_STATUS_TAPI_INVALCALLPARAMS
  106. NDIS_STATUS_RESOURCES
  107. NDIS_STATUS_TAPI_OPERATIONUNAVAIL
  108. NDIS_STATUS_FAILURE
  109. NDIS_STATUS_TAPI_RESOURCEUNAVAIL
  110. NDIS_STATUS_TAPI_RATEUNAVAIL
  111. NDIS_STATUS_TAPI_USERUSERINFOTOOBIG
  112. */
  113. NDIS_STATUS TspiMakeCall(
  114. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  115. IN PNDIS_TAPI_MAKE_CALL Request,
  116. OUT PULONG BytesWritten,
  117. OUT PULONG BytesNeeded
  118. )
  119. {
  120. DBG_FUNC("TspiMakeCall")
  121. NDIS_STATUS Status = NDIS_STATUS_TAPI_INVALPARAM;
  122. PLINE_CALL_PARAMS pLineCallParams;
  123. USHORT DialStringLength;
  124. PBCHANNEL_OBJECT pBChannel;
  125. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  126. DBG_ENTER(pAdapter);
  127. DBG_PARAMS(pAdapter,
  128. ("\n\thdLine=0x%X\n"
  129. "\thtCall=0x%X\n"
  130. "\tulDestAddressSize=%d\n"
  131. "\tulDestAddressOffset=0x%X\n"
  132. "\tbUseDefaultLineCallParams=%d\n"
  133. "\tLineCallParams=0x%X:0x%X\n",
  134. Request->hdLine,
  135. Request->htCall,
  136. Request->ulDestAddressSize,
  137. Request->ulDestAddressOffset,
  138. Request->bUseDefaultLineCallParams,
  139. &Request->LineCallParams,
  140. Request
  141. ));
  142. /*
  143. // This request must be associated with a line device.
  144. */
  145. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  146. if (pBChannel == NULL)
  147. {
  148. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  149. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  150. }
  151. /*
  152. // The line must be in-service before we can let this request go thru.
  153. */
  154. if ((pBChannel->DevState & LINEDEVSTATE_INSERVICE) == 0)
  155. {
  156. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINESTATE\n"));
  157. return (NDIS_STATUS_TAPI_INVALLINESTATE);
  158. }
  159. /*
  160. // We should be idle when this call comes down, but if we're out of
  161. // state for some reason, don't let this go any further.
  162. */
  163. if (pBChannel->CallState != 0)
  164. {
  165. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INUSE\n"));
  166. return (NDIS_STATUS_TAPI_INUSE);
  167. }
  168. /*
  169. // Which set of call parameters should we use?
  170. */
  171. if (Request->bUseDefaultLineCallParams)
  172. {
  173. pLineCallParams = &pAdapter->DefaultLineCallParams;
  174. DBG_NOTICE(pAdapter, ("UseDefaultLineCallParams\n"));
  175. }
  176. else
  177. {
  178. pLineCallParams = &Request->LineCallParams;
  179. }
  180. /*
  181. // Make sure the call parameters are valid for us.
  182. */
  183. if (pLineCallParams->ulBearerMode & ~pBChannel->BearerModesCaps)
  184. {
  185. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALBEARERMODE=0x%X\n",
  186. pLineCallParams->ulBearerMode));
  187. return (NDIS_STATUS_TAPI_INVALBEARERMODE);
  188. }
  189. if (pLineCallParams->ulMediaMode & ~pBChannel->MediaModesCaps)
  190. {
  191. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALMEDIAMODE=0x%X\n",
  192. pLineCallParams->ulMediaMode));
  193. return (NDIS_STATUS_TAPI_INVALMEDIAMODE);
  194. }
  195. if (pLineCallParams->ulMinRate > _64KBPS ||
  196. pLineCallParams->ulMinRate > pLineCallParams->ulMaxRate)
  197. {
  198. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALRATE=%d:%d\n",
  199. pLineCallParams->ulMinRate,pLineCallParams->ulMaxRate));
  200. return (NDIS_STATUS_TAPI_INVALRATE);
  201. }
  202. if (pLineCallParams->ulMaxRate && pLineCallParams->ulMaxRate < _56KBPS)
  203. {
  204. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALRATE=%d:%d\n",
  205. pLineCallParams->ulMinRate,pLineCallParams->ulMaxRate));
  206. return (NDIS_STATUS_TAPI_INVALRATE);
  207. }
  208. /*
  209. // Remember the TAPI call connection handle.
  210. */
  211. pBChannel->htCall = Request->htCall;
  212. /*
  213. // Since we only allow one call per line, we use the same handle.
  214. */
  215. Request->hdCall = (HDRV_CALL) pBChannel;
  216. /*
  217. // Dial the number if it's available, otherwise it may come via
  218. // OID_TAPI_DIAL. Be aware the the phone number format may be
  219. // different for other applications. I'm assuming an ASCII digits
  220. // string.
  221. */
  222. DialStringLength = (USHORT) Request->ulDestAddressSize;
  223. if (DialStringLength > 0)
  224. {
  225. PUCHAR pDestAddress;
  226. UCHAR DialString[CARD_MAX_DIAL_DIGITS+1];
  227. // Temporary copy of dial string. One extra for NULL terminator.
  228. pDestAddress = ((PUCHAR)Request) + Request->ulDestAddressOffset;
  229. /*
  230. // Dial the number, but don't include the null terminator.
  231. */
  232. DialStringLength = CardCleanPhoneNumber(DialString,
  233. pDestAddress,
  234. DialStringLength);
  235. if (DialStringLength > 0)
  236. {
  237. /*
  238. // Save the call parameters.
  239. */
  240. pBChannel->MediaMode = pLineCallParams->ulMediaMode;
  241. pBChannel->BearerMode = pLineCallParams->ulBearerMode;
  242. pBChannel->LinkSpeed = pLineCallParams->ulMaxRate == 0 ?
  243. _64KBPS : pLineCallParams->ulMaxRate;
  244. DBG_FILTER(pAdapter, DBG_TAPICALL_ON,
  245. ("#%d Call=0x%X CallState=0x%X DIALING: '%s'\n"
  246. "Rate=%d-%d - MediaMode=0x%X - BearerMode=0x%X\n",
  247. pBChannel->BChannelIndex,
  248. pBChannel->htCall, pBChannel->CallState,
  249. pDestAddress,
  250. Request->LineCallParams.ulMinRate,
  251. Request->LineCallParams.ulMaxRate,
  252. Request->LineCallParams.ulMediaMode,
  253. Request->LineCallParams.ulBearerMode
  254. ));
  255. Status = DChannelMakeCall(pAdapter->pDChannel,
  256. pBChannel,
  257. DialString,
  258. DialStringLength,
  259. pLineCallParams);
  260. }
  261. }
  262. DBG_RETURN(pAdapter, Status);
  263. return (Status);
  264. }
  265. /* @doc INTERNAL TspiCall TspiCall_c TspiDrop
  266. @func
  267. This request drops or disconnects the specified call. User-to-user
  268. information can optionally be transmitted as part of the call disconnect.
  269. This function can be called by the application at any time. When
  270. OID_TAPI_DROP returns with success, the call should be idle.
  271. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  272. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  273. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  274. @parm IN PNDIS_TAPI_DROP | Request |
  275. A pointer to the NDIS_TAPI request structure for this call.
  276. @iex
  277. typedef struct _NDIS_TAPI_DROP
  278. {
  279. IN ULONG ulRequestID;
  280. IN HDRV_CALL hdCall;
  281. IN ULONG ulUserUserInfoSize;
  282. IN UCHAR UserUserInfo[1];
  283. } NDIS_TAPI_DROP, *PNDIS_TAPI_DROP;
  284. @rdesc This routine returns one of the following values:
  285. @flag NDIS_STATUS_SUCCESS |
  286. If this function is successful.
  287. <f Note>: A non-zero return value indicates one of the following error codes:
  288. @iex
  289. NDIS_STATUS_TAPI_INVALCALLHANDLE
  290. */
  291. NDIS_STATUS TspiDrop(
  292. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  293. IN PNDIS_TAPI_DROP Request,
  294. OUT PULONG BytesRead,
  295. OUT PULONG BytesNeeded
  296. )
  297. {
  298. DBG_FUNC("TspiDrop")
  299. PBCHANNEL_OBJECT pBChannel;
  300. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  301. DBG_ENTER(pAdapter);
  302. DBG_PARAMS(pAdapter,
  303. ("\n\thdCall=0x%X\n"
  304. "\tulUserUserInfoSize=%d\n"
  305. "\tUserUserInfo=0x%X\n",
  306. Request->hdCall,
  307. Request->ulUserUserInfoSize,
  308. Request->UserUserInfo
  309. ));
  310. /*
  311. // This request must be associated with a call.
  312. */
  313. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  314. if (pBChannel == NULL)
  315. {
  316. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  317. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  318. }
  319. /*
  320. // The user wants to disconnect, so make it happen cappen.
  321. */
  322. DBG_FILTER(pAdapter, DBG_TAPICALL_ON,
  323. ("#%d Call=0x%X CallState=0x%X\n",
  324. pBChannel->BChannelIndex,
  325. pBChannel->htCall, pBChannel->CallState));
  326. /*
  327. // Drop the call after flushing the transmit and receive buffers.
  328. */
  329. DChannelDropCall(pAdapter->pDChannel, pBChannel);
  330. #if !defined(NDIS50_MINIPORT)
  331. /*
  332. // NDISWAN_BUG
  333. // Under some conditions, NDISWAN does not do a CLOSE_CALL,
  334. // so the line would be left unusable if we don't timeout
  335. // and force a close call condition.
  336. */
  337. NdisMSetTimer(&pBChannel->CallTimer, CARD_NO_CLOSECALL_TIMEOUT);
  338. #endif // NDIS50_MINIPORT
  339. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  340. return (NDIS_STATUS_SUCCESS);
  341. }
  342. /* @doc INTERNAL TspiCall TspiCall_c TspiCloseCall
  343. @func
  344. This request deallocates the call after completing or aborting all
  345. outstanding asynchronous requests on the call.
  346. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  347. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  348. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  349. @parm IN PNDIS_TAPI_CLOSE_CALL | Request |
  350. A pointer to the NDIS_TAPI request structure for this call.
  351. @iex
  352. typedef struct _NDIS_TAPI_CLOSE_CALL
  353. {
  354. IN ULONG ulRequestID;
  355. IN HDRV_CALL hdCall;
  356. } NDIS_TAPI_CLOSE_CALL, *PNDIS_TAPI_CLOSE_CALL;
  357. @rdesc This routine returns one of the following values:
  358. @flag NDIS_STATUS_SUCCESS |
  359. If this function is successful.
  360. <f Note>: A non-zero return value indicates one of the following error codes:
  361. @iex
  362. NDIS_STATUS_TAPI_INVALCALLHANDLE
  363. */
  364. NDIS_STATUS TspiCloseCall(
  365. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  366. IN PNDIS_TAPI_CLOSE_CALL Request,
  367. OUT PULONG BytesRead,
  368. OUT PULONG BytesNeeded
  369. )
  370. {
  371. DBG_FUNC("TspiCloseCall")
  372. PBCHANNEL_OBJECT pBChannel;
  373. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  374. /*
  375. // The results of this call.
  376. */
  377. NDIS_STATUS Status;
  378. DBG_ENTER(pAdapter);
  379. DBG_PARAMS(pAdapter,
  380. ("\n\thdCall=0x%X\n",
  381. Request->hdCall
  382. ));
  383. /*
  384. // This request must be associated with a call.
  385. */
  386. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  387. if (pBChannel == NULL)
  388. {
  389. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  390. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  391. }
  392. /*
  393. // Mark the link as closing, so no more packets will be accepted,
  394. // and when the last transmit is complete, the link will be closed.
  395. */
  396. if (!IsListEmpty(&pBChannel->TransmitBusyList))
  397. {
  398. DBG_FILTER(pAdapter, DBG_TAPICALL_ON,
  399. ("#%d Call=0x%X CallState=0x%X PENDING\n",
  400. pBChannel->BChannelIndex,
  401. pBChannel->htCall, pBChannel->CallState));
  402. pBChannel->CallClosing = TRUE;
  403. Status = NDIS_STATUS_PENDING;
  404. }
  405. else
  406. {
  407. DBG_FILTER(pAdapter, DBG_TAPICALL_ON,
  408. ("#%d Call=0x%X CallState=0x%X CLOSING\n",
  409. pBChannel->BChannelIndex,
  410. pBChannel->htCall, pBChannel->CallState));
  411. DChannelCloseCall(pAdapter->pDChannel, pBChannel);
  412. Status = NDIS_STATUS_SUCCESS;
  413. }
  414. #if !defined(NDIS50_MINIPORT)
  415. {
  416. /*
  417. // NDISWAN_BUG
  418. // Cancel the CARD_NO_CLOSECALL_TIMEOUT.
  419. */
  420. BOOLEAN TimerCancelled;
  421. // Flag tells whether call time-out routine was cancelled.
  422. NdisMCancelTimer(&pBChannel->CallTimer, &TimerCancelled);
  423. }
  424. #endif // NDIS50_MINIPORT
  425. DBG_RETURN(pAdapter, Status);
  426. return (Status);
  427. }
  428. /* @doc INTERNAL TspiCall TspiCall_c TspiAccept
  429. @func
  430. This request accepts the specified offered call. It may optionally send
  431. the specified user-to-user information to the calling party.
  432. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  433. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  434. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  435. @parm IN PNDIS_TAPI_ACCEPT | Request |
  436. A pointer to the NDIS_TAPI request structure for this call.
  437. @iex
  438. typedef struct _NDIS_TAPI_ACCEPT
  439. {
  440. IN ULONG ulRequestID;
  441. IN HDRV_CALL hdCall;
  442. IN ULONG ulUserUserInfoSize;
  443. IN UCHAR UserUserInfo[1];
  444. } NDIS_TAPI_ACCEPT, *PNDIS_TAPI_ACCEPT;
  445. @rdesc This routine returns one of the following values:
  446. @flag NDIS_STATUS_SUCCESS |
  447. If this function is successful.
  448. <f Note>: A non-zero return value indicates one of the following error codes:
  449. @iex
  450. NDIS_STATUS_FAILURE
  451. NDIS_STATUS_TAPI_INVALCALLHANDLE
  452. NDIS_STATUS_TAPI_OPERATIONUNAVAIL
  453. */
  454. NDIS_STATUS TspiAccept(
  455. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  456. IN PNDIS_TAPI_ACCEPT Request,
  457. OUT PULONG BytesRead,
  458. OUT PULONG BytesNeeded
  459. )
  460. {
  461. DBG_FUNC("TspiAccept")
  462. PBCHANNEL_OBJECT pBChannel;
  463. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  464. DBG_ENTER(pAdapter);
  465. DBG_PARAMS(pAdapter,
  466. ("\n\thdCall=0x%X\n"
  467. "\tulUserUserInfoSize=%d\n"
  468. "\tUserUserInfo=0x%X\n",
  469. Request->hdCall,
  470. Request->ulUserUserInfoSize,
  471. Request->UserUserInfo
  472. ));
  473. /*
  474. // This request must be associated with a call.
  475. */
  476. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  477. if (pBChannel == NULL)
  478. {
  479. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  480. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  481. }
  482. /*
  483. // Note that the call has been accepted, we should see and answer soon.
  484. */
  485. DBG_FILTER(pAdapter,DBG_TAPICALL_ON,
  486. ("#%d Call=0x%X CallState=0x%X ACCEPTING\n",
  487. pBChannel->BChannelIndex,
  488. pBChannel->htCall, pBChannel->CallState));
  489. TspiCallStateHandler(pAdapter, pBChannel, LINECALLSTATE_ACCEPTED, 0);
  490. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  491. return (NDIS_STATUS_SUCCESS);
  492. }
  493. /* @doc INTERNAL TspiCall TspiCall_c TspiAnswer
  494. @func
  495. This request answers the specified offering call. It may optionally send
  496. the specified user-to-user information to the calling party.
  497. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  498. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  499. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  500. @parm IN PNDIS_TAPI_ANSWER | Request |
  501. A pointer to the NDIS_TAPI request structure for this call.
  502. @iex
  503. typedef struct _NDIS_TAPI_ANSWER
  504. {
  505. IN ULONG ulRequestID;
  506. IN HDRV_CALL hdCall;
  507. IN ULONG ulUserUserInfoSize;
  508. IN UCHAR UserUserInfo[1];
  509. } NDIS_TAPI_ANSWER, *PNDIS_TAPI_ANSWER;
  510. @rdesc This routine returns one of the following values:
  511. @flag NDIS_STATUS_SUCCESS |
  512. If this function is successful.
  513. <f Note>: A non-zero return value indicates one of the following error codes:
  514. @iex
  515. NDIS_STATUS_TAPI_INVALCALLHANDLE
  516. */
  517. NDIS_STATUS TspiAnswer(
  518. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  519. IN PNDIS_TAPI_ANSWER Request,
  520. OUT PULONG BytesRead,
  521. OUT PULONG BytesNeeded
  522. )
  523. {
  524. DBG_FUNC("TspiAnswer")
  525. PBCHANNEL_OBJECT pBChannel;
  526. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  527. /*
  528. // The results of this call.
  529. */
  530. NDIS_STATUS Status;
  531. DBG_ENTER(pAdapter);
  532. DBG_PARAMS(pAdapter,
  533. ("\n\thdCall=0x%X\n"
  534. "\tulUserUserInfoSize=%d\n"
  535. "\tUserUserInfo=0x%X\n",
  536. Request->hdCall,
  537. Request->ulUserUserInfoSize,
  538. Request->UserUserInfo
  539. ));
  540. /*
  541. // This request must be associated with a call.
  542. */
  543. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  544. if (pBChannel == NULL)
  545. {
  546. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  547. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  548. }
  549. DBG_FILTER(pAdapter,DBG_TAPICALL_ON,
  550. ("#%d Call=0x%X CallState=0x%X ANSWERING\n",
  551. pBChannel->BChannelIndex,
  552. pBChannel->htCall, pBChannel->CallState));
  553. Status = DChannelAnswer(pAdapter->pDChannel, pBChannel);
  554. DBG_RETURN(pAdapter, Status);
  555. return (Status);
  556. }
  557. /* @doc INTERNAL TspiCall TspiCall_c TspiGetCallInfo
  558. @func
  559. This request returns detailed information about the specified call.
  560. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  561. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  562. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  563. @parm IN PNDIS_TAPI_GET_CALL_INFO | Request |
  564. A pointer to the NDIS_TAPI request structure for this call.
  565. @iex
  566. typedef struct _NDIS_TAPI_GET_CALL_INFO
  567. {
  568. IN ULONG ulRequestID;
  569. IN HDRV_CALL hdCall;
  570. OUT LINE_CALL_INFO LineCallInfo;
  571. } NDIS_TAPI_GET_CALL_INFO, *PNDIS_TAPI_GET_CALL_INFO;
  572. typedef struct _LINE_CALL_INFO
  573. {
  574. ULONG ulTotalSize;
  575. ULONG ulNeededSize;
  576. ULONG ulUsedSize;
  577. ULONG hLine;
  578. ULONG ulLineDeviceID;
  579. ULONG ulAddressID;
  580. ULONG ulBearerMode;
  581. ULONG ulRate;
  582. ULONG ulMediaMode;
  583. ULONG ulAppSpecific;
  584. ULONG ulCallID;
  585. ULONG ulRelatedCallID;
  586. ULONG ulCallParamFlags;
  587. ULONG ulCallStates;
  588. ULONG ulMonitorDigitModes;
  589. ULONG ulMonitorMediaModes;
  590. LINE_DIAL_PARAMS DialParams;
  591. ULONG ulOrigin;
  592. ULONG ulReason;
  593. ULONG ulCompletionID;
  594. ULONG ulNumOwners;
  595. ULONG ulNumMonitors;
  596. ULONG ulCountryCode;
  597. ULONG ulTrunk;
  598. ULONG ulCallerIDFlags;
  599. ULONG ulCallerIDSize;
  600. ULONG ulCallerIDOffset;
  601. ULONG ulCallerIDNameSize;
  602. ULONG ulCallerIDNameOffset;
  603. ULONG ulCalledIDFlags;
  604. ULONG ulCalledIDSize;
  605. ULONG ulCalledIDOffset;
  606. ULONG ulCalledIDNameSize;
  607. ULONG ulCalledIDNameOffset;
  608. ULONG ulConnectedIDFlags;
  609. ULONG ulConnectedIDSize;
  610. ULONG ulConnectedIDOffset;
  611. ULONG ulConnectedIDNameSize;
  612. ULONG ulConnectedIDNameOffset;
  613. ULONG ulRedirectionIDFlags;
  614. ULONG ulRedirectionIDSize;
  615. ULONG ulRedirectionIDOffset;
  616. ULONG ulRedirectionIDNameSize;
  617. ULONG ulRedirectionIDNameOffset;
  618. ULONG ulRedirectingIDFlags;
  619. ULONG ulRedirectingIDSize;
  620. ULONG ulRedirectingIDOffset;
  621. ULONG ulRedirectingIDNameSize;
  622. ULONG ulRedirectingIDNameOffset;
  623. ULONG ulAppNameSize;
  624. ULONG ulAppNameOffset;
  625. ULONG ulDisplayableAddressSize;
  626. ULONG ulDisplayableAddressOffset;
  627. ULONG ulCalledPartySize;
  628. ULONG ulCalledPartyOffset;
  629. ULONG ulCommentSize;
  630. ULONG ulCommentOffset;
  631. ULONG ulDisplaySize;
  632. ULONG ulDisplayOffset;
  633. ULONG ulUserUserInfoSize;
  634. ULONG ulUserUserInfoOffset;
  635. ULONG ulHighLevelCompSize;
  636. ULONG ulHighLevelCompOffset;
  637. ULONG ulLowLevelCompSize;
  638. ULONG ulLowLevelCompOffset;
  639. ULONG ulChargingInfoSize;
  640. ULONG ulChargingInfoOffset;
  641. ULONG ulTerminalModesSize;
  642. ULONG ulTerminalModesOffset;
  643. ULONG ulDevSpecificSize;
  644. ULONG ulDevSpecificOffset;
  645. } LINE_CALL_INFO, *PLINE_CALL_INFO;
  646. typedef struct _LINE_DIAL_PARAMS
  647. {
  648. ULONG ulDialPause;
  649. ULONG ulDialSpeed;
  650. ULONG ulDigitDuration;
  651. ULONG ulWaitForDialtone;
  652. } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS;
  653. @rdesc This routine returns one of the following values:
  654. @flag NDIS_STATUS_SUCCESS |
  655. If this function is successful.
  656. <f Note>: A non-zero return value indicates one of the following error codes:
  657. @iex
  658. NDIS_STATUS_FAILURE
  659. NDIS_STATUS_TAPI_INVALCALLHANDLE
  660. */
  661. NDIS_STATUS TspiGetCallInfo(
  662. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  663. IN PNDIS_TAPI_GET_CALL_INFO Request,
  664. OUT PULONG BytesWritten,
  665. OUT PULONG BytesNeeded
  666. )
  667. {
  668. DBG_FUNC("TspiGetCallInfo")
  669. PBCHANNEL_OBJECT pBChannel;
  670. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  671. DBG_ENTER(pAdapter);
  672. DBG_PARAMS(pAdapter,
  673. ("\n\thdCall=0x%X\n",
  674. Request->hdCall
  675. ));
  676. /*
  677. // This request must be associated with a call.
  678. */
  679. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  680. if (pBChannel == NULL)
  681. {
  682. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  683. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  684. }
  685. Request->LineCallInfo.ulNeededSize =
  686. Request->LineCallInfo.ulUsedSize = sizeof(Request->LineCallInfo);
  687. if (Request->LineCallInfo.ulNeededSize > Request->LineCallInfo.ulTotalSize)
  688. {
  689. DBG_PARAMS(pAdapter,
  690. ("STRUCTURETOOSMALL %d<%d\n",
  691. Request->LineCallInfo.ulTotalSize,
  692. Request->LineCallInfo.ulNeededSize));
  693. }
  694. /*
  695. // The link has all the call information we need to return.
  696. */
  697. Request->LineCallInfo.hLine = (ULONG) (ULONG_PTR) pBChannel;
  698. Request->LineCallInfo.ulLineDeviceID = GET_DEVICEID_FROM_BCHANNEL(pAdapter, pBChannel);
  699. Request->LineCallInfo.ulAddressID = TSPI_ADDRESS_ID;
  700. Request->LineCallInfo.ulBearerMode = pBChannel->BearerMode;
  701. Request->LineCallInfo.ulRate = pBChannel->LinkSpeed;
  702. Request->LineCallInfo.ulMediaMode = pBChannel->MediaMode;
  703. Request->LineCallInfo.ulCallParamFlags = LINECALLPARAMFLAGS_IDLE;
  704. Request->LineCallInfo.ulCallStates = pBChannel->CallStatesMask;
  705. Request->LineCallInfo.ulAppSpecific = pBChannel->AppSpecificCallInfo;
  706. /*
  707. // We don't support any of the callerid functions.
  708. */
  709. Request->LineCallInfo.ulCallerIDFlags =
  710. Request->LineCallInfo.ulCalledIDFlags =
  711. Request->LineCallInfo.ulConnectedIDFlags =
  712. Request->LineCallInfo.ulRedirectionIDFlags =
  713. Request->LineCallInfo.ulRedirectingIDFlags = LINECALLPARTYID_UNAVAIL;
  714. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  715. return (NDIS_STATUS_SUCCESS);
  716. }
  717. /* @doc INTERNAL TspiCall TspiCall_c TspiGetCallStatus
  718. @func
  719. This request returns detailed information about the specified call.
  720. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  721. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  722. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  723. @parm IN PNDIS_TAPI_GET_CALL_STATUS | Request |
  724. A pointer to the NDIS_TAPI request structure for this call.
  725. @iex
  726. typedef struct _NDIS_TAPI_GET_CALL_STATUS
  727. {
  728. IN ULONG ulRequestID;
  729. IN HDRV_CALL hdCall;
  730. OUT LINE_CALL_STATUS LineCallStatus;
  731. } NDIS_TAPI_GET_CALL_STATUS, *PNDIS_TAPI_GET_CALL_STATUS;
  732. typedef struct _LINE_CALL_STATUS
  733. {
  734. ULONG ulTotalSize;
  735. ULONG ulNeededSize;
  736. ULONG ulUsedSize;
  737. ULONG ulCallState;
  738. ULONG ulCallStateMode;
  739. ULONG ulCallPrivilege;
  740. ULONG ulCallFeatures;
  741. ULONG ulDevSpecificSize;
  742. ULONG ulDevSpecificOffset;
  743. } LINE_CALL_STATUS, *PLINE_CALL_STATUS;
  744. @rdesc This routine returns one of the following values:
  745. @flag NDIS_STATUS_SUCCESS |
  746. If this function is successful.
  747. <f Note>: A non-zero return value indicates one of the following error codes:
  748. @iex
  749. NDIS_STATUS_FAILURE
  750. NDIS_STATUS_TAPI_INVALCALLHANDLE
  751. */
  752. NDIS_STATUS TspiGetCallStatus(
  753. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  754. IN PNDIS_TAPI_GET_CALL_STATUS Request,
  755. OUT PULONG BytesWritten,
  756. OUT PULONG BytesNeeded
  757. )
  758. {
  759. DBG_FUNC("TspiGetCallStatus")
  760. PBCHANNEL_OBJECT pBChannel;
  761. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  762. DBG_ENTER(pAdapter);
  763. DBG_PARAMS(pAdapter,
  764. ("hdCall=0x%X\n",
  765. Request->hdCall
  766. ));
  767. /*
  768. // This request must be associated with a call.
  769. */
  770. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  771. if (pBChannel == NULL)
  772. {
  773. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  774. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  775. }
  776. Request->LineCallStatus.ulNeededSize =
  777. Request->LineCallStatus.ulUsedSize = sizeof(Request->LineCallStatus);
  778. if (Request->LineCallStatus.ulNeededSize > Request->LineCallStatus.ulTotalSize)
  779. {
  780. DBG_PARAMS(pAdapter,
  781. ("STRUCTURETOOSMALL %d<%d\n",
  782. Request->LineCallStatus.ulTotalSize,
  783. Request->LineCallStatus.ulNeededSize));
  784. }
  785. /*
  786. // The link has all the call information.
  787. */
  788. Request->LineCallStatus.ulCallPrivilege = LINECALLPRIVILEGE_OWNER;
  789. Request->LineCallStatus.ulCallState = pBChannel->CallState;
  790. Request->LineCallStatus.ulCallStateMode = pBChannel->CallStateMode;
  791. /*
  792. // The call features depend on the call state.
  793. */
  794. switch (pBChannel->CallState)
  795. {
  796. case LINECALLSTATE_CONNECTED:
  797. Request->LineCallStatus.ulCallFeatures = LINECALLFEATURE_DROP;
  798. break;
  799. case LINECALLSTATE_OFFERING:
  800. Request->LineCallStatus.ulCallFeatures = LINECALLFEATURE_ACCEPT |
  801. LINECALLFEATURE_ANSWER;
  802. case LINECALLSTATE_ACCEPTED:
  803. Request->LineCallStatus.ulCallFeatures = LINECALLFEATURE_ANSWER;
  804. break;
  805. }
  806. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  807. return (NDIS_STATUS_SUCCESS);
  808. }
  809. /* @doc INTERNAL TspiCall TspiCall_c TspiSetAppSpecific
  810. @func
  811. This request sets the application-specific field of the specified call's
  812. LINECALLINFO structure.
  813. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  814. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  815. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  816. @parm IN PNDIS_TAPI_SET_APP_SPECIFIC | Request |
  817. A pointer to the NDIS_TAPI request structure for this call.
  818. @iex
  819. typedef struct _NDIS_TAPI_SET_APP_SPECIFIC
  820. {
  821. IN ULONG ulRequestID;
  822. IN HDRV_CALL hdCall;
  823. IN ULONG ulAppSpecific;
  824. } NDIS_TAPI_SET_APP_SPECIFIC, *PNDIS_TAPI_SET_APP_SPECIFIC;
  825. @rdesc This routine returns one of the following values:
  826. @flag NDIS_STATUS_SUCCESS |
  827. If this function is successful.
  828. <f Note>: A non-zero return value indicates one of the following error codes:
  829. @iex
  830. NDIS_STATUS_FAILURE
  831. NDIS_STATUS_TAPI_INVALCALLHANDLE
  832. */
  833. NDIS_STATUS TspiSetAppSpecific(
  834. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  835. IN PNDIS_TAPI_SET_APP_SPECIFIC Request,
  836. OUT PULONG BytesRead,
  837. OUT PULONG BytesNeeded
  838. )
  839. {
  840. DBG_FUNC("TspiSetAppSpecific")
  841. PBCHANNEL_OBJECT pBChannel;
  842. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  843. DBG_ENTER(pAdapter);
  844. DBG_PARAMS(pAdapter,
  845. ("\n\thdCall=0x%X\n"
  846. "\tulAppSpecific=%d\n",
  847. Request->hdCall,
  848. Request->ulAppSpecific
  849. ));
  850. /*
  851. // This request must be associated with a call.
  852. */
  853. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  854. if (pBChannel == NULL)
  855. {
  856. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  857. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  858. }
  859. /*
  860. // The app wants us to save a ulong for him to associate with this call.
  861. */
  862. pBChannel->AppSpecificCallInfo = Request->ulAppSpecific;
  863. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  864. return (NDIS_STATUS_SUCCESS);
  865. }
  866. /* @doc INTERNAL TspiCall TspiCall_c TspiSetCallParams
  867. @func
  868. This request sets certain call parameters for an existing call.
  869. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  870. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  871. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  872. @parm IN PNDIS_TAPI_SET_CALL_PARAMS | Request |
  873. A pointer to the NDIS_TAPI request structure for this call.
  874. @iex
  875. typedef struct _NDIS_TAPI_SET_CALL_PARAMS
  876. {
  877. IN ULONG ulRequestID;
  878. IN HDRV_CALL hdCall;
  879. IN ULONG ulBearerMode;
  880. IN ULONG ulMinRate;
  881. IN ULONG ulMaxRate;
  882. IN BOOLEAN bSetLineDialParams;
  883. IN LINE_DIAL_PARAMS LineDialParams;
  884. } NDIS_TAPI_SET_CALL_PARAMS, *PNDIS_TAPI_SET_CALL_PARAMS;
  885. typedef struct _LINE_DIAL_PARAMS
  886. {
  887. ULONG ulDialPause;
  888. ULONG ulDialSpeed;
  889. ULONG ulDigitDuration;
  890. ULONG ulWaitForDialtone;
  891. } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS;
  892. @rdesc This routine returns one of the following values:
  893. @flag NDIS_STATUS_SUCCESS |
  894. If this function is successful.
  895. <f Note>: A non-zero return value indicates one of the following error codes:
  896. @iex
  897. NDIS_STATUS_FAILURE
  898. NDIS_STATUS_TAPI_INVALCALLHANDLE
  899. */
  900. NDIS_STATUS TspiSetCallParams(
  901. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  902. IN PNDIS_TAPI_SET_CALL_PARAMS Request,
  903. OUT PULONG BytesRead,
  904. OUT PULONG BytesNeeded
  905. )
  906. {
  907. DBG_FUNC("TspiSetCallParams")
  908. PBCHANNEL_OBJECT pBChannel;
  909. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  910. DBG_ENTER(pAdapter);
  911. DBG_PARAMS(pAdapter,
  912. ("\n\thdCall=0x%X\n"
  913. "\tulBearerMode=0x%X\n",
  914. "\tulMinRate=%d\n",
  915. "\tulMaxRate=%d\n",
  916. "\tbSetLineDialParams=%d\n",
  917. "\tLineDialParams=0x%X\n",
  918. Request->hdCall,
  919. Request->ulBearerMode,
  920. Request->ulMinRate,
  921. Request->ulMaxRate,
  922. Request->bSetLineDialParams,
  923. Request->LineDialParams
  924. ));
  925. /*
  926. // This request must be associated with a call.
  927. */
  928. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  929. if (pBChannel == NULL)
  930. {
  931. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  932. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  933. }
  934. /*
  935. // Make sure the call parameters are valid for us.
  936. */
  937. if (Request->ulBearerMode & ~pBChannel->BearerModesCaps)
  938. {
  939. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALMEDIAMODE\n"));
  940. return (NDIS_STATUS_TAPI_INVALBEARERMODE);
  941. }
  942. if (Request->ulMinRate > _64KBPS ||
  943. Request->ulMinRate > Request->ulMaxRate)
  944. {
  945. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALRATE=%d:%d\n",
  946. Request->ulMinRate,Request->ulMaxRate));
  947. return (NDIS_STATUS_TAPI_INVALRATE);
  948. }
  949. if (Request->ulMaxRate && Request->ulMaxRate < _56KBPS)
  950. {
  951. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALRATE=%d:%d\n",
  952. Request->ulMinRate,Request->ulMaxRate));
  953. return (NDIS_STATUS_TAPI_INVALRATE);
  954. }
  955. /*
  956. // Make sure we've got an active call on this channel.
  957. */
  958. if (pBChannel->CallState == 0 ||
  959. pBChannel->CallState == LINECALLSTATE_IDLE ||
  960. pBChannel->CallState == LINECALLSTATE_DISCONNECTED)
  961. {
  962. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLSTATE=0x%X\n",
  963. pBChannel->CallState));
  964. return (NDIS_STATUS_TAPI_INVALCALLSTATE);
  965. }
  966. /*
  967. // RASTAPI only places calls through the MAKE_CALL interface.
  968. // So there's nothing to do here for the time being.
  969. */
  970. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  971. return (NDIS_STATUS_SUCCESS);
  972. }
  973. /* @doc INTERNAL TspiCall TspiCall_c TspiSetMediaMode
  974. @func
  975. This request changes a call's media mode as stored in the call's
  976. LINE_CALL_INFO structure.
  977. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  978. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  979. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  980. @parm IN PNDIS_TAPI_SET_MEDIA_MODE | Request |
  981. A pointer to the NDIS_TAPI request structure for this call.
  982. @iex
  983. typedef struct _NDIS_TAPI_SET_MEDIA_MODE
  984. {
  985. IN ULONG ulRequestID;
  986. IN HDRV_CALL hdCall;
  987. IN ULONG ulMediaMode;
  988. } NDIS_TAPI_SET_MEDIA_MODE, *PNDIS_TAPI_SET_MEDIA_MODE;
  989. @rdesc This routine returns one of the following values:
  990. @flag NDIS_STATUS_SUCCESS |
  991. If this function is successful.
  992. <f Note>: A non-zero return value indicates one of the following error codes:
  993. @iex
  994. NDIS_STATUS_FAILURE
  995. NDIS_STATUS_TAPI_INVALCALLHANDLE
  996. */
  997. NDIS_STATUS TspiSetMediaMode(
  998. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  999. IN PNDIS_TAPI_SET_MEDIA_MODE Request,
  1000. OUT PULONG BytesRead,
  1001. OUT PULONG BytesNeeded
  1002. )
  1003. {
  1004. DBG_FUNC("TspiSetMediaMode")
  1005. PBCHANNEL_OBJECT pBChannel;
  1006. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  1007. DBG_ENTER(pAdapter);
  1008. DBG_PARAMS(pAdapter,
  1009. ("\n\thdCall=0x%X\n"
  1010. "\tulMediaMode=0x%X\n",
  1011. Request->hdCall,
  1012. Request->ulMediaMode
  1013. ));
  1014. /*
  1015. // This request must be associated with a call.
  1016. */
  1017. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  1018. if (pBChannel == NULL)
  1019. {
  1020. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  1021. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  1022. }
  1023. /*
  1024. // Don't accept the request for media modes we don't support.
  1025. */
  1026. if (Request->ulMediaMode & ~pBChannel->MediaModesCaps)
  1027. {
  1028. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALMEDIAMODE\n"));
  1029. return (NDIS_STATUS_TAPI_INVALMEDIAMODE);
  1030. }
  1031. /*
  1032. // If you can detect different medias, you will need to setup to use
  1033. // the selected media here.
  1034. */
  1035. pBChannel->MediaMode = Request->ulMediaMode & pBChannel->MediaModesCaps;
  1036. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  1037. return (NDIS_STATUS_SUCCESS);
  1038. }
  1039. /* @doc INTERNAL TspiCall TspiCall_c TspiCallStateHandler
  1040. @func
  1041. <f TspiCallStateHandler> will indicate the given LINECALLSTATE to the
  1042. Connection Wrapper if the event has been enabled by the wrapper.
  1043. Otherwise the state information is saved, but no indication is made.
  1044. */
  1045. VOID TspiCallStateHandler(
  1046. IN PMINIPORT_ADAPTER_OBJECT pAdapter, // @parm
  1047. // A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
  1048. IN PBCHANNEL_OBJECT pBChannel, // @parm
  1049. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  1050. IN ULONG CallState, // @parm
  1051. // The LINECALLSTATE event to be posted to TAPI/WAN.
  1052. IN ULONG StateParam // @parm
  1053. // This value depends on the event being posted, and some events will
  1054. // pass in zero if they don't use this parameter.
  1055. )
  1056. {
  1057. DBG_FUNC("TspiCallStateHandler")
  1058. NDIS_TAPI_EVENT CallEvent;
  1059. // The event structure passed to the Connection Wrapper.
  1060. BOOLEAN TimerCancelled;
  1061. // Flag tells whether call time-out routine was cancelled.
  1062. DBG_ENTER(pAdapter);
  1063. DBG_PARAMS(pAdapter,
  1064. ("#%d Call=0x%X CallState=0x%X "
  1065. "NewCallState=0x%X Param=0x%X\n",
  1066. pBChannel->BChannelIndex,
  1067. pBChannel->htCall,
  1068. pBChannel->CallState,
  1069. CallState, StateParam
  1070. ));
  1071. /*
  1072. // Cancel any call time-outs events associated with this link.
  1073. // Don't cancel for network status indications.
  1074. */
  1075. if (CallState != LINECALLSTATE_PROCEEDING &&
  1076. CallState != LINECALLSTATE_RINGBACK &&
  1077. CallState != LINECALLSTATE_UNKNOWN)
  1078. {
  1079. NdisMCancelTimer(&pBChannel->CallTimer, &TimerCancelled);
  1080. }
  1081. /*
  1082. // Init the optional parameters. They will be set as needed below.
  1083. */
  1084. CallEvent.ulParam2 = StateParam;
  1085. CallEvent.ulParam3 = pBChannel->MediaMode;
  1086. /*
  1087. // OUTGOING) The expected sequence of events for outgoing calls is:
  1088. // 0, LINECALLSTATE_DIALTONE, LINECALLSTATE_DIALING,
  1089. // LINECALLSTATE_PROCEEDING, LINECALLSTATE_RINGBACK,
  1090. // LINECALLSTATE_CONNECTED, LINECALLSTATE_DISCONNECTED,
  1091. // LINECALLSTATE_IDLE
  1092. //
  1093. // INCOMING) The expected sequence of events for incoming calls is:
  1094. // 0, LINECALLSTATE_OFFERING, LINECALLSTATE_ACCEPTED,
  1095. // LINECALLSTATE_CONNECTED, LINECALLSTATE_DISCONNECTED,
  1096. // LINECALLSTATE_IDLE
  1097. //
  1098. // Under certain failure conditions, these sequences may be violated.
  1099. // So I used ASSERTs to verify the normal state transitions which will
  1100. // cause a debug break point if an unusual transition is detected.
  1101. */
  1102. switch (CallState)
  1103. {
  1104. case 0:
  1105. case LINECALLSTATE_IDLE:
  1106. /*
  1107. // Make sure that an idle line is disconnected.
  1108. */
  1109. if (pBChannel->CallState != 0 &&
  1110. pBChannel->CallState != LINECALLSTATE_IDLE &&
  1111. pBChannel->CallState != LINECALLSTATE_DISCONNECTED)
  1112. {
  1113. DBG_WARNING(pAdapter, ("#%d NOT DISCONNECTED OldState=0x%X\n",
  1114. pBChannel->BChannelIndex, pBChannel->CallState));
  1115. TspiCallStateHandler(pAdapter, pBChannel,
  1116. LINECALLSTATE_DISCONNECTED,
  1117. LINEDISCONNECTMODE_UNKNOWN);
  1118. }
  1119. pBChannel->CallStateMode = 0;
  1120. break;
  1121. case LINECALLSTATE_DIALTONE:
  1122. ASSERT(pBChannel->CallState == 0);
  1123. break;
  1124. case LINECALLSTATE_DIALING:
  1125. ASSERT(pBChannel->CallState == 0 ||
  1126. pBChannel->CallState == LINECALLSTATE_DIALTONE);
  1127. break;
  1128. case LINECALLSTATE_PROCEEDING:
  1129. ASSERT(pBChannel->CallState == LINECALLSTATE_DIALING ||
  1130. pBChannel->CallState == LINECALLSTATE_PROCEEDING);
  1131. break;
  1132. case LINECALLSTATE_RINGBACK:
  1133. ASSERT(pBChannel->CallState == LINECALLSTATE_DIALING ||
  1134. pBChannel->CallState == LINECALLSTATE_PROCEEDING);
  1135. break;
  1136. case LINECALLSTATE_BUSY:
  1137. ASSERT(pBChannel->CallState == LINECALLSTATE_DIALING ||
  1138. pBChannel->CallState == LINECALLSTATE_PROCEEDING);
  1139. pBChannel->CallStateMode = StateParam;
  1140. break;
  1141. case LINECALLSTATE_CONNECTED:
  1142. ASSERT(pBChannel->CallState == LINECALLSTATE_DIALING ||
  1143. pBChannel->CallState == LINECALLSTATE_RINGBACK ||
  1144. pBChannel->CallState == LINECALLSTATE_PROCEEDING ||
  1145. pBChannel->CallState == LINECALLSTATE_OFFERING ||
  1146. pBChannel->CallState == LINECALLSTATE_ACCEPTED);
  1147. pBChannel->CallStateMode = 0;
  1148. break;
  1149. case LINECALLSTATE_DISCONNECTED:
  1150. ASSERT(pBChannel->CallState == 0 ||
  1151. pBChannel->CallState == LINECALLSTATE_IDLE ||
  1152. pBChannel->CallState == LINECALLSTATE_DIALING ||
  1153. pBChannel->CallState == LINECALLSTATE_RINGBACK ||
  1154. pBChannel->CallState == LINECALLSTATE_PROCEEDING ||
  1155. pBChannel->CallState == LINECALLSTATE_OFFERING ||
  1156. pBChannel->CallState == LINECALLSTATE_ACCEPTED ||
  1157. pBChannel->CallState == LINECALLSTATE_CONNECTED ||
  1158. pBChannel->CallState == LINECALLSTATE_DISCONNECTED);
  1159. if (pBChannel->CallState != 0 &&
  1160. pBChannel->CallState != LINECALLSTATE_IDLE &&
  1161. pBChannel->CallState != LINECALLSTATE_DISCONNECTED)
  1162. {
  1163. pBChannel->CallStateMode = StateParam;
  1164. }
  1165. else
  1166. {
  1167. // Don't do anything if there is no call on this line.
  1168. CallState = pBChannel->CallState;
  1169. }
  1170. break;
  1171. case LINECALLSTATE_OFFERING:
  1172. ASSERT(pBChannel->CallState == 0);
  1173. break;
  1174. case LINECALLSTATE_ACCEPTED:
  1175. ASSERT(pBChannel->CallState == LINECALLSTATE_OFFERING);
  1176. break;
  1177. case LINECALLSTATE_UNKNOWN:
  1178. // Unknown call state doesn't cause any change here.
  1179. CallState = pBChannel->CallState;
  1180. break;
  1181. default:
  1182. DBG_ERROR(pAdapter, ("#%d UNKNOWN CALLSTATE=0x%X IGNORED\n",
  1183. pBChannel->BChannelIndex, CallState));
  1184. CallState = pBChannel->CallState;
  1185. break;
  1186. }
  1187. /*
  1188. // Change the current CallState and notify the Connection Wrapper if it
  1189. // wants to know about this event.
  1190. */
  1191. if (pBChannel->CallState != CallState)
  1192. {
  1193. pBChannel->CallState = CallState;
  1194. if (pBChannel->CallStatesMask & CallState)
  1195. {
  1196. CallEvent.htLine = pBChannel->htLine;
  1197. CallEvent.htCall = pBChannel->htCall;
  1198. CallEvent.ulMsg = LINE_CALLSTATE;
  1199. CallEvent.ulParam1 = CallState;
  1200. NdisMIndicateStatus(
  1201. pAdapter->MiniportAdapterHandle,
  1202. NDIS_STATUS_TAPI_INDICATION,
  1203. &CallEvent,
  1204. sizeof(CallEvent)
  1205. );
  1206. pAdapter->NeedStatusCompleteIndication = TRUE;
  1207. }
  1208. else
  1209. {
  1210. DBG_NOTICE(pAdapter, ("#%d LINE_CALLSTATE=0x%X EVENT NOT ENABLED\n",
  1211. pBChannel->BChannelIndex, CallState));
  1212. }
  1213. }
  1214. DBG_LEAVE(pAdapter);
  1215. }
  1216. /* @doc INTERNAL TspiCall TspiCall_c TspiCallTimerHandler
  1217. @func
  1218. <f TspiCallTimerHandler> is called when the CallTimer timeout occurs.
  1219. It will handle the event according to the current CallState and make
  1220. the necessary indications and changes to the call state.
  1221. */
  1222. VOID TspiCallTimerHandler(
  1223. IN PVOID SystemSpecific1, // @parm
  1224. // UNREFERENCED_PARAMETER
  1225. IN PBCHANNEL_OBJECT pBChannel, // @parm
  1226. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  1227. IN PVOID SystemSpecific2, // @parm
  1228. // UNREFERENCED_PARAMETER
  1229. IN PVOID SystemSpecific3 // @parm
  1230. // UNREFERENCED_PARAMETER
  1231. )
  1232. {
  1233. DBG_FUNC("TspiCallTimerHandler")
  1234. PMINIPORT_ADAPTER_OBJECT pAdapter;
  1235. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  1236. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  1237. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  1238. DBG_ENTER(pAdapter);
  1239. DBG_ERROR(pAdapter, ("#%d TIMEOUT CallState=0x%X\n",
  1240. pBChannel->BChannelIndex, pBChannel->CallState));
  1241. switch (pBChannel->CallState)
  1242. {
  1243. case LINECALLSTATE_DIALTONE:
  1244. case LINECALLSTATE_DIALING:
  1245. #if !defined(NDIS50_MINIPORT)
  1246. // NDISWAN_BUG
  1247. // NDIS will hang if we try to disconnect before proceeding state!
  1248. TspiCallStateHandler(pAdapter, pBChannel, LINECALLSTATE_PROCEEDING, 0);
  1249. // Fall through.
  1250. #endif // NDIS50_MINIPORT
  1251. case LINECALLSTATE_PROCEEDING:
  1252. case LINECALLSTATE_RINGBACK:
  1253. /*
  1254. // We did not get a connect from remote end,
  1255. // so hangup and abort the call.
  1256. */
  1257. LinkLineError(pBChannel, WAN_ERROR_TIMEOUT);
  1258. TspiCallStateHandler(pAdapter, pBChannel, LINECALLSTATE_IDLE, 0);
  1259. break;
  1260. case LINECALLSTATE_OFFERING:
  1261. case LINECALLSTATE_ACCEPTED:
  1262. /*
  1263. // Call has been offered, but no one has answered, so reject the call.
  1264. // And
  1265. */
  1266. DChannelRejectCall(pAdapter->pDChannel, pBChannel);
  1267. TspiCallStateHandler(pAdapter, pBChannel, 0, 0);
  1268. break;
  1269. case LINECALLSTATE_DISCONNECTED:
  1270. TspiCallStateHandler(pAdapter, pBChannel, LINECALLSTATE_IDLE, 0);
  1271. break;
  1272. default:
  1273. break;
  1274. }
  1275. DBG_LEAVE(pAdapter);
  1276. UNREFERENCED_PARAMETER(SystemSpecific1);
  1277. UNREFERENCED_PARAMETER(SystemSpecific2);
  1278. UNREFERENCED_PARAMETER(SystemSpecific3);
  1279. }