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.

1229 lines
37 KiB

  1. #include "globals.h"
  2. #include "line.h"
  3. #include "q931pdu.h"
  4. #include "q931obj.h"
  5. #include "ras.h"
  6. //
  7. // TSPI procedures
  8. //
  9. // This file contains all of the TSPI export functions that act directly on calls.
  10. //
  11. /*++
  12. Parameters
  13. hdCall - The handle to the call whose application-specific field is to be
  14. set. The call state of hdCall can be any state.
  15. dwAppSpecific - The new content of the dwAppSpecific member for the call's
  16. LINECALLINFO structure. This value is uninterpreted by the service
  17. provider. This parameter is not validated by TAPI when this function is called.
  18. Return Values
  19. Returns zero if the function succeeds, or an error number if an error
  20. occurs. Possible return values are as follows:
  21. LINEERR_INVALCALLHANDLE,
  22. LINEERR_OPERATIONFAILED,
  23. LINEERR_NOMEM,
  24. LINEERR_RESOURCEUNAVAIL,
  25. LINEERR_OPERATIONUNAVAIL.
  26. Routine Description:
  27. The application-specific field in the LINECALLINFO data structure that
  28. exists for each call is uninterpreted by the Telephony API or any of its
  29. service providers. Its usage is entirely defined by the applications. The
  30. field can be read from the LINECALLINFO record returned by
  31. TSPI_lineGetCallInfo. However, TSPI_lineSetAppSpecific must be used to set
  32. the field so that changes become visible to other applications. When this
  33. field is changed, the service provider sends a LINE_CALLINFO message with
  34. an indication that the AppSpecific field has changed.
  35. ++*/
  36. LONG
  37. TSPIAPI
  38. TSPI_lineSetAppSpecific(
  39. HDRVCALL hdCall,
  40. DWORD dwAppSpecific
  41. )
  42. {
  43. PH323_CALL pCall;
  44. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineSetAppSpecific - Entered." ));
  45. //this function locks the call
  46. pCall = g_pH323Line -> FindH323CallAndLock( hdCall );
  47. if( pCall == NULL )
  48. {
  49. return LINEERR_INVALCALLHANDLE;
  50. }
  51. pCall -> SetAppSpecific( dwAppSpecific );
  52. pCall -> Unlock();
  53. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineSetAppSpecific - Exited." ));
  54. // success
  55. return ERROR_SUCCESS;
  56. }
  57. LONG TSPIAPI TSPI_lineSetCallData(
  58. DRV_REQUESTID dwRequestID,
  59. HDRVCALL hdCall,
  60. LPVOID lpCallData,
  61. DWORD dwSize
  62. )
  63. {
  64. PH323_CALL pCall;
  65. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineSetCallData - Entered." ));
  66. //This function locks the call
  67. pCall = g_pH323Line -> FindH323CallAndLock( hdCall );
  68. if( pCall == NULL )
  69. {
  70. return LINEERR_INVALCALLHANDLE;
  71. }
  72. if( !pCall -> SetCallData( lpCallData, dwSize ) )
  73. {
  74. pCall -> Unlock();
  75. return LINEERR_OPERATIONFAILED;
  76. }
  77. pCall -> PostLineEvent( LINE_CALLINFO,
  78. LINECALLINFOSTATE_CALLDATA,
  79. 0,
  80. 0 );
  81. // complete the async accept operation now
  82. H323CompleteRequest (dwRequestID, ERROR_SUCCESS);
  83. pCall -> Unlock();
  84. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineSetCallData - Exited." ));
  85. // success
  86. return dwRequestID;
  87. }
  88. LONG
  89. TSPIAPI
  90. TSPI_lineAnswer(
  91. DRV_REQUESTID dwRequestID,
  92. HDRVCALL hdCall,
  93. LPCSTR pUserUserInfo,
  94. DWORD dwSize
  95. )
  96. /*++
  97. Routine Description:
  98. This function answers the specified offering call.
  99. When a new call arrives, the Service Provider sends the TAPI DLL a
  100. LINE_NEWCALL event to exchange opaque handles for the call. The Service
  101. Provider follows this with a LINE_CALLSTATE message inform the TAPI DLL
  102. and its client applications of the call's call state. The TAPI DLL
  103. typically answers this call (on behalf of an application) using
  104. TSPI_lineAnswer. After the call has been successfully answered, the call
  105. will typically transition to the connected state.
  106. In some telephony environments (like ISDN) where user alerting is separate
  107. from call offering, the TAPI DLL and its client apps may have the option to
  108. first accept a call prior to answering, or instead to reject or redirect
  109. the offering call.
  110. If a call comes in (is offered) at the time another call is already active,
  111. then the new call is connected to by invoking TSPI_lineAnswer. The effect
  112. this has on the existing active call depends on the line's device
  113. capabilities. The first call may be unaffected, it may automatically be
  114. dropped, or it may automatically be placed on hold. The appropriate
  115. LINE_CALLSTATE messages will report state transitions to the TAPI DLL about
  116. both calls.
  117. The TAPI DLL has the option to send user-to-user information at the time of
  118. the answer. Even if user-to-user information can be sent, often no
  119. guarantees are made that the network will deliver this information to the
  120. calling party. The TAPI DLL can consult a line's device capabilities to
  121. determine whether or not sending user-to-user information on answer is
  122. available.
  123. Arguments:
  124. dwRequestID - Specifies the identifier of the asynchronous request.
  125. The Service Provider returns this value if the function completes
  126. asynchronously.
  127. hdCall - Specifies the Service Provider's opaque handle to the call to be
  128. answered. Valid call states: offering, accepted.
  129. pUserUserInfo - Specifies a far pointer to a string containing
  130. user-to-user information to be sent to the remote party at the time of
  131. answering the call. If this pointer is NULL, it indicates that no
  132. user-to-user information is to be sent. User-to-user information is
  133. only sent if supported by the underlying network (see LINEDEVCAPS).
  134. dwSize - Specifies the size in bytes of the user-to-user information in
  135. pUserUserInfo. If pUserUserInfo is NULL, no user-to-user
  136. information is sent to the calling party and dwSize is ignored.
  137. Return Values:
  138. Returns zero if the function is successful, the (positive) dwRequestID
  139. value if the function will be completed asynchronously, or a negative
  140. error number if an error has occurred. Possible error returns are:
  141. LINEERR_INVALCALLHANDLE - The specified call handle is invalid.
  142. LINEERR_INVALCALLSTATE - The call is not in a valid state for the
  143. requested operation.
  144. LINEERR_OPERATIONFAILED - The specified operation failed for
  145. unspecified reason.
  146. --*/
  147. {
  148. PH323_CALL pCall;
  149. DWORD dwCallState;
  150. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineAnswer - Entered." ));
  151. //this function locks the call
  152. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  153. if( pCall == NULL )
  154. {
  155. return LINEERR_INVALCALLHANDLE;
  156. }
  157. // see if call in offering state
  158. dwCallState = pCall -> GetCallState();
  159. if( ( dwCallState & LINECALLSTATE_OFFERING) == 0 )
  160. {
  161. H323DBG(( DEBUG_LEVEL_ERROR,
  162. "call 0x%08lx cannot be accepted state 0x%08lx.",
  163. pCall,
  164. pCall -> GetCallState()));
  165. pCall -> Unlock();
  166. // invalid call state
  167. return LINEERR_INVALCALLSTATE;
  168. }
  169. // save outgoing user user information (if specified)
  170. if( !pCall -> AddU2U( U2U_OUTBOUND, dwSize, (PBYTE)pUserUserInfo) )
  171. {
  172. H323DBG(( DEBUG_LEVEL_ERROR, "could not save user user info." ));
  173. pCall -> Unlock();
  174. // no memory available
  175. return LINEERR_NOMEM;
  176. }
  177. if( !pCall -> QueueTAPICallRequest( TSPI_ANSWER_CALL, NULL) )
  178. {
  179. H323DBG(( DEBUG_LEVEL_ERROR,
  180. "could not post place call message." ));
  181. //drop the call
  182. pCall -> CloseCall( 0 );
  183. pCall -> Unlock();
  184. // could not complete operation
  185. return LINEERR_OPERATIONFAILED;
  186. }
  187. // complete the async accept operation now
  188. H323CompleteRequest (dwRequestID, ERROR_SUCCESS);
  189. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineAnswer - Exited." ));
  190. pCall -> Unlock();
  191. // async success
  192. return dwRequestID;
  193. }
  194. LONG
  195. TSPIAPI
  196. TSPI_lineCloseCall(
  197. HDRVCALL hdCall
  198. )
  199. /*++
  200. Routine Description:
  201. This function deletes the call after completing or aborting all outstanding
  202. asynchronous operations on the call.
  203. The Service Provider has the responsibility to (eventually) report
  204. completion for every operation it decides to execute asynchronously.
  205. If this procedure is called for a call on which there are outstanding
  206. asynchronous operations, the operations should be reported complete with an
  207. appropriate result or error code before this procedure returns. If there
  208. is an active call on the line at the time of TSPI_lineCloseCall, the call
  209. must be dropped. Generally the TAPI DLL would wait for calls to be
  210. finished and asynchronous operations to complete in an orderly fashion.
  211. However, the Service Provider should be prepared to handle an early call to
  212. TSPI_lineCloseCall in "abort" or "emergency shutdown" situations.
  213. After this procedure returns the Service Provider must report no further
  214. events on the call. The Service Provider's opaque handle for the call
  215. becomes "invalid".
  216. This function is presumed to complete successfully and synchronously.
  217. Arguments:
  218. hdCall - Specifies the Service Provider's opaque handle to the call to be
  219. deleted. After the call has been successfully deleted, this handle is
  220. no longer valid. Valid call states: any.
  221. Return Values:
  222. None.
  223. --*/
  224. {
  225. PH323_CALL pCall;
  226. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineCloseCall - Entered." ));
  227. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  228. if( pCall == NULL )
  229. {
  230. H323DBG(( DEBUG_LEVEL_TRACE, "call already deleted." ));
  231. //return LINEERR_INVALCALLHANDLE;
  232. return NOERROR;
  233. }
  234. // drop specified call
  235. pCall->CloseCall( LINEDISCONNECTMODE_CANCELLED );
  236. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineCloseCall - Exited." ));
  237. pCall -> Unlock();
  238. // success
  239. return NOERROR;
  240. }
  241. LONG
  242. TSPIAPI
  243. TSPI_lineDrop(
  244. DRV_REQUESTID dwRequestID,
  245. HDRVCALL hdCall,
  246. LPCSTR pUserUserInfo,
  247. DWORD dwSize
  248. )
  249. /*++
  250. Routine Description:
  251. This functions drops or disconnects the specified call. The TAPI DLL has
  252. the option to specify user-to-user information to be transmitted as part
  253. of the call disconnect.
  254. When invoking TSPI_lineDrop related calls may sometimes be affected as
  255. well. For example, dropping a conference call may drop all individual
  256. participating calls. LINE_CALLSTATE messages are sent to the TAPI DLL for
  257. all calls whose call state is affected. A dropped call will typically
  258. transition to the idle state.
  259. Invoking TSPI_lineDrop on a call in the offering state rejects the call.
  260. Not all telephone networks provide this capability.
  261. Invoking TSPI_lineDrop on a consultation call that was set up using either
  262. TSPI_lineSetupTransfer or TSPI_lineSetupConference, will cancel the
  263. consultation call. Some switches automatically unhold the other call.
  264. The TAPI DLL has the option to send user-to-user information at the time
  265. of the drop. Even if user-to-user information can be sent, often no
  266. guarantees are made that the network will deliver this information to the
  267. remote party.
  268. Note that in various bridged or party line configurations when multiple
  269. parties are on the call, TSPI_lineDrop by the application may not actually
  270. clear the call.
  271. Arguments:
  272. dwRequestID - Specifies the identifier of the asynchronous request.
  273. The Service Provider returns this value if the function completes
  274. asynchronously.
  275. hdCall - Specifies the Service Provider's opaque handle to the call to
  276. be dropped. Valid call states: any.
  277. psUserUserInfo - Specifies a far pointer to a string containing
  278. user-to-user information to be sent to the remote party as part of
  279. the call disconnect. This pointer is unused if dwUserUserInfoSize
  280. is zero and no user-to-user information is to be sent. User-to-user
  281. information is only sent if supported by the underlying network
  282. (see LINEDEVCAPS).
  283. dwSize - Specifies the size in bytes of the user-to-user information in
  284. psUserUserInfo. If zero, then psUserUserInfo can be left NULL, and
  285. no user-to-user information will be sent to the remote party.
  286. Return Values:
  287. Returns zero if the function is successful, the (positive) dwRequestID
  288. value if the function will be completed asynchronously, or a negative error
  289. number if an error has occurred. Possible error returns are:
  290. LINEERR_INVALCALLHANDLE - The specified call handle is invalid.
  291. LINEERR_INVALPOINTER - The specified pointer parameter is invalid.
  292. LINEERR_INVALCALLSTATE - The current state of the call does not allow
  293. the call to be dropped.
  294. LINEERR_OPERATIONUNAVAIL - The specified operation is not available.
  295. LINEERR_OPERATIONFAILED - The specified operation failed for
  296. unspecified reasons.
  297. --*/
  298. {
  299. PH323_CALL pCall;
  300. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineDrop - Entered." ));
  301. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  302. if( pCall == NULL )
  303. {
  304. // complete the async accept operation now
  305. H323CompleteRequest (dwRequestID, ERROR_SUCCESS);
  306. return dwRequestID;
  307. //return LINEERR_INVALCALLHANDLE;
  308. }
  309. // save outgoing user user information (if specified)
  310. if( dwSize != 0 && pUserUserInfo )
  311. {
  312. if( !pCall -> AddU2U( U2U_OUTBOUND, dwSize, (PBYTE)pUserUserInfo) )
  313. {
  314. H323DBG(( DEBUG_LEVEL_ERROR,
  315. "could not save user user info." ));
  316. pCall -> Unlock();
  317. // no memory available
  318. return LINEERR_NOMEM;
  319. }
  320. }
  321. // drop specified call
  322. if( !pCall->QueueTAPICallRequest( TSPI_DROP_CALL, NULL ))
  323. {
  324. pCall -> Unlock();
  325. // could not drop call
  326. return LINEERR_OPERATIONFAILED;
  327. }
  328. // complete the async accept operation now
  329. H323CompleteRequest (dwRequestID, ERROR_SUCCESS);
  330. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineDrop - Exited." ));
  331. pCall -> Unlock();
  332. // async success
  333. return dwRequestID;
  334. }
  335. LONG
  336. TSPIAPI
  337. TSPI_lineGetCallAddressID(
  338. HDRVCALL hdCall,
  339. LPDWORD pdwAddressID
  340. )
  341. /*++
  342. Routine Description:
  343. This operation allows the TAPI DLL to retrieve the address ID for the
  344. indicated call.
  345. This operation must be executed synchronously by the Service Provider,
  346. with presumed success. This operation may be called from within the
  347. context of the ASYNC_LINE_COMPLETION or LINEEVENT callbacks (i.e., from
  348. within an interrupt context). This function would typically be called
  349. at the start of the call life cycle.
  350. If the Service Provider models lines as "pools" of channel resources
  351. and does "inverse multiplexing" of a call over several address IDs it
  352. should consistently choose one of these address IDs as the primary
  353. identifier reported by this function and in the LINE_CALLINFO data
  354. structure.
  355. Arguments:
  356. hdCall - Specifies the Service Provider's opaque handle to the call
  357. whose address ID is to be retrieved. Valid call states: any.
  358. pdwAddressID - Specifies a far pointer to a DWORD into which the
  359. Service Provider writes the call's address ID.
  360. Return Values:
  361. None.
  362. --*/
  363. {
  364. PH323_CALL pCall;
  365. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineGetCallAddressID - Entered." ));
  366. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  367. if( pCall == NULL )
  368. {
  369. return LINEERR_INVALCALLHANDLE;
  370. }
  371. // only one addr
  372. *pdwAddressID = 0;
  373. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineGetCallAddressID - Exited." ));
  374. pCall -> Unlock();
  375. // success
  376. return NOERROR;
  377. }
  378. /*++
  379. Routine Description:
  380. This operation enables the TAPI DLL to obtain fixed information about
  381. the specified call.
  382. A separate LINECALLINFO structure exists for every (inbound or outbound)
  383. call. The structure contains primarily fixed information about the call.
  384. An application would typically be interested in checking this information
  385. when it receives its handle for a call via the LINE_CALLSTATE message, or
  386. each time it receives notification via a LINE_CALLINFO message that parts
  387. of the call information structure have changed. These messages supply the
  388. handle for the call as a parameter.
  389. If the Service Provider models lines as "pools" of channel resources and
  390. does "inverse multiplexing" of a call over several address IDs it should
  391. consistently choose one of these address IDs as the primary identifier
  392. reported by this function in the LINE_CALLINFO data structure.
  393. Arguments:
  394. hdCall - Specifies the Service Provider's opaque handle to the call
  395. whose call information is to be retrieved.
  396. pCallInfo - Specifies a far pointer to a variable sized data structure
  397. of type LINECALLINFO. Upon successful completion of the request, this
  398. structure is filled with call related information.
  399. Return Values:
  400. Returns zero if the function is successful or a negative error
  401. number if an error has occurred. Possible error returns are:
  402. LINEERR_INVALCALLHANDLE - The specified call handle is invalid.
  403. LINEERR_STRUCTURETOOSMALL - The dwTotalSize member of a structure does
  404. not specify enough memory to contain the fixed portion of the
  405. structure. The dwNeededSize field has been set to the amount
  406. required.
  407. --*/
  408. LONG
  409. TSPIAPI
  410. TSPI_lineGetCallInfo(
  411. HDRVCALL hdCall,
  412. LPLINECALLINFO pCallInfo
  413. )
  414. {
  415. LONG retVal;
  416. PH323_CALL pCall;
  417. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineGetCallInfo - Entered." ));
  418. if( pCallInfo == NULL )
  419. {
  420. return LINEERR_INVALPARAM;
  421. }
  422. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  423. if( pCall == NULL )
  424. {
  425. return LINEERR_INVALCALLHANDLE;
  426. }
  427. retVal = pCall -> CopyCallInfo( pCallInfo );
  428. pCall -> Unlock();
  429. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineGetCallInfo - Exited." ));
  430. return retVal;
  431. }
  432. LONG
  433. TSPIAPI
  434. TSPI_lineGetCallStatus(
  435. HDRVCALL hdCall,
  436. LPLINECALLSTATUS pCallStatus
  437. )
  438. /*++
  439. Routine Description:
  440. This operation returns the current status of the specified call.
  441. TSPI_lineCallStatus returns the dynamic status of a call, whereas
  442. TSPI_lineGetCallInfo returns primarily static information about a call.
  443. Call status information includes the current call state, detailed mode
  444. information related to the call while in this state (if any), as well
  445. as a list of the available TSPI functions the TAPI DLL can invoke on the
  446. call while the call is in this state. An application would typically be
  447. interested in requesting this information when it receives notification
  448. about a call state change via the LINE_CALLSTATE message.
  449. Arguments:
  450. hdCall - Specifies the Service Provider's opaque handle to the call
  451. to be queried for its status. Valid call states: any.
  452. pCallStatus - Specifies a far pointer to a variable sized data structure
  453. of type LINECALLSTATUS. Upon successful completion of the request,
  454. this structure is filled with call status information.
  455. Return Values:
  456. Returns zero if the function is successful or a negative error
  457. number if an error has occurred. Possible error returns are:
  458. LINEERR_INVALCALLHANDLE - The specified call handle is invalid.
  459. LINEERR_STRUCTURETOOSMALL - The dwTotalSize member of a structure does
  460. not specify enough memory to contain the fixed portion of the
  461. structure. The dwNeededSize field has been set to the amount
  462. required.
  463. --*/
  464. {
  465. PH323_CALL pCall;
  466. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineGetCallStatus - Entered." ));
  467. if( pCallStatus == NULL )
  468. {
  469. return LINEERR_INVALPARAM;
  470. }
  471. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  472. if( pCall == NULL )
  473. {
  474. return LINEERR_INVALCALLHANDLE;
  475. }
  476. // determine number of bytes needed
  477. pCallStatus->dwNeededSize = sizeof(LINECALLSTATUS);
  478. // see if structure size is large enough
  479. if (pCallStatus->dwTotalSize < pCallStatus->dwNeededSize)
  480. {
  481. H323DBG(( DEBUG_LEVEL_ERROR,
  482. "linecallstatus structure too small." ));
  483. pCall -> Unlock();
  484. // allocated structure too small
  485. return LINEERR_STRUCTURETOOSMALL;
  486. }
  487. // record amount of memory used
  488. pCallStatus->dwUsedSize = pCallStatus->dwNeededSize;
  489. pCall -> CopyCallStatus( pCallStatus );
  490. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineGetCallStatus - Exited." ));
  491. pCall -> Unlock();
  492. // success
  493. return NOERROR;
  494. }
  495. /*++
  496. Routine Description:
  497. This function places a call on the specified line to the specified
  498. destination address, exchanging opaque handles for the new call
  499. between the TAPI DLL and Service Provider. Optionally, call parameters
  500. can be specified if anything but default call setup parameters are
  501. requested.
  502. After dialing has completed, several LINE_CALLSTATE messages will
  503. typically be sent to the TAPI DLL to notify it about the progress of the
  504. call. No generally valid sequence of call state transitions is specified
  505. as no single fixed sequence of transitions can be guaranteed in practice.
  506. A typical sequence may cause a call to transition from dialtone, dialing,
  507. proceeding, ringback, to connected. With non-dialed lines, the call may
  508. typically transition directly to connected state.
  509. The TAPI DLL has the option to specify an originating address on the
  510. specified line device. A service provider that models all stations on a
  511. switch as addresses on a single line device allows the TAPI DLL to
  512. originate calls from any of these stations using TSPI_lineMakeCall.
  513. The call parameters allow the TAPI DLL to make non voice calls or request
  514. special call setup options that are not available by default.
  515. The TAPI DLL can partially dial using TSPI_lineMakeCall and continue
  516. dialing using TSPI_lineDial. To abandon a call attempt, use TSPI_lineDrop.
  517. The Service Provider initially does media monitoring on the new call for
  518. at least the set of media modes that were monitored for on the line.
  519. Arguments:
  520. dwRequestID - Specifies the identifier of the asynchronous request.
  521. The Service Provider returns this value if the function completes
  522. asynchronously.
  523. hdLine - Specifies the Service Provider's opaque handle to the line on
  524. which the new call is to be originated.
  525. htCall - Specifies the TAPI DLL's opaque handle to the new call. The
  526. Service Provider must save this and use it in all subsequent calls to
  527. the LINEEVENT procedure reporting events on the call.
  528. phdCall - Specifies a far pointer to an opaque HDRVCALL representing the
  529. Service Provider's identifier for the call. The Service Provider must
  530. fill this location with its opaque handle for the call before this
  531. procedure returns, whether it decides to execute the request
  532. sychronously or asynchronously. This handle is invalid if the function
  533. results in an error (either synchronously or asynchronously).
  534. pwszDialableAddr - Specifies a far pointer to the destination address. This
  535. follows the standard dialable number format. This pointer may be
  536. specified as NULL for non-dialed addresses (i.e., a hot phone) or when
  537. all dialing will be performed using TSPI_lineDial. In the latter case,
  538. TSPI_lineMakeCall will allocate an available call appearance which
  539. would typically remain in the dialtone state until dialing begins.
  540. Service providers that have inverse multiplexing capabilities may allow
  541. an application to specify multiple addresses at once.
  542. dwCountryCode - Specifies the country code of the called party. If a value
  543. of zero is specified, then a default will be used by the
  544. implementation.
  545. pCallParams - Specifies a far pointer to a LINECALLPARAMS structure. This
  546. structure allows the TAPI DLL to specify how it wants the call to be
  547. set up. If NULL is specified, then a default 3.1kHz voice call is
  548. established, and an arbitrary origination address on the line is
  549. selected. This structure allows the TAPI DLL to select such elements
  550. as the call's bearer mode, data rate, expected media mode, origination
  551. address, blocking of caller ID information, dialing parameters, etc.
  552. Return Values:
  553. Returns zero if the function is successful, the (positive) dwRequestID
  554. value if the function will be completed asynchronously, or a negative error
  555. number if an error has occurred. Possible error returns are:
  556. LINEERR_CALLUNAVAIL - All call appearances on the specified address are
  557. currently in use.
  558. LINEERR_INVALADDRESSID - The specified address ID is out of range.
  559. LINEERR_INVALADDRESSMODE - The address mode is invalid.
  560. LINEERR_INVALBEARERMODE - The bearer mode is invalid.
  561. LINEERR_INVALCALLPARAMS - The specified call parameter structure is
  562. invalid.
  563. LINEERR_INVALLINEHANDLE - The specified line handle is invalid.
  564. LINEERR_INVALLINESTATE - The line is currently not in a state in
  565. which this operation can be performed.
  566. LINEERR_INVALMEDIAMODE - One or more media modes specified as a
  567. parameter or in a list is invalid or not supported by the the
  568. service provider.
  569. LINEERR_OPERATIONFAILED - The operation failed for unspecified reasons.
  570. LINEERR_RESOURCEUNAVAIL - The specified operation cannot be completed
  571. because of resource overcommitment.
  572. --*/
  573. LONG
  574. TSPIAPI
  575. TSPI_lineMakeCall(
  576. DRV_REQUESTID dwRequestID,
  577. HDRVLINE hdLine,
  578. HTAPICALL htCall,
  579. LPHDRVCALL phdCall,
  580. LPCWSTR pwszDialableAddr,
  581. DWORD dwCountryCode,
  582. LPLINECALLPARAMS const pCallParams
  583. )
  584. {
  585. DWORD dwStatus = dwRequestID;
  586. PH323_CALL pCall = NULL;
  587. H323_CONFERENCE * pConf = NULL;
  588. BOOL fDelete = FALSE;
  589. DWORD dwState;
  590. UNREFERENCED_PARAMETER( dwCountryCode );
  591. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineMakeCall - Entered." ));
  592. //lock the line device
  593. g_pH323Line -> Lock();
  594. if( hdLine != g_pH323Line -> GetHDLine() )
  595. {
  596. return LINEERR_RESOURCEUNAVAIL;
  597. }
  598. // validate line state
  599. dwState = g_pH323Line -> GetState();
  600. if( ( dwState != H323_LINESTATE_OPENED) &&
  601. ( dwState != H323_LINESTATE_LISTENING) )
  602. {
  603. H323DBG(( DEBUG_LEVEL_ERROR, "H323 line is not currently opened:%d.",
  604. dwState ));
  605. // release line device
  606. g_pH323Line ->Unlock();
  607. // line needs to be opened
  608. return LINEERR_INVALLINESTATE;
  609. }
  610. // see if line is available
  611. if( g_pH323Line -> GetNoOfCalls() == H323_MAXCALLSPERLINE )
  612. {
  613. H323DBG(( DEBUG_LEVEL_ERROR,
  614. "H323 line is currently used at maximum capacity." ));
  615. // release line device
  616. g_pH323Line -> Unlock();
  617. // line is currenty maxed
  618. return LINEERR_RESOURCEUNAVAIL;
  619. }
  620. // allocate outgoing call
  621. pCall = new CH323Call();
  622. if( pCall == NULL )
  623. {
  624. H323DBG(( DEBUG_LEVEL_ERROR,
  625. "could not allocate outgoing call." ));
  626. // no memory available
  627. dwStatus = LINEERR_NOMEM;
  628. goto cleanup;
  629. }
  630. // save tapi handle and specify outgoing call direction
  631. if( !pCall -> Initialize( htCall,
  632. LINECALLORIGIN_OUTBOUND,
  633. CALLTYPE_NORMAL ) )
  634. {
  635. H323DBG(( DEBUG_LEVEL_ERROR,
  636. "could not allocate outgoing call." ));
  637. // no memory available
  638. dwStatus = LINEERR_NOMEM;
  639. goto cleanup;
  640. }
  641. //This function should be called in a lock. But here we aint calling it in
  642. //a lock because this call is not added to the call table yet. Before
  643. //calling this function from anywhere else the call should be locked first
  644. if (!pCall -> ValidateCallParams( pCallParams,
  645. pwszDialableAddr,
  646. &dwStatus))
  647. {
  648. dwStatus = LINEERR_INVALCALLPARAMS;
  649. // failure
  650. goto cleanup;
  651. }
  652. // transfer handle
  653. *phdCall = pCall -> GetCallHandle();
  654. // bind outgoing call
  655. pConf = pCall -> CreateConference(NULL);
  656. if( pConf == NULL )
  657. {
  658. H323DBG(( DEBUG_LEVEL_ERROR, "could not create conference." ));
  659. // no memory available
  660. dwStatus = LINEERR_NOMEM;
  661. // failure
  662. goto cleanup;
  663. }
  664. if( !g_pH323Line -> GetH323ConfTable() -> Add(pConf) )
  665. {
  666. H323DBG(( DEBUG_LEVEL_ERROR, "could not add conf to conf table." ));
  667. // no memory available
  668. dwStatus = LINEERR_NOMEM;
  669. // failure
  670. goto cleanup;
  671. }
  672. pCall->Lock();
  673. // post place call request to callback thread
  674. if( !pCall -> QueueTAPICallRequest( TSPI_MAKE_CALL, NULL ))
  675. {
  676. H323DBG(( DEBUG_LEVEL_ERROR,
  677. "could not post place call message." ));
  678. // could not complete operation
  679. dwStatus = LINEERR_OPERATIONFAILED;
  680. pCall->Unlock();
  681. // failure
  682. goto cleanup;
  683. }
  684. // complete the async accept operation now
  685. H323CompleteRequest (dwRequestID, ERROR_SUCCESS);
  686. pCall->Unlock();
  687. // release line device
  688. g_pH323Line -> Unlock();
  689. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineMakeCall - Exited." ));
  690. // success
  691. return dwStatus;
  692. cleanup:
  693. if( pCall != NULL )
  694. {
  695. pCall -> Shutdown( &fDelete );
  696. H323DBG((DEBUG_LEVEL_TRACE, "call delete:%p.", pCall ));
  697. delete pCall;
  698. pCall = NULL;
  699. }
  700. *phdCall = NULL;
  701. // release line device
  702. g_pH323Line -> Unlock();
  703. // failure
  704. return dwStatus;
  705. }
  706. LONG
  707. TSPIAPI
  708. TSPI_lineReleaseUserUserInfo(
  709. DRV_REQUESTID dwRequestID,
  710. HDRVCALL hdCall
  711. )
  712. {
  713. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineReleaseUUIE - Entered." ));
  714. // retrieve call pointer from handle
  715. PH323_CALL pCall;
  716. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  717. if( pCall == NULL )
  718. {
  719. return LINEERR_INVALCALLHANDLE;
  720. }
  721. if( !pCall -> QueueTAPICallRequest( TSPI_RELEASE_U2U, NULL))
  722. {
  723. H323DBG(( DEBUG_LEVEL_ERROR, "could not post close event." ));
  724. }
  725. // complete the async accept operation now
  726. H323CompleteRequest (dwRequestID, ERROR_SUCCESS);
  727. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineReleaseUUIE - Exited." ));
  728. pCall -> Unlock();
  729. // async success
  730. return dwRequestID;
  731. }
  732. LONG
  733. TSPIAPI
  734. TSPI_lineSendUserUserInfo(
  735. DRV_REQUESTID dwRequestID,
  736. HDRVCALL hdCall,
  737. LPCSTR pUserUserInfo,
  738. DWORD dwSize
  739. )
  740. {
  741. BYTE* pU2UInfo = NULL;
  742. PBUFFERDESCR pBuf = NULL;
  743. // retrieve call pointer from handle
  744. PH323_CALL pCall;
  745. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineSendUUIE - Entered." ));
  746. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  747. if( pCall == NULL )
  748. {
  749. return LINEERR_INVALCALLHANDLE;
  750. }
  751. if( dwSize && pUserUserInfo )
  752. {
  753. pU2UInfo = (BYTE*)new char[dwSize];
  754. if( pU2UInfo == NULL )
  755. {
  756. pCall -> Unlock();
  757. return LINEERR_NOMEM;
  758. }
  759. pBuf = (PBUFFERDESCR) new BUFFERDESCR;
  760. if( pBuf == NULL )
  761. {
  762. delete pU2UInfo;
  763. pU2UInfo = NULL;
  764. pCall -> Unlock();
  765. return LINEERR_NOMEM;
  766. }
  767. CopyMemory( (PVOID)pU2UInfo, (PVOID)pUserUserInfo, dwSize );
  768. pBuf -> pbBuffer = pU2UInfo;
  769. pBuf -> dwLength = dwSize;
  770. if( !pCall -> QueueTAPICallRequest( TSPI_SEND_U2U, (PVOID)pBuf ))
  771. {
  772. H323DBG(( DEBUG_LEVEL_ERROR, "could not post close event." ));
  773. pCall -> Unlock();
  774. return LINEERR_OPERATIONFAILED;
  775. }
  776. }
  777. //complete the async accept operation now
  778. H323CompleteRequest (dwRequestID, ERROR_SUCCESS);
  779. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineSendUUIE - Exited." ));
  780. pCall -> Unlock();
  781. // async success
  782. return dwRequestID;
  783. }
  784. LONG
  785. TSPIAPI
  786. TSPI_lineMonitorDigits(
  787. HDRVCALL hdCall,
  788. DWORD dwDigitModes
  789. )
  790. {
  791. PH323_CALL pCall;
  792. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineMonitor - Entered." ));
  793. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  794. if( pCall == NULL )
  795. {
  796. return LINEERR_INVALCALLHANDLE;
  797. }
  798. // see if mode empty
  799. if( dwDigitModes == 0 )
  800. {
  801. H323DBG(( DEBUG_LEVEL_VERBOSE, "disabling dtmf detection." ));
  802. // disable monitoring digits
  803. pCall->m_fMonitoringDigits = FALSE;
  804. //unlock the call
  805. pCall -> Unlock();
  806. // success
  807. return NOERROR;
  808. }
  809. else if( dwDigitModes != LINEDIGITMODE_DTMF )
  810. {
  811. H323DBG(( DEBUG_LEVEL_ERROR,
  812. "invalid digit modes 0x%08lx.", dwDigitModes ));
  813. //unlock the call
  814. pCall -> Unlock();
  815. // invalid call handle
  816. return LINEERR_INVALDIGITMODE;
  817. }
  818. H323DBG(( DEBUG_LEVEL_VERBOSE, "enabling dtmf detection." ));
  819. // enable monitoring digits
  820. pCall->m_fMonitoringDigits = TRUE;
  821. //unlock the call
  822. pCall -> Unlock();
  823. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineMonitor - Exited." ));
  824. // success
  825. return NOERROR;
  826. }
  827. LONG
  828. TSPIAPI
  829. TSPI_lineGenerateDigits(
  830. HDRVCALL hdCall,
  831. DWORD dwEndToEndID,
  832. DWORD dwDigitMode,
  833. LPCWSTR pwszDigits,
  834. DWORD dwDuration
  835. )
  836. {
  837. PH323_CALL pCall;
  838. DWORD dwLength;
  839. UNREFERENCED_PARAMETER(dwDuration);
  840. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineGenerateDigits - Entered." ));
  841. // retrieve call pointer from handle
  842. pCall=g_pH323Line -> FindH323CallAndLock(hdCall);
  843. if( pCall == NULL )
  844. {
  845. return LINEERR_INVALCALLHANDLE;
  846. }
  847. // verify that the call was connected
  848. if( pCall -> GetCallState() != LINECALLSTATE_CONNECTED )
  849. {
  850. H323DBG(( DEBUG_LEVEL_ERROR, "call 0x%08lx not connected.", pCall ));
  851. pCall -> Unlock();
  852. return LINEERR_INVALCALLSTATE;
  853. }
  854. // verify monitor modes
  855. if( dwDigitMode != LINEDIGITMODE_DTMF )
  856. {
  857. H323DBG(( DEBUG_LEVEL_ERROR, "invalid digit mode 0x%08lx.",
  858. dwDigitMode ));
  859. pCall -> Unlock();
  860. // invalid call handle
  861. return LINEERR_INVALDIGITMODE;
  862. }
  863. H323DBG(( DEBUG_LEVEL_VERBOSE, "sending user input %S.", pwszDigits ));
  864. if( pwszDigits == NULL )
  865. {
  866. // signal completion
  867. pCall->PostLineEvent (
  868. LINE_GENERATE,
  869. LINEGENERATETERM_CANCEL,
  870. dwEndToEndID,
  871. GetTickCount()
  872. );
  873. pCall -> Unlock();
  874. return NOERROR;
  875. }
  876. LPCWSTR wszDigits = pwszDigits;
  877. for( dwLength = 0; (*wszDigits) != L'\0'; wszDigits++ )
  878. {
  879. if( IsValidDTMFDigit(*wszDigits) == FALSE )
  880. {
  881. // signal completion
  882. pCall->PostLineEvent (
  883. LINE_GENERATE,
  884. LINEGENERATETERM_CANCEL,
  885. dwEndToEndID,
  886. GetTickCount()
  887. );
  888. pCall -> Unlock();
  889. // digit generation cancelled.
  890. return LINEERR_INVALDIGITS;
  891. }
  892. dwLength++;
  893. }
  894. if( dwLength == 0 )
  895. {
  896. H323DBG(( DEBUG_LEVEL_ERROR, "no digits to passo on." ));
  897. pCall -> Unlock();
  898. // invalid call handle
  899. return LINEERR_INVALPARAM;
  900. }
  901. // send user input message
  902. pCall -> SendMSPMessage(
  903. SP_MSG_SendDTMFDigits,
  904. (BYTE*)pwszDigits,
  905. dwLength,
  906. NULL );
  907. // signal completion
  908. pCall->PostLineEvent (
  909. LINE_GENERATE,
  910. LINEGENERATETERM_DONE,
  911. dwEndToEndID,
  912. GetTickCount()
  913. );
  914. H323DBG(( DEBUG_LEVEL_TRACE, "TSPI_lineGenerateDigits - Exited." ));
  915. pCall -> Unlock();
  916. // success
  917. return NOERROR;
  918. }