Interface Description
WebEx Meetings provides the TSP Hybrid Audio Client SDK in order to enable the partner to integrate their TSP Partner VoIP Client with the WebEx Meetings client. This DLL is responsible for interprocess communication (IPC) with the WebEx meeting client, and it is to be packaged within and loaded by the TSP Partner client. It encapsulates all the necessary messaging, IPC, client handshake, heartbeat mechanism and client authentication as follows:
- Asynchronous notification with relatively high frequency but long timeout creates a heartbeat. The DLL exports the timeout interface.
- To alleviate the need for developers to pass HWND in the CreateProcess parameter, the SDK defines a specified window name to find that window.
- If a WebEx Meetings client crashes, and if:
- The TSP Audio Partner Client detects the WebEx Meetings client crash, stop, or hang, the TSP Partner VoIP client should stop VoIP and end the TSP Audio Partner Client process.
- A new WebEx Meetings client process is launched, the WebEx Meetings client launches a new TSP Partner VoIP client which can start a new VoIP connection.
- If the TSP Audio Partner Client crashes and if the WebEx Meetings client detects that the TSP Audio Partner Client has crashed, the WebEx Meetings client creates a new instance of the TSP Audio Partner Client.
- If there are two WebEx Meetings clients, in different meetings, on same computer and both requests VoIP, the TSP Partner VoIP client can keep the first VoIP connection and reject the second VoIP request. Running two meetings on one machine is not officially supported.
The TSPHybridSDK.dll exports the C style API listed below to register and unregister the interface. The DLL also gets appropriate information from WebEx Meetings client before registering the TSP Audio Partner Client.
- C2W_Initialize @1
- C2W_UnInitialize @2
- C2W_GetConnectData @3
- C2W_GetMeetingNumber @4
- C2W_RegisterCSPClient @5
- C2W_UnRegisterCSPClient @6
Verification and Authentication
Encryption of IPC communications
All the IPC communication between the WebEx Meetings Client and the TSP Hybrid Audio SDK are encrypted using AES after the TSP Partner VoIP Client registration has succeeded. The Key is the HybridSDKToken, which is mentioned in the TSP API command, A2W_RspCreateConference. The TSP Partner VoIP Client gets the key by parsing the HybridConnectData according a certain format which is defined by the 3rd partner internal, before registering the TSP Partner VoIP Client to the WebEx Meetings client.
Identification of the VoIP client executable
The WebEx Meetings client determines the TSP Partner VoIP Client main executable file by checking the value of the registry key named by the partner in the TSP API call A2W_RspCreateConference::AppDetection and in one of these two registry locations:
- HKCU\Software\WebEx\TSPSDK\[A2W_RspCreateConference::AppDetection]
- HKLM\Software\WebEx\TSPSDK\[A2W_RspCreateConference::AppDetection]
The registry example below illustrates the following scenario. As an example, the value that was passed for [A2W_RspCreateConference::AppDetection] was "testHybrid" and so the WebEx Meeting Center client examines that registry key value to determine the executable name of the TSP Partner VoIP client. Your AppDetection string should be unique.

Client verification
The following steps outline the client verification process.
- The WebEx Meetings service client verifies the authenticity of the TSP Partner VoIP client by comparing a SHA-1 hash value of the main executable file with the hash list that was passed into the TSP server by [A2W_RspCreateConference::ClientHashList]. If the SHA-1 hash value of the executable file matches one of the entries passed from the list, verification is successful.
- The TSP Partners' server configuration keeps the SHA-1 hash values for all clients. The partner keeps track of different versions which are currently available to their customers. The max length WebEx Meetings accepts for this value can be reviewed in [A2W_RspCreateConference::ClientHashList].
- A partner may wish to prevent the use of a certain VoIP client, for example, due to a bug that requires a newer version. The partner can remove the hash value for that VoIP client version from the hash list. This causes the WebEx Meetings client to show �Install Now� in the audio dialog box asking the user to download a new release. Installations such as these, only occur if the ad-hoc installation is allowed, as defined by [A2W_RspCreateConference::AdhocInstall].
- Once the TSP Partner VoIP client is verified, the WebEx Meetings client launches the TSP Partner VoIP client and waits for the TSP Partner VoIP client to register as described in steps 5 through 7.
- When the TSP Partner VoIP client starts, it gets the meeting number and HybridConnectData from the WebEx Meetings client via C2W_GetMeetingNumber and C2W_GetConnectData. It then parses the token from HybridConnectData and is ready to register to the WebEx Meetings client.
- Then the TSP Partner VoIP client calls C2W_RegisterCSPClient with the token from step 5 to try and register the WebEx Meetings client. The SDK DLL generates a SHA hash value with the timestamp and the token for authentication. This hash ensures that the IPC described in step 8 is a one-to-one match and that the registry verification succeeds.
- The WebEx Meetings client, upon receiving the registry message, calculates a hash value using the same timestamp and the A2W_RspCreateConference::HybridSDKToken. It then compares that hash value with the hash value passed in the message. The WebEx Meetings client trusts the TSP Partner VoIP Client if these two hash values are identical which means the client authentication is accomplished.
- AES encryption and decryption for subsequent IPC communications continues to use the same token.
Logic Description
The figure below represents the major logic and call sequence of the interface between a WebEx Meetings client, TSP Hybrid Client SDK and the TSP Partner VoIP client.

Data Structures and Interfaces
Contents of WbxTSPHybridClient.h
#pragma once namespace tspsdk_cspclient { //User Roles define /** @name User Roles * */ //@{ /*! User role is unknown or user is not exist */ const DWORD WBX_USER_ROLE_UNKNOW = 0x00; /*! Host User role */ const DWORD WBX_USER_ROLE_HOST = 0x01; /*! Presenter User role */ const DWORD WBX_USER_ROLE_PRESENTER = 0x02; /*! Panelist User role */ const DWORD WBX_USER_ROLE_PANELIST = 0x04; /*! Attendee User role */ const DWORD WBX_USER_ROLE_ATTENDEE = 0x08; //@} const long TSP_CHECK_WIZARD_STATUS_ALREADY_RUN = 1; //audio setting ran succeed already const long TSP_CHECK_WIZARD_STATUS_RUNNING = 2; //audio setting dialog is running const long TSP_CHECK_WIZARD_STATUS_NOT_FINISHED = 3; //audio setting dialog was run failed const long TSP_CHECK_WIZARD_STATUS_DEVICE_CHANGED= 4; //audio device changed, suggest to run setting again. const long TSP_VOIP_DEVICE_OK = 1; //Both microphone and speaker work normal const long TSP_VOIP_DEVICE_NO_MICRIPHONE = 2; //Microphone works abnormal, still can join conference const long TSP_VOIP_DEVICE_NO_SPEAKER = 3; //Speaker works abnormal, can't join conference const long TSP_VOIP_DEVICE_ERROR = 4; //Both microphone and speaker work abnormal, can't join conference const long TSP_AUDIO_TYPE_NOCONNECT = 0x00; const long TSP_AUDIO_TYPE_TELE = 0x01; const long TSP_AUDIO_TYPE_VOIP = 0x02; const long TSP_HEARTBEAT_STATUS_NORMAL = 1; const long TSP_HEARTBEAT_STATUS_RECONNECT_START =2; const long TSP_HEARTBEAT_STATUS_RECONNECT_FAILED = 3; const long TSP_HEARTBEAT_STATUS_RECONNECT_SUCCEED = 4; const long TSP_HEARTBEAT_STATUS_UNGISTERED = 5; } //Return value define /** @name the return value define */ //@{ /*! return value : succeed with no error */ #define WBX_TSPSDK_SUCCEED 1 /*! return value : failed with unknown error */ #define WBX_TSPSDK_FAILED 0 /*! return value: the interface is not implemented yet */ #define WBX_TSPSDK_NOTIMPLEMENTED -1 /*! return error value: no meeting data * */ #define WBX_TSPSDK_DATA_NOT_AVAILABLE -2 /*! return error value: meeting service disable the SDK * */ #define WBX_TSPSDK_SDK_DISABLE -3 /*! return error value: current user have no privilege * */ #define WBX_TSPSDK_NO_PRIVILEGE -4 /*! return error value: Input Invalid Param * */ #define WBX_TSPSDK_INVALID_PARAM -5 /*! return error value: current service client don't support the feature. * */ #define WBX_TSPSDK_CLIENT_NOT_SUPPORT -6 /*! return error value: current service client wasn't running * */ #define WBX_TSPSDK_CLIENT_NOT_FOUND -7 /*! return error value: no register SDK. * */ #define WBX_TSPSDK_CLIENT_NOT_REGISTER -8 /*! return error value:The token does not match with the one in WebEx Meetings client retrieved from WebEx Meetings platform. * */ #define WBX_TSPSDK_TOKEN_NOT_MATCH -10 /*! return error value:input file path not valid * */ #define WBX_TSPSDK_FILE_PATH_INVALID -11 /*!return error value: Not initialize, no windows handle of CSP client. * */ #define WBX_TSPSDK_NOT_HANDSHAKE - 12 //@} typedef enum { //Initialize and Enroll before StartVoIP, "Call use computer" button will be disabled before get Enroll_OK TSPSDK_CONNECT_VOIP_INITIALIZING = 1000, //Gather required information as pop up keypad TSPSDK_CONNECT_VOIP_ENROLL_OK, //Enroll/Register to SIP/VoIP server succeed, enable Call PC button TSPSDK_CONNECT_VOIP_ENROLL_FAIL, //Enroll/Register to SIP/VoIP server failed, disable Call PC button //Status update after call W2C_StartVoIP TSPSDK_CONNECT_VOIP_CALLING, //Start to place VoIP call, disable the Cancel button as Partner required to resolve the Cancel action failed issue. TSPSDK_CONNECT_VOIP_CONNECTING, //Connect to bridge TSPSDK_CONNECT_VOIP_RETRY, //Connect failed need user retry TSPSDK_CONNECT_VOIP_CONNECT_OK, //Join audio session succeed TSPSDK_CONNECT_VOIP_CONNECT_FAIL, //Join audio session failed TSPSDK_CONNECT_VOIP_NETWORK_FAIL, //Network error, start to reconnect with CSP server TSPSDK_CONNECT_VOIP_RECONNECT_OK, //Reconnect succeed TSPSDK_CONNECT_VOIP_RECONNECT_FAIL, //Reconnect final failed TSPSDK_CONNECT_VOIP_DISCONNECT, //Disconnect succeed. TSPSDK_CONNECT_VOIP_FLASH, //Reserved for flash VoIP icon in status bar TSPSDK_CONNECT_VOIP_QUALITY_INDICATION, //Reserved to indicate Voice quality bad TSPSDK_CONNECT_UNKNOWN, //Unknown error }TSPSDK_CCONNECT_STATUS;
Contents of WbxTSPHybridClient.h
#pragma once #include "TSPHybridSDKClientDef.h" //===================================================================== //CSP Client Command and notification from WebEx Meetings Client //===================================================================== //In order WebEx Meetings Client send command and notification to CSP Client, the CSP Client must implement this interface , //And please create the new instance of this interface before call #C2W_Initialize //! Class IWbxCspClient /*! In order WebEx Meetings Client send command and notification to CSP Client, the CSP Client must implement this interface , And please create the new instance of this interface before call #C2W_Initialize */ class ICSPClient { public: virtual __checkReturn LONG W2C_StartVoIP(__in int nReason, __in_opt DWORD dwSubConfId = 0, __in_opt BOOL bCheckWizardStatus = TRUE) =0; /*! Start VoIP connect or start Switch from PSTN to VoIP \param[in] nReason : VoIP connect reason, this parameter can be one of the following values: \li #0 : Start VoIP connect normally \li #1 : Switch from PSTN to VoIP \param[in] dwSubConfId : the sub-conference Id for Training Center BO sub-conference and HOL sub-conference \li #0 : Default value, means main conference. \note \li The dwSubConfId is Reserved for TC sub-conference in later release. \param[in] bCheckWizardStatus : Indicate if need to run audio setting dialog first if never set. \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_StopVoIP(__in int nReason) =0; /*! Stop VoIP connection \param[in] nReason : Stop VoIP connection reason, this parameter can be one of the following values: \li #0 : Stop VoIP connect normally \li #1 : Caused by switch from VoIP to PSTN successfully, so confirm drop in the CSP client side again. \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_SetVoIPSpeakerVolume(__in int nVolume) = 0; /*!Set speaker volume when user drag the speaker track bar. \param[in] nVlume: The new speaker volume. \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_SetVoIPMicrophoneVolume(__in int nVolume) = 0; /*!Set microphone volume when user drag the microphone track bar. \param[in] nVlume: The new microphone volume. \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual __checkReturn LONG W2C_CheckWizardStatus() = 0; /*!Check if the audio setting was run already. \return \li #TSP_CHECK_WIZARD_STATUS_ALREADY_RUN, audio setting ran succeed already \li #TSP_CHECK_WIZARD_STATUS_RUNNING, audio setting dialog is running \li #TSP_CHECK_WIZARD_STATUS_NOT_FINISHED, audio setting dialog was run failed \li #TSP_CHECK_WIZARD_STATUS_DEVICE_CHANGED= 4; audio device changed, suggest to run setting again. \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_OpenAudioSetting() = 0; /*!Open the audio setting dialog when user click the audio setting menu and link, etc. \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_CloseAudioSetting() = 0; /*!Close the audio setting dialog \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_BringTopWizard() = 0; /*!Bring the Audio Setting dialog to Topmost. \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_UseDefaultDevice() = 0; /*!Continue use the current default device if use click cancel when pop up the device changed dialog. \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual __checkReturn LONG W2C_IsAudioDeviceNormal() = 0; /*!Check if the audio device is work normal. \return \li #TSP_VOIP_DEVICE_OK, both microphone and speaker work normal \li #TSP_VOIP_DEVICE_NO_MICRIPHONE, microphone works abnormal, still can join conference \li #TSP_VOIP_DEVICE_NO_SPEAKER, speaker works abnormal, can't join conference \li #TSP_VOIP_DEVICE_ERROR, both microphone and speaker work abnormal, can't join conference \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ //Notification from WebEx Meetings Client to CSP Client virtual LONG W2C_OnMeetingEnd() = 0; /*!Notify when meeting is ended or attendee will leave meeting now. \return \li #WBX_TSPSDK_SUCCEED: Ready to unload the module and terminate the process \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_OnParticipantRoleChanged(__in DWORD dwRole) = 0; /*!Set speaker volume when user drag the speaker track bar. \param[in] dwRole: The new role of self. \li: USER_ROLE_UNKNOW: Unknown \li: USER_ROLE_HOST: Host \li: USER_ROLE_PRESENTER: Presenter \li: USER_ROLE_PANELIST Panelist \li: USER_ROLE_ATTENDEE: Attendee \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_OnHeartbeatStatus(__in DWORD dwStatus) = 0; /*!Notify if the heart beat has any issue \param[in] dwStatus: The new speaker volume. \li: TSP_HEARTBEAT_STATUS_NORMAL: Normal \li: TSP_HEARTBEAT_STATUS_RECONNECT_START: Heartbeat abnormal and start to reconnect \li: TSP_HEARTBEAT_STATUS_RECONNECT_FAILED: Heartbeat abnormal and exceed 2.5 minutes, so need to stop VoIP and exit process \li: TSP_HEARTBEAT_STATUS_RECONNECT_SUCCEED: Heartbeat reconnect succeed \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions \note \li: The heartbeat interval is 200ms \li: Will enter recovery mode by 30s if cant receive/service any heartbeat message, and update the heartbeat status to HEARTBEAT_STATUS_RECONNECT_START \li: Finally heartbeat failed if still can't receive/service any heartbeat message by the 2.5mintues timeout interval define in #C2W_RegisterCSPClient, and update status to HEARTBEAT_STATUS_RECONNECT_FAILED and end process. \li: Will turn to HEARTBEAT_STATUS_RECONNECT_SUCCEED if get any heartbeat message before finally timeout. */ virtual LONG W2C_OnCSPPassThroughFromServer(__in_ecount(1024) BYTE* lpBuffer, int nLen) = 0; /*!Pass through data from TSP Server \param[in] lpData: Pass through data, an UTF-8 string with zero end. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_OnConnectDataChanged(__in_ecount_z(1024) LPCTSTR lpszConnectData) = 0; /*!Notify that the connect data need to be updated for optimize TSP traffic, for users connected VoIP already. \param[in] lpszConnectData: The buffer to store the connect data. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_MuteUnmuteSelfSpeaker(BOOL bMute) = 0; /*!Mute self speaker when click speaker icon in speaker/mic volume section of audio dialog. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG W2C_OnClickKeypadIcon() = 0; /*!Notify the CSP client that the user clicked the Key pad icon in the audio dialog. CSP client should show the key pad if it's hide, and bring it to top if show already. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ }; //===================================================================== //CSP Client Event notification sink and WebEx Meetings client command //===================================================================== //In order WebEx Meetings Client to receive the notification even from CSP Client, and CSP client can call command of WebEx Meetings client, the WebEx Meetings TSP Hybrid SDK will implement this interface, //And will return the instance in ppCspClientSink of #C2W_Initialize when register SDK //The CSP Client need to keep this instance and call appropriate interface when VoIP connecting status updated. //The CSP Client also can call WebEx Meetings client command by this interface //! Class IWbxCspClientSink /*! In order CSP Client send command to WBX Client, the WebEx Meetings TSP Hybrid SDK must implement this interface , Will return the instance in in ppCspClientSink of #C2W_Initialize when register SDK */ class IWBXClient { public: virtual LONG C2W_OnConnectIndication(__in TSPSDK_CCONNECT_STATUS connectIndication) =0; /*!Notify the WebEx Meetings client that the connecting status is changed when start VoIP, and also pass the reconnect status when CSP client reconnecting with VoIP server. \param[in] dwStatus: The connect status. \li: TSPSDK_CONNECT_VOIP_ENROLL_OK: Enroll to CSP server succeed \li: TSPSDK_CONNECT_VOIP_ENROLL_FAIL: Enroll to CSP server failed \li: TSPSDK_CONNECT_VOIP_NETWORK_FAIL: Network connect error with CSP server \li: TSPSDK_CONNECT_VOIP_RECONNECT_OK: Network reconnect succeed \li: TSPSDK_CONNECT_VOIP_RECONNECT_FAIL: Network reconnect failed \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_OnVoIPSpeakerLevel(__in int nLevel) = 0; /*!Notify the WebEx Meetings client that the energy changed when others speaking. \param[in] nLevel: The new speaker energy level, 0~100. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_OnVoIPMicrophoneLevel(__in int nLevel) = 0; /*!Notify the WebEx Meetings client that the energy changed when I'm speaking. \param[in] nLevel: The new energy level of self microphone, 0~100. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_OnVoIPSpeakerVolume(__in int nVolume) = 0; /*!Notify the WebEx Meetings client that the volume setting is changed \param[in] nVolume: The new speaker volume, 0~100. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_OnVoIPMicrophoneVolume(__in int nVolume) = 0; /*!Notify the WebEx Meetings client that the microphone volume setting is changed \param[in] nVolume: The new microphone volume, 0~100. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_OnAudioSettingOpened(__in DWORD hwndAudioSettingDlg) = 0; /*!Notify the WebEx Meetings client that the Audio Setting dialog is opened. \param[in] hwndAudioSettingDlg: The handle of the Audio Setting dialog, used to pass to share component for keep consistent behavior with meeting window. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_OnAudioSettingClosed() = 0; /*!Notify the WebEx Meetings client that the Audio Setting dialog is closed. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_OnSelfSpeakerMuted(BOOL bMuted) = 0; /*!Notify the self speaker is muted. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ //Command of WebEx Meetings client. virtual LONG C2W_OpenAudioDialog() = 0; /*!Ask WebEx Meetings client to open the audio dialog \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_CloseAudioDialog() = 0; /*!Ask WebEx Meetings client to close the audio dialog \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_GetMeetingInfo(__out DWORD& dwAttendeeId, __out DWORD& dwLanguage) = 0; /*!Retrieve meeting information from WebEx Meetings client \param[out] dwAttendeeId: The attendee id of myself \param[out] dwLanguage: The L10N language of WebEx meeting client, used to so show the correct UI language of AudioSetting dialog \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_GetParticipantRole(__out DWORD& dwRole) = 0; /*!Retrieve current participant role from WebEx Meetings client \param[out] dwRole: The current participant role of myself \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_GetUserAudioStatus(__out DWORD& dwUserAudioStatus) = 0; /*!Retrieve current audio connected status from WebEx Meetings client \param[out] dwUserAudioStatus: The current VoIP and PSTN connected status of myself \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_CSPPassThrough(__in_ecount(1024) BYTE* lpBuffer, int nLen) = 0; /*!Pass data from CSP client through WebEx Meetings client, WebEx Meetings platform, to CSP server finally. \param[in] lpszData: Pass through data, an UTF-8 string with zero end. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ virtual LONG C2W_OnHeartbeatStatus(__in DWORD dwStatus) = 0; /*!Notify if the heart beat has any issue \param[in] dwStatus: The new speaker volume. \li: TSP_HEARTBEAT_STATUS_NORMAL: Normal \li: TSP_HEARTBEAT_STATUS_RECONNECT_START: Heartbeat abnormal and start to reconnect \li: TSP_HEARTBEAT_STATUS_RECONNECT_FAILED: Heartbeat abnormal and exceed 2.5 minutes, so need to stop VoIP and exit process \li: TSP_HEARTBEAT_STATUS_RECONNECT_SUCCEED: Heartbeat reconnect succeed \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions \note \li: The heartbeat interval is 200ms \li: Will enter recovery mode by 30s if cant receive/service any heartbeat message, and update the heartbeat status to HEARTBEAT_STATUS_RECONNECT_START \li: Finally heartbeat failed if still can't receive/service any heartbeat message by the 2.5mintues timeout interval define in #C2W_RegisterCSPClient, and update status to HEARTBEAT_STATUS_RECONNECT_FAILED and end process. \li: Will turn to HEARTBEAT_STATUS_RECONNECT_SUCCEED if get any heartbeat message before finally timeout. */ virtual LONG C2W_OnAudioDeviceChanged(BOOL bRemoveDevice, BOOL bOutputDevice) = 0; /*!Notify the WebEx Meetings client that the user plug in / pull out a (USB) audio device when be in audio conference already. WebEx Meetings client will show a device changed dialog to ask user if he need to run audio setting dialog to select device \param[in] bRemoveDevice: Pull out the current using audio device. \param[in] bOutputDevice: The changed device is output device (speaker), otherwise input device (microphone). \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ }; extern "C" { LONG WINAPI C2W_Initialize(__in ICSPClient* pCspClient, __out IWBXClient** ppWbxAudioClient); /*! Initialize the agent window instance and prepare for IPC \param[in] pCspClient: The CSP Client instance used to receive command and notification from WebEx client. \param[in] ppCspClientSink: The CSP Client sink used to call command of WebEx client and send notification to WebEx client. \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_INVALID_PARAM Failed: Input invalid param. \li #WBX_TSPSDK_CLIENT_NOT_START Failed: be not able to register for no running WebEx Service Client \li #WBX_TSPSDK_SDK_DISABLE Failed: the WebEx Client SDK is disabled, it dot support integration \li #WBX_TSPSDK_NO_PRIVILEGE Failed: Have no privilege to call the interface. \li #WBX_TSPSDK_SITEID_PARTNERID_NOT_MATCH Failed: \li #WBX_TSPSDK_TOKEN_NOT_MATCH Failed: \li #WBX_TSPSDK_FAILED Failed: all other unknown Errors and Exceptions \sa IWebExClientSink \warning User must call this interface first */ LONG WINAPI C2W_UnInitialize(); /*! Destroy the agent windows, and ready to unload the DLL \return \li #WBX_TSPSDK_SUCCEED: Succeeded \sa IWebExClientSink \warning User must call this interface first */ LONG WINAPI C2W_GetMeetingNumber(__out LONG& lMeetingNumber); /*!Get the meeting number from WebEx Meetings client \param[out] lMeetingNumber: The meeting number / conference Id \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ LONG WINAPI C2W_GetConnectData(__out_ecount(cchMaxLenght) LPTSTR lpszConnectData, __in int cchMaxLenght); /*!Get the connect data used to connect to CSP server \param[out] lpszConnectData: The buffer to store the connect data, in \param[in] cchMaxLength: The max element length of the buffer. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ LONG WINAPI C2W_RegisterCSPClient(__in LPCSTR szToken, __in_opt int nHeartbeatTimeout = 150000, __in_opt BOOL bShowKeypadIcon = FALSE); /*! Register the CSP client \param[in] szToken: The token used to handshake authentication and encrypt/decrypt the IPC data \param[in] nHeartbeatTimeout: The heartbeat timeout interval which indicate the WebEx client was crashed finally and need to end the CSP client process. Millisecond, default value is 150,000, 2.5minutes. \param[in] bShowKeypadIcon: Whether the audio dialog should show a key pad icon to let user bring out the dial key pad \return \li #WBX_TSPSDK_SUCCEED: Succeeded \li #WBX_TSPSDK_INVALID_PARAM Failed: Input invalid param. \li #WBX_TSPSDK_CLIENT_NOT_START Failed: be not able to register for no running WebEx Service Client \li #WBX_TSPSDK_SDK_DISABLE Failed: the WebEx Client SDK is disabled, it dot support integration \li #WBX_TSPSDK_NO_PRIVILEGE Failed: Have no privilege to call the interface. \li #WBX_TSPSDK_SITEID_PARTNERID_NOT_MATCH Failed: \li #WBX_TSPSDK_TOKEN_NOT_MATCH Failed: \li #WBX_TSPSDK_FAILED Failed: all other unknown Errors and Exceptions \sa IWebExClientSink \warning Need to call this API to authenticate the CSP client before call any registered required APIs */ LONG WINAPI C2W_UnRegisterCSPClient(); /*! UnRegister WebEx TSP Client SDK \param[in] dwReserved : Reserved for interface extensible \return return one BOOL value \li #WBX_TSPSDK_SUCCEED Succeeded \li #WBX_TSPSDK_FAILED : Failed \warning \li User must call the interface when exit and don't use the Service SDK . \li as long as user has ever called #C2W_RegisterCSPClient , whether it register successfully or fail, user must call the interface to clean some resource when application exit and don't use the Service SDK. */ LONG WINAPI C2W_GetSDKVersion(__out_ecount(cchBufferMax) LPTSTR lpszVersion, int cchBufferMax, __in_opt void* pReserved = NULL); /*!Get the SDK version from WebEx SDK client \param[out] lpszVersion: The buffer to store the version \param[in] cchMaxLength: The max element length of the buffer. \return \li #WBX_TSPSDK_SUCCEED: Succeed \li #WBX_TSPSDK_FAILED Failed: all unknown Errors & Exceptions */ };
Restrictions and Limitations
The following limitations and restrictions exist for TSP Hybrid Partner VoIP client.
- A cascading failure occurs when a WebEx Meetings client crashes, while in a meeting with a TSP Hybrid Partner VoIP client connected and does not restart within 2.5 minutes. The TSP Hybrid Partner VoIP client also exits when it becomes aware of the crash since there is no longer UI control.
- If a TSP Hybrid Partner VoIP client rejoins a meeting quickly after exiting, the TSP server waits for the process associated with the older client join to end and then starts a new TSP Hybrid Partner VoIP client instance to join the VoIP session with a new Attendee Id.
- Only one TSP Hybrid Partner VoIP client can join a meeting from a single machine, even if there are multiple TSP Hybrid Partner VoIP clients launched on that machine.
Performance Issues
The following activities may appear to effect performance.
- The Register interface waits for a while until register completes successfully or fails.
- PostMessage implements Heartbeat with high frequency, but it does not have performance issues since PostMessage is an asynchronous mechanism.
- PostMessage implements Speaker and Microphone energy notifications to avoid performance issue.
Input Data Validation
All of the TSP Hybrid Audio Client SDK interfaces use input data validation defined by SAL (Microsoft's standard source code annotation language). The SAL annotations describe how an interface uses it parameters, assumptions about the parameters, and the expected actions upon completion of the interface.
Working with Windows Registry and User Access Controls
The webex client is compiled as a 32 bit application. On 64 bit machines, a 32 bit application cannot directly access folders under HKLM. This can cause problems with user accounts that do not have administrative rights on their local PC. Windows has created a special folder for 32 bit applications to read from called wow6432node.
Your client installer should write to the following registry locations to account for User Account Controls on windows.
- HKLM\software\wow6432node\webex\TSPSDK on 64 bit machines (Webex is a 32 bit application)
- HKLM\software\webex\TSPSDK on 32 bit machines
- HKCU\Software\WebEx\TSPSDK