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.

645 lines
21 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. media.cpp
  5. Abstract:
  6. TAPI Service Provider functions related to media.
  7. TSPI_lineConditionalMediaDetection
  8. TSPI_lineGetID
  9. TSPI_lineMSPIdentify
  10. TSPI_lineReceiveMSPData
  11. TSPI_lineSetDefaultMediaDetection
  12. TSPI_lineSetMediaMode
  13. Author:
  14. Nikhil Bobde (NikhilB)
  15. Revision History:
  16. --*/
  17. //
  18. // Include files
  19. //
  20. #include "globals.h"
  21. #include <initguid.h>
  22. #include "line.h"
  23. #include "ras.h"
  24. // {0F1BE7F8-45CA-11d2-831F-00A0244D2298}
  25. DEFINE_GUID(CLSID_IPMSP,
  26. 0x0F1BE7F8,0x45CA, 0x11d2, 0x83, 0x1F, 0x0, 0xA0, 0x24, 0x4D, 0x22, 0x98);
  27. //
  28. // TSPI procedures
  29. //
  30. /*++
  31. Routine Description:
  32. If the Service Provider can monitor for the indicated set of media modes
  33. AND support the capabilities indicated in pCallParams, then it sets the
  34. indicated media moditoring modes for the line and replies with a "success"
  35. indication. Otherwise, it leaves the media monitoring modes for the line
  36. unchanged and replies with a "failure" indication.
  37. A TAPI lineOpen that specifies the device ID LINE_MAPPER typically results
  38. in calling this procedure for multiple line devices to hunt for a suitable
  39. line, possibly also opening as-yet unopened lines. A "success" result
  40. indicates that the line is suitable for the calling application's
  41. requirements. Note that the media monitoring modes demanded at the TSPI
  42. level are the union of monitoring modes demanded by multiple applications
  43. at the TAPI level. As a consequence of this, it is most common for
  44. multiple media mode flags to be set simultaneously at this level. The
  45. Service Provider should test to determine if it can support at least the
  46. specified set regardless of what modes are currently in effect.
  47. The Device ID LINE_MAPPER is never used at the TSPI level.
  48. The service provider shall return an error (e.g., LINEERR_RESOURCEUNAVAIL)
  49. if, at the time this function is called, it is impossible to place a new
  50. call on the specified line device (in other words, if it would return
  51. LINEERR_CALLUNAVAIL or LINEERR_RESOURCEUNAVAIL should TSPI_lineMakeCall be
  52. invoked immediately after opening the line).
  53. The function operates strictly synchronously.
  54. Arguments:
  55. hdLine - Specifies the Service Provider's opaque handle to the line to
  56. have media monitoring and parameter capabilities tested and set.
  57. dwMediaModes - Specifies the media mode(s) of interest to the app, of
  58. type LINEMEDIAMODE. The dwMediaModes parameter is used to register
  59. the app as a potential target for inbound call and call hand off for
  60. the specified media mode. This parameter is ignored if the OWNER flag
  61. is not set in dwPrivileges.
  62. pCallParams - Specifies a far pointer to a structure of type
  63. LINECALLPARAMS. It describes the call parameters that the line device
  64. should be able to provide.
  65. Return Values:
  66. Returns zero if the function is successful, or a negative error number if
  67. an error has occurred. Possible error returns are:
  68. LINEERR_INVALADDRESSMODE - The address mode is invalid.
  69. LINEERR_INVALBEARERMODE - The bearer mode is invalid.
  70. LINEERR_INVALLINEHANDLE - The specified line handle is invalid.
  71. LINEERR_INVALMEDIAMODE - One or more media modes specified as a
  72. parameter or in a list is invalid or not supported by the the
  73. service provider.
  74. LINEERR_RESOURCEUNAVAIL - The specified operation cannot be completed
  75. because of resource overcommitment.
  76. --*/
  77. LONG
  78. TSPIAPI
  79. TSPI_lineConditionalMediaDetection(
  80. HDRVLINE hdLine,
  81. DWORD dwMediaModes,
  82. LPLINECALLPARAMS const pCallParams
  83. )
  84. {
  85. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineCondMediaDetect - Entered." ));
  86. // attempt to close line device
  87. if( hdLine != g_pH323Line -> GetHDLine() )
  88. {
  89. return LINEERR_INVALLINEHANDLE;
  90. }
  91. // see if we support media modes specified
  92. if (dwMediaModes & ~H323_LINE_MEDIAMODES)
  93. {
  94. H323DBG(( DEBUG_LEVEL_ERROR, "do not support media modes 0x%08lx.",
  95. dwMediaModes ));
  96. // do not support media mode
  97. return LINEERR_INVALMEDIAMODE;
  98. }
  99. // validate pointer
  100. if (pCallParams != NULL)
  101. {
  102. // see if we support media modes specified
  103. if (pCallParams->dwMediaMode & ~H323_LINE_MEDIAMODES)
  104. {
  105. H323DBG(( DEBUG_LEVEL_ERROR,
  106. "do not support media modes 0x%08lx.",
  107. pCallParams->dwMediaMode ));
  108. // do not support media mode
  109. return LINEERR_INVALMEDIAMODE;
  110. }
  111. // see if we support bearer modes
  112. if (pCallParams->dwBearerMode & ~H323_LINE_BEARERMODES)
  113. {
  114. H323DBG(( DEBUG_LEVEL_ERROR,
  115. "do not support bearer mode 0x%08lx.",
  116. pCallParams->dwBearerMode ));
  117. // do not support bearer mode
  118. return LINEERR_INVALBEARERMODE;
  119. }
  120. // see if we support address modes
  121. if (pCallParams->dwAddressMode & ~H323_LINE_ADDRESSMODES)
  122. {
  123. H323DBG(( DEBUG_LEVEL_ERROR,
  124. "do not support address mode 0x%08lx.",
  125. pCallParams->dwAddressMode ));
  126. // do not support address mode
  127. return LINEERR_INVALADDRESSMODE;
  128. }
  129. }
  130. // retrieve line device pointer from handle
  131. if (g_pH323Line -> GetHDLine() != hdLine)
  132. {
  133. // invalid line device handle
  134. return LINEERR_INVALLINEHANDLE;
  135. }
  136. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineCondMediaDetect - Entered." ));
  137. // success
  138. return NOERROR;
  139. }
  140. LONG
  141. TSPIAPI
  142. TSPI_lineGetID(
  143. HDRVLINE hdLine,
  144. DWORD dwAddressID,
  145. HDRVCALL hdCall,
  146. DWORD dwSelect,
  147. LPVARSTRING pDeviceID,
  148. LPCWSTR pwszDeviceClass,
  149. HANDLE hTargetProcess
  150. )
  151. /*++
  152. Routine Description:
  153. This function returns a device ID for the specified device class
  154. associated with the selected line, address or call.
  155. This function can be used to retrieve a line device ID given a
  156. line handle. Although the TAPI DLL has sufficient information to
  157. determine the line device ID from a line handle, it may still call
  158. this operation in such a fashion on behalf of an application that
  159. has opened a line device using LINE_MAPPER. The Service Provider
  160. should support the "line" device class to allow applications to
  161. determine the real line device ID of an opened line.
  162. This function can also be used to obtain the device ID of a phone
  163. device or media device (e.g., mci waveform, mci midi, wave, fax,
  164. etc.) associated with a call, address or line. This ID can then be
  165. used with the appropriate API (e.g., phone, mci, midi, wave, etc.)
  166. to select the corresponding media device associated with the specified
  167. call.
  168. Note that the notion of Windows device class is different from that of
  169. media mode. For example, the interactive voice or stored voice media
  170. modes may be accessed using either the mci waveaudio or the low level
  171. wave device classes. A media modes describes a format of information
  172. on a call, a device class defines a Windows API used to manage that
  173. stream. Often, a single media stream may be accessed using multiple
  174. device classes, or a single device class (e.g., the Windows COMM API)
  175. may provide access to multiple media modes.
  176. Note that a new device class value is defined in TAPI 2.0:
  177. "comm/datamodem/portname"
  178. When TSPI_lineGetID is called specifying this device class on a line
  179. device that supports the class, the VARSTRING structure returned will
  180. contain a null-terminated ANSI (not UNICODE) string specifying the name
  181. of the port to which the specified modem is attached, such as "COM1\0".
  182. This is intended primarily for identification purposes in user interface,
  183. but could be used under some circumstances to open the device directly,
  184. bypassing the service provider (if the service provider does not already
  185. have the device open itself). If there is no port associated with the
  186. device, a null string ("\0") is returned in the VARSTRING structure (with
  187. a string length of 1).
  188. Arguments:
  189. hdLine - Specifies the Service Provider's opaque handle to the line
  190. to be queried.
  191. dwAddressID - Specifies an address on the given open line device.
  192. hdCall - Specifies the Service Provider's opaque handle to the call
  193. to be queried.
  194. dwSelect - Specifies the whether the device ID requested is associated
  195. with the line, address or a single call, of type LINECALLSELECT.
  196. pDeviceID - Specifies a far pointer to the memory location of type
  197. VARSTRING where the device ID is returned. Upon successful completion
  198. of the request, this location is filled with the device ID. The
  199. format of the returned information depends on the method used by the
  200. device class (API) for naming devices.
  201. pwszDeviceClass - Specifies a far pointer to a NULL-terminated ASCII
  202. string that specifies the device class of the device whose ID is
  203. requested. Valid device class strings are those used in the SYSTEM.INI
  204. section to identify device classes.
  205. hTargetProcess - The process handle of the application on behalf of which
  206. the TSPI_lineGetID function is being invoked. If the information being
  207. returned in the VARSTRING structure includes a handle for use by the
  208. application, the service provider should create or duplicate the handle
  209. for the process.
  210. If hTargetProcess is set to INVALID_HANDLE_VALUE, then the application
  211. is executing on a remote client system and it is not possible to create
  212. a duplicate handle directly. Instead, the VARSTRING structure should
  213. contain a UNC name of a network device or other name that the remote
  214. client can use to access the device. If this is not possible, then the
  215. function should fail.
  216. Return Values:
  217. Returns zero if the function is successful or a negative error
  218. number if an error has occurred. Possible error returns are:
  219. LINEERR_INVALCALLHANDLE - The hdCall parameter is an invalid handle.
  220. LINEERR_INVALCALLSELECT - The specified dwCallSelect parameter is
  221. invalid.
  222. LINEERR_INVALCALLSTATE - One or more of the specified calls are not in
  223. a valid state for the requested operation.
  224. LINEERR_NODEVICE - The line device has no associated device for the
  225. given device class.
  226. LINEERR_STRUCTURETOOSMALL - The dwTotalSize member of a structure does
  227. not specify enough memory to contain the fixed portion of the
  228. structure. The dwNeededSize field has been set to the amount
  229. required.
  230. --*/
  231. {
  232. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineGetID - Entered." ));
  233. // do not support device
  234. return LINEERR_NODEVICE;
  235. }
  236. LONG
  237. TSPIAPI
  238. TSPI_lineMSPIdentify(
  239. DWORD dwDeviceID,
  240. GUID * pCLSID
  241. )
  242. /*++
  243. Routine Description:
  244. This procedure is called after TAPI has initialized the line device in
  245. order to determine the assoicated Media Service Provider.
  246. Arguments:
  247. dwDeviceID - Identifies the line device to be opened. The value
  248. LINE_MAPPER for a device ID is not permitted.
  249. pCLSID - Points to a GUID-sized memory location which the service
  250. provider writes the class identifier of the associated media
  251. service provider.
  252. Return Values:
  253. Returns zero if the function is successful or a negative error
  254. number if an error has occurred. Possible error returns are:
  255. LINEERR_BADDEVICEID - The specified line device ID is out of range.
  256. LINEERR_OPERATIONFAILED - The operation failed for an unspecified or
  257. unknown reason.
  258. --*/
  259. {
  260. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineMSPIdentify - Entered." ));
  261. if( g_pH323Line -> GetDeviceID() != dwDeviceID )
  262. {
  263. // do not recognize device
  264. return LINEERR_BADDEVICEID;
  265. }
  266. // copy class id
  267. *pCLSID = CLSID_IPMSP;
  268. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineMSPIdentify - Exited." ));
  269. // success
  270. return NOERROR;
  271. }
  272. /*++
  273. Routine Description:
  274. This procedure is called to deliver a payload from the MSP.
  275. Arguments:
  276. hdCall - Handle to line object.
  277. hdCall - Handle to call object associated with MSP.
  278. hdMSPLine - Handle to MSP.
  279. pBuffer - Pointer to opaque buffer with MSP data.
  280. dwSize - Size of buffer above.
  281. Return Values:
  282. Returns zero if the function is successful or a negative error
  283. number if an error has occurred. Possible error returns are:
  284. LINEERR_INVALCALLHANDLE - The specified call handle is invalid.
  285. LINEERR_OPERATIONFAILED - The operation failed for an unspecified or
  286. unknown reason.
  287. --*/
  288. LONG
  289. TSPIAPI
  290. TSPI_lineReceiveMSPData(
  291. HDRVLINE hdLine,
  292. HDRVCALL hdCall,
  293. HDRVMSPLINE hdMSPLine,
  294. LPVOID pBuffer,
  295. DWORD dwSize
  296. )
  297. {
  298. HTAPIMSPLINE htMSPLine;
  299. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineRecvMSPData - Entered." ));
  300. // line device
  301. if( hdLine != g_pH323Line -> GetHDLine() )
  302. {
  303. return LINEERR_RESOURCEUNAVAIL;
  304. }
  305. PH323_CALL pCall;
  306. PTspMspMessage pMessage = (PTspMspMessage)pBuffer;
  307. if( !g_pH323Line -> IsValidMSPHandle( hdMSPLine, &htMSPLine ) )
  308. {
  309. H323DBG(( DEBUG_LEVEL_ERROR,
  310. "Invalid MSP handle:%lx.", hdMSPLine ));
  311. return LINEERR_RESOURCEUNAVAIL;
  312. }
  313. // see if call handle is valid
  314. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  315. if( pCall == NULL )
  316. {
  317. H323DBG(( DEBUG_LEVEL_ERROR, "msp message-wrong call handle." ));
  318. return LINEERR_INVALCALLHANDLE;
  319. }
  320. // validate pointer and message size
  321. if( dwSize < pMessage -> dwMessageSize )
  322. {
  323. pCall -> Unlock();
  324. H323DBG(( DEBUG_LEVEL_ERROR, "msp message has wrong size." ));
  325. //error in processing message
  326. return LINEERR_OPERATIONFAILED;
  327. }
  328. //HandleMSPMessage unlocks the call object always.
  329. if(!pCall -> HandleMSPMessage( pMessage, hdMSPLine, htMSPLine ) )
  330. {
  331. //error in processing message
  332. return LINEERR_OPERATIONFAILED;
  333. }
  334. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineRecvMSPData - Exited." ));
  335. // success
  336. return NOERROR;
  337. }
  338. /*++
  339. Routine Description:
  340. This procedure tells the Service Provider the new set of Media Modes to
  341. detect for the indicated line (replacing any previous set). It also sets
  342. the initial set of Media Modes that should be monitored for on subsequent
  343. calls (inbound or outbound) on this line.
  344. The TAPI DLL typically calls this function to update the set of detected
  345. media modes for the line to the union of all modes selected by all
  346. outstanding lineOpens whenever a line is Opened or Closed at the TAPI
  347. level. A lineOpen attempt is rejected if media detection is rejected.
  348. A single call to this procedure is typically the result of a lineOpen
  349. that does not specify the device ID LINE_MAPPER. The Device ID LINE_MAPPER
  350. is never used at the TSPI level.
  351. Arguments:
  352. hdLine - Specifies the Service Provider's opaque handle to the line to
  353. have media monitoring set.
  354. dwMediaModes - Specifies the media mode(s) of interest to the TAPI DLL,
  355. of type LINEMEDIAMODE.
  356. Return Values:
  357. Returns zero if the function is successful or a negative error
  358. number if an error has occurred. Possible error returns are:
  359. LINEERR_INVALLINEHANDLE - The specified line handle is invalid.
  360. LINEERR_INVALMEDIAMODE - One or more media modes specified as a
  361. parameter or in a list is invalid or not supported by the the
  362. service provider.
  363. --*/
  364. LONG
  365. TSPIAPI
  366. TSPI_lineSetDefaultMediaDetection(
  367. HDRVLINE hdLine,
  368. DWORD dwMediaModes
  369. )
  370. {
  371. HRESULT hResult;
  372. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineSetDefaultMediaDtect-Entered." ));
  373. // attempt to close line device
  374. if( hdLine != g_pH323Line -> GetHDLine() )
  375. {
  376. return LINEERR_RESOURCEUNAVAIL;
  377. }
  378. // see if unknown bit is specified
  379. if (dwMediaModes & LINEMEDIAMODE_UNKNOWN)
  380. {
  381. H323DBG(( DEBUG_LEVEL_VERBOSE, "clearing unknown media mode." ));
  382. // clear unknown bit from modes
  383. dwMediaModes &= ~LINEMEDIAMODE_UNKNOWN;
  384. }
  385. // see if both audio bits are specified
  386. if ((dwMediaModes & LINEMEDIAMODE_AUTOMATEDVOICE) &&
  387. (dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE))
  388. {
  389. H323DBG(( DEBUG_LEVEL_VERBOSE,
  390. "clearing automated voice media mode." ));
  391. // clear extra audio bit from modes
  392. dwMediaModes &= ~LINEMEDIAMODE_INTERACTIVEVOICE;
  393. }
  394. // see if we support media modes specified
  395. if (dwMediaModes & ~H323_LINE_MEDIAMODES)
  396. {
  397. H323DBG(( DEBUG_LEVEL_ERROR,
  398. "do not support media modes 0x%08lx.", dwMediaModes ));
  399. // do not support media mode
  400. return LINEERR_INVALMEDIAMODE;
  401. }
  402. H323DBG(( DEBUG_LEVEL_TRACE,
  403. "line %d enabled to detect media modes 0x%08lx.",
  404. g_pH323Line->GetDeviceID(), dwMediaModes ));
  405. g_pH323Line -> Lock();
  406. // record media modes to detect
  407. g_pH323Line->SetMediaModes( dwMediaModes );
  408. // see if we need to start listening
  409. if( g_pH323Line -> IsMediaDetectionEnabled() &&
  410. (g_pH323Line -> GetState() != H323_LINESTATE_LISTENING)
  411. )
  412. {
  413. hResult = Q931AcceptStart();
  414. if( hResult != S_OK )
  415. {
  416. // release line device
  417. g_pH323Line -> Unlock();
  418. // could not cancel listen
  419. return LINEERR_OPERATIONFAILED;
  420. }
  421. g_pH323Line -> SetState( H323_LINESTATE_LISTENING );
  422. RasStart();
  423. }
  424. else if( (g_pH323Line -> GetState() == H323_LINESTATE_LISTENING) &&
  425. !g_pH323Line -> IsMediaDetectionEnabled() )
  426. {
  427. //stop listening means dont close exiting calls but stop accepting new
  428. //ones for some time close means close all the existing calls and stop
  429. //listening for new ones
  430. Q931AcceptStop();
  431. //RasStop();
  432. g_pH323Line -> SetState( H323_LINESTATE_OPENED );
  433. }
  434. // release line device
  435. g_pH323Line -> Unlock();
  436. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineSetDefaultMediaDetect - Exited." ));
  437. // success
  438. return NOERROR;
  439. }
  440. LONG
  441. TSPIAPI
  442. TSPI_lineSetMediaMode(
  443. HDRVCALL hdCall,
  444. DWORD dwMediaMode
  445. )
  446. /*++
  447. Routine Description:
  448. This function changes the call's media as stored in the call's
  449. LINECALLINFO structure.
  450. Other than changing the call's media as stored in the call's
  451. LINECALLINFO structure, this procedure is simply "advisory" in the sense
  452. that it indicates an expected media change that is about to occur, rather
  453. than forcing a specific change to the call. Typical usage is to set a
  454. calls media mode to a specific known media mode, or to exclude possible
  455. media modes as long as the call's media mode is not fully known; i.e.,
  456. the UNKNOWN media mode flag is set.
  457. Arguments:
  458. hdCall - Specifies the Service Provider's opaque handle to the call
  459. undergoing a change in media mode. Valid call states: any.
  460. dwMediaMode - Specifies the new media mode(s) for the call, of type
  461. LINEMEDIAMODE. As long as the UNKNOWN media mode flag is set,
  462. multiple other media mode flags may be set as well. This is used
  463. to indentify a call's media mode as not fully determined, but
  464. narrowed down to one of just a small set of specified media modes.
  465. If the UNKNOWN flag is not set, then only a single media mode can
  466. be specified.
  467. Return Values:
  468. Returns zero if the function is successful or a negative error
  469. number if an error has occurred. Possible error returns are:
  470. LINEERR_INVALCALLHANDLE - The specified call handle is invalid.
  471. LINEERR_INVALMEDIAMODE - The specified media mode parameter is invalid.
  472. LINEERR_OPERATIONUNAVAIL - The specified operation is not available.
  473. LINEERR_OPERATIONFAILED - The specified operation failed for
  474. unspecified reasons.
  475. --*/
  476. {
  477. return LINEERR_OPERATIONUNAVAIL; // CODEWORK...
  478. }