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

620 lines
19 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 TspiAddr TspiAddr_c
  12. @module TspiAddr.c |
  13. This module implements the Telephony Service Provider Interface for
  14. Address objects.
  15. @head3 Contents |
  16. @index class,mfunc,func,msg,mdata,struct,enum | TspiAddr_c
  17. @end
  18. */
  19. #define __FILEID__ TSPIADDR_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 TspiAddr TspiAddr_c TspiGetAddressID
  28. @func
  29. This request returns the address ID associated with address in a different
  30. format on the specified line.
  31. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  32. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  33. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  34. @parm IN PNDIS_TAPI_GET_ADDRESS_ID | Request |
  35. A pointer to the NDIS_TAPI request structure for this call.
  36. @iex
  37. typedef struct _NDIS_TAPI_GET_ADDRESS_ID
  38. {
  39. IN ULONG ulRequestID;
  40. IN HDRV_LINE hdLine;
  41. OUT ULONG ulAddressID;
  42. IN ULONG ulAddressMode;
  43. IN ULONG ulAddressSize;
  44. IN CHAR szAddress[1];
  45. } NDIS_TAPI_GET_ADDRESS_ID, *PNDIS_TAPI_GET_ADDRESS_ID;
  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_FAILURE
  52. NDIS_STATUS_TAPI_INVALLINEHANDLE
  53. NDIS_STATUS_TAPI_RESOURCEUNAVAIL
  54. */
  55. NDIS_STATUS TspiGetAddressID(
  56. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  57. IN PNDIS_TAPI_GET_ADDRESS_ID Request,
  58. OUT PULONG BytesWritten,
  59. OUT PULONG BytesNeeded
  60. )
  61. {
  62. DBG_FUNC("TspiGetAddressID")
  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\thdLine=0x%X\n"
  68. "\tulAddressMode=0x%X\n"
  69. "\tulAddressSize=%d\n"
  70. "\tszAddress=0x%X\n",
  71. Request->hdLine,
  72. Request->ulAddressMode,
  73. Request->ulAddressSize,
  74. Request->szAddress
  75. ));
  76. /*
  77. // This request must be associated with a line device.
  78. */
  79. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  80. if (pBChannel == NULL)
  81. {
  82. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  83. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  84. }
  85. /*
  86. // We only support ID mode.
  87. */
  88. if (Request->ulAddressMode != LINEADDRESSMODE_DIALABLEADDR)
  89. {
  90. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_FAILURE\n"));
  91. return (NDIS_STATUS_FAILURE);
  92. }
  93. /*
  94. // Make sure we have enough room set aside for this address string.
  95. */
  96. if (Request->ulAddressSize > sizeof(pBChannel->pTapiLineAddress)-1)
  97. {
  98. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_RESOURCEUNAVAIL\n"));
  99. return (NDIS_STATUS_TAPI_RESOURCEUNAVAIL);
  100. }
  101. /*
  102. // This driver only supports one address per link.
  103. */
  104. Request->ulAddressID = TSPI_ADDRESS_ID;
  105. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  106. return (NDIS_STATUS_SUCCESS);
  107. }
  108. /* @doc INTERNAL TspiAddr TspiAddr_c TspiGetAddressCaps
  109. @func
  110. This request queries the specified address on the specified line device
  111. to determine its telephony capabilities.
  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_GET_ADDRESS_CAPS | Request |
  116. A pointer to the NDIS_TAPI request structure for this call.
  117. @iex
  118. typedef struct _NDIS_TAPI_GET_ADDRESS_CAPS
  119. {
  120. IN ULONG ulRequestID;
  121. IN ULONG ulDeviceID;
  122. IN ULONG ulAddressID;
  123. IN ULONG ulExtVersion;
  124. OUT LINE_ADDRESS_CAPS LineAddressCaps;
  125. } NDIS_TAPI_GET_ADDRESS_CAPS, *PNDIS_TAPI_GET_ADDRESS_CAPS;
  126. typedef struct _LINE_ADDRESS_CAPS
  127. {
  128. ULONG ulTotalSize;
  129. ULONG ulNeededSize;
  130. ULONG ulUsedSize;
  131. ULONG ulLineDeviceID;
  132. ULONG ulAddressSize;
  133. ULONG ulAddressOffset;
  134. ULONG ulDevSpecificSize;
  135. ULONG ulDevSpecificOffset;
  136. ULONG ulAddressSharing;
  137. ULONG ulAddressStates;
  138. ULONG ulCallInfoStates;
  139. ULONG ulCallerIDFlags;
  140. ULONG ulCalledIDFlags;
  141. ULONG ulConnectedIDFlags;
  142. ULONG ulRedirectionIDFlags;
  143. ULONG ulRedirectingIDFlags;
  144. ULONG ulCallStates;
  145. ULONG ulDialToneModes;
  146. ULONG ulBusyModes;
  147. ULONG ulSpecialInfo;
  148. ULONG ulDisconnectModes;
  149. ULONG ulMaxNumActiveCalls;
  150. ULONG ulMaxNumOnHoldCalls;
  151. ULONG ulMaxNumOnHoldPendingCalls;
  152. ULONG ulMaxNumConference;
  153. ULONG ulMaxNumTransConf;
  154. ULONG ulAddrCapFlags;
  155. ULONG ulCallFeatures;
  156. ULONG ulRemoveFromConfCaps;
  157. ULONG ulRemoveFromConfState;
  158. ULONG ulTransferModes;
  159. ULONG ulParkModes;
  160. ULONG ulForwardModes;
  161. ULONG ulMaxForwardEntries;
  162. ULONG ulMaxSpecificEntries;
  163. ULONG ulMinFwdNumRings;
  164. ULONG ulMaxFwdNumRings;
  165. ULONG ulMaxCallCompletions;
  166. ULONG ulCallCompletionConds;
  167. ULONG ulCallCompletionModes;
  168. ULONG ulNumCompletionMessages;
  169. ULONG ulCompletionMsgTextEntrySize;
  170. ULONG ulCompletionMsgTextSize;
  171. ULONG ulCompletionMsgTextOffset;
  172. } LINE_ADDRESS_CAPS, *PLINE_ADDRESS_CAPS;
  173. @rdesc This routine returns one of the following values:
  174. @flag NDIS_STATUS_SUCCESS |
  175. If this function is successful.
  176. <f Note>: A non-zero return value indicates one of the following error codes:
  177. @iex
  178. NDIS_STATUS_TAPI_INVALADDRESSID
  179. NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION
  180. NDIS_STATUS_TAPI_NODEVICE
  181. */
  182. NDIS_STATUS TspiGetAddressCaps(
  183. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  184. IN PNDIS_TAPI_GET_ADDRESS_CAPS Request,
  185. OUT PULONG BytesWritten,
  186. OUT PULONG BytesNeeded
  187. )
  188. {
  189. DBG_FUNC("TspiGetAddressCaps")
  190. PBCHANNEL_OBJECT pBChannel;
  191. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  192. UINT AddressLength;
  193. // Length of the address string assigned to this line device.
  194. DBG_ENTER(pAdapter);
  195. DBG_PARAMS(pAdapter,
  196. ("\n\tulDeviceID=%d\n"
  197. "\tulAddressID=%d\n"
  198. "\tulExtVersion=0x%X\n",
  199. Request->ulDeviceID,
  200. Request->ulAddressID,
  201. Request->ulExtVersion
  202. ));
  203. /*
  204. // Make sure the address is within range - we only support one per line.
  205. */
  206. if (Request->ulAddressID >= TSPI_NUM_ADDRESSES)
  207. {
  208. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALADDRESSID\n"));
  209. return (NDIS_STATUS_TAPI_INVALADDRESSID);
  210. }
  211. /*
  212. // This request must be associated with a line device.
  213. */
  214. pBChannel = GET_BCHANNEL_FROM_DEVICEID(pAdapter, Request->ulDeviceID);
  215. if (pBChannel == NULL)
  216. {
  217. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_NODEVICE\n"));
  218. return (NDIS_STATUS_TAPI_NODEVICE);
  219. }
  220. Request->LineAddressCaps.ulNeededSize =
  221. Request->LineAddressCaps.ulUsedSize = sizeof(Request->LineAddressCaps);
  222. Request->LineAddressCaps.ulLineDeviceID = GET_DEVICEID_FROM_BCHANNEL(pAdapter, pBChannel);
  223. /*
  224. // Return the various address capabilites for the adapter.
  225. */
  226. Request->LineAddressCaps.ulAddressSharing = LINEADDRESSSHARING_PRIVATE;
  227. Request->LineAddressCaps.ulAddressStates = pBChannel->AddressStatesCaps;
  228. Request->LineAddressCaps.ulCallStates = pBChannel->CallStatesCaps;
  229. Request->LineAddressCaps.ulDialToneModes = LINEDIALTONEMODE_NORMAL;
  230. Request->LineAddressCaps.ulDisconnectModes =
  231. LINEDISCONNECTMODE_NORMAL |
  232. LINEDISCONNECTMODE_UNKNOWN |
  233. LINEDISCONNECTMODE_BUSY |
  234. LINEDISCONNECTMODE_NOANSWER;
  235. /*
  236. // This driver does not support conference calls, transfers, or holds.
  237. */
  238. Request->LineAddressCaps.ulMaxNumActiveCalls = 1;
  239. Request->LineAddressCaps.ulAddrCapFlags = LINEADDRCAPFLAGS_DIALED;
  240. Request->LineAddressCaps.ulCallFeatures = LINECALLFEATURE_ACCEPT |
  241. LINECALLFEATURE_ANSWER |
  242. LINECALLFEATURE_DROP;
  243. /*
  244. // RASTAPI requires the "I-L-A" be placed in the Address field at the end
  245. // of this structure. Where:
  246. // I = The device intance assigned to this adapter in the registry
  247. // \LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\I
  248. // L = The device line number associated with this line (1..NumLines)
  249. // A = The address (channel) to be used on this line (0..NumAddresses-1)
  250. */
  251. AddressLength = strlen(pBChannel->pTapiLineAddress);
  252. Request->LineAddressCaps.ulNeededSize += AddressLength;
  253. *BytesNeeded += AddressLength;
  254. if (Request->LineAddressCaps.ulNeededSize <= Request->LineAddressCaps.ulTotalSize)
  255. {
  256. Request->LineAddressCaps.ulUsedSize += AddressLength;
  257. Request->LineAddressCaps.ulAddressSize = AddressLength;
  258. Request->LineAddressCaps.ulAddressOffset = sizeof(Request->LineAddressCaps);
  259. NdisMoveMemory((PUCHAR) &Request->LineAddressCaps +
  260. Request->LineAddressCaps.ulAddressOffset,
  261. pBChannel->pTapiLineAddress,
  262. AddressLength
  263. );
  264. }
  265. else
  266. {
  267. DBG_PARAMS(pAdapter,
  268. ("STRUCTURETOOSMALL %d<%d\n",
  269. Request->LineAddressCaps.ulTotalSize,
  270. Request->LineAddressCaps.ulNeededSize));
  271. }
  272. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  273. return (NDIS_STATUS_SUCCESS);
  274. }
  275. /* @doc INTERNAL TspiAddr TspiAddr_c TspiGetAddressStatus
  276. @func
  277. This request queries the specified address for its current status.
  278. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  279. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  280. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  281. @parm IN PNDIS_TAPI_GET_ADDRESS_STATUS | Request |
  282. A pointer to the NDIS_TAPI request structure for this call.
  283. @iex
  284. typedef struct _NDIS_TAPI_GET_ADDRESS_STATUS
  285. {
  286. IN ULONG ulRequestID;
  287. IN HDRV_LINE hdLine;
  288. IN ULONG ulAddressID;
  289. OUT LINE_ADDRESS_STATUS LineAddressStatus;
  290. } NDIS_TAPI_GET_ADDRESS_STATUS, *PNDIS_TAPI_GET_ADDRESS_STATUS;
  291. typedef struct _LINE_ADDRESS_STATUS
  292. {
  293. ULONG ulTotalSize;
  294. ULONG ulNeededSize;
  295. ULONG ulUsedSize;
  296. ULONG ulNumInUse;
  297. ULONG ulNumActiveCalls;
  298. ULONG ulNumOnHoldCalls;
  299. ULONG ulNumOnHoldPendCalls;
  300. ULONG ulAddressFeatures;
  301. ULONG ulNumRingsNoAnswer;
  302. ULONG ulForwardNumEntries;
  303. ULONG ulForwardSize;
  304. ULONG ulForwardOffset;
  305. ULONG ulTerminalModesSize;
  306. ULONG ulTerminalModesOffset;
  307. ULONG ulDevSpecificSize;
  308. ULONG ulDevSpecificOffset;
  309. } LINE_ADDRESS_STATUS, *PLINE_ADDRESS_STATUS;
  310. @rdesc This routine returns one of the following values:
  311. @flag NDIS_STATUS_SUCCESS |
  312. If this function is successful.
  313. <f Note>: A non-zero return value indicates one of the following error codes:
  314. @iex
  315. NDIS_STATUS_FAILURE
  316. NDIS_STATUS_TAPI_INVALLINEHANDLE
  317. NDIS_STATUS_TAPI_INVALADDRESSID
  318. */
  319. NDIS_STATUS TspiGetAddressStatus(
  320. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  321. IN PNDIS_TAPI_GET_ADDRESS_STATUS Request,
  322. OUT PULONG BytesWritten,
  323. OUT PULONG BytesNeeded
  324. )
  325. {
  326. DBG_FUNC("TspiGetAddressStatus")
  327. PBCHANNEL_OBJECT pBChannel;
  328. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  329. DBG_ENTER(pAdapter);
  330. DBG_PARAMS(pAdapter,
  331. ("\n\thdLine=0x%X\n"
  332. "\tulAddressID=%d\n",
  333. Request->hdLine,
  334. Request->ulAddressID
  335. ));
  336. /*
  337. // This request must be associated with a line device.
  338. */
  339. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  340. if (pBChannel == NULL)
  341. {
  342. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  343. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  344. }
  345. /*
  346. // Make sure the address is within range - we only support one per line.
  347. */
  348. if (Request->ulAddressID >= TSPI_NUM_ADDRESSES)
  349. {
  350. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALADDRESSID\n"));
  351. return (NDIS_STATUS_TAPI_INVALADDRESSID);
  352. }
  353. Request->LineAddressStatus.ulNeededSize =
  354. Request->LineAddressStatus.ulUsedSize = sizeof(Request->LineAddressStatus);
  355. if (Request->LineAddressStatus.ulNeededSize > Request->LineAddressStatus.ulTotalSize)
  356. {
  357. DBG_PARAMS(pAdapter,
  358. ("STRUCTURETOOSMALL %d<%d\n",
  359. Request->LineAddressStatus.ulTotalSize,
  360. Request->LineAddressStatus.ulNeededSize));
  361. }
  362. /*
  363. // Return the current status information for the line.
  364. */
  365. Request->LineAddressStatus.ulNumInUse =
  366. pBChannel->CallState <= LINECALLSTATE_IDLE ? 0 : 1;
  367. Request->LineAddressStatus.ulNumActiveCalls =
  368. pBChannel->CallState <= LINECALLSTATE_IDLE ? 0 : 1;
  369. Request->LineAddressStatus.ulAddressFeatures =
  370. pBChannel->CallState <= LINECALLSTATE_IDLE ?
  371. LINEADDRFEATURE_MAKECALL : 0;
  372. Request->LineAddressStatus.ulNumRingsNoAnswer = 999;
  373. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  374. return (NDIS_STATUS_SUCCESS);
  375. }
  376. /* @doc INTERNAL TspiAddr TspiAddr_c TspiGetCallAddressID
  377. @func
  378. This request retrieves the address ID for the indicated call.
  379. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  380. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  381. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  382. @parm IN PNDIS_TAPI_GET_CALL_ADDRESS_ID | Request |
  383. A pointer to the NDIS_TAPI request structure for this call.
  384. @iex
  385. typedef struct _NDIS_TAPI_GET_CALL_ADDRESS_ID
  386. {
  387. IN ULONG ulRequestID;
  388. IN HDRV_CALL hdCall;
  389. OUT ULONG ulAddressID;
  390. } NDIS_TAPI_GET_CALL_ADDRESS_ID, *PNDIS_TAPI_GET_CALL_ADDRESS_ID;
  391. @rdesc This routine returns one of the following values:
  392. @flag NDIS_STATUS_SUCCESS |
  393. If this function is successful.
  394. <f Note>: A non-zero return value indicates one of the following error codes:
  395. @iex
  396. NDIS_STATUS_FAILURE
  397. NDIS_STATUS_TAPI_INVALCALLHANDLE
  398. */
  399. NDIS_STATUS TspiGetCallAddressID(
  400. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  401. IN PNDIS_TAPI_GET_CALL_ADDRESS_ID Request,
  402. OUT PULONG BytesWritten,
  403. OUT PULONG BytesNeeded
  404. )
  405. {
  406. DBG_FUNC("TspiGetCallAddressID")
  407. PBCHANNEL_OBJECT pBChannel;
  408. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  409. DBG_ENTER(pAdapter);
  410. DBG_PARAMS(pAdapter,
  411. ("\n\thdCall=0x%X\n",
  412. Request->hdCall
  413. ));
  414. /*
  415. // This request must be associated with a call.
  416. */
  417. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  418. if (pBChannel == NULL)
  419. {
  420. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  421. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  422. }
  423. /*
  424. // Return the address ID associated with this call.
  425. */
  426. Request->ulAddressID = TSPI_ADDRESS_ID;
  427. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  428. return (NDIS_STATUS_SUCCESS);
  429. }
  430. /* @doc INTERNAL TspiAddr TspiAddr_c TspiAddressStateHandler
  431. @func
  432. <f TspiAddressStateHandler> will indicate the given LINEADDRESSSTATE to
  433. the Connection Wrapper if the event has been enabled by the wrapper.
  434. Otherwise the state information is saved, but no indication is made.
  435. @parm IN ULONG | AddressState |
  436. The LINEADDRESSSTATE event to be posted to TAPI/WAN.
  437. */
  438. VOID TspiAddressStateHandler(
  439. IN PMINIPORT_ADAPTER_OBJECT pAdapter, // @parm
  440. // A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
  441. IN PBCHANNEL_OBJECT pBChannel, // @parm
  442. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  443. IN ULONG AddressState
  444. )
  445. {
  446. DBG_FUNC("TspiAddressStateHandler")
  447. /*
  448. // The event structure passed to the Connection Wrapper.
  449. */
  450. NDIS_TAPI_EVENT Event;
  451. DBG_ENTER(pAdapter);
  452. if (pBChannel->AddressStatesMask & AddressState)
  453. {
  454. Event.htLine = pBChannel->htLine;
  455. Event.htCall = pBChannel->htCall;
  456. Event.ulMsg = LINE_CALLSTATE;
  457. Event.ulParam1 = AddressState;
  458. Event.ulParam2 = 0;
  459. Event.ulParam3 = 0;
  460. /*
  461. // We really don't have much to do here with this adapter.
  462. // And RASTAPI doesn't handle these events anyway...
  463. */
  464. switch (AddressState)
  465. {
  466. case LINEADDRESSSTATE_INUSEZERO:
  467. break;
  468. case LINEADDRESSSTATE_INUSEONE:
  469. break;
  470. }
  471. NdisMIndicateStatus(
  472. pAdapter->MiniportAdapterHandle,
  473. NDIS_STATUS_TAPI_INDICATION,
  474. &Event,
  475. sizeof(Event)
  476. );
  477. pAdapter->NeedStatusCompleteIndication = TRUE;
  478. }
  479. else
  480. {
  481. DBG_NOTICE(pAdapter, ("#%d ADDRESSSTATE EVENT=0x%X IS NOT ENABLED\n",
  482. pBChannel->BChannelIndex, AddressState));
  483. }
  484. DBG_LEAVE(pAdapter);
  485. }