Kaidul

SessionControl

Dec 19th, 2014
277
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 163.12 KB | None | 0 0
  1. // SessionControl.cpp : Implementation of CSessionControl
  2.  
  3. #include "stdafx.h"
  4.  
  5. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  6.  
  7. #ifndef _WIN32_WCE
  8. #include "MediaSession_win.h"
  9. #else
  10. #include "MediaSession_win.h"
  11. #endif
  12.  
  13. #include <WinInet.h>
  14.     #include "SessionControl.h"
  15.  
  16.     #include "registry.h"
  17.     #ifdef _WIN32_WCE
  18.     #  include "PALthread.h"
  19.     #  include "Msgqueue.h"
  20.     #  include "pm.h"
  21.     #endif
  22.  
  23. #else
  24.     #include "SessionControl_unix.h"
  25.     #include "MFControl_unix.h"
  26. #endif
  27.  
  28. #include "SessionAgent.h"
  29. #include "CallHistory.h"
  30. #include "Framework.h"
  31. #include "TextUtil.h"
  32. #include "CallLine.h"
  33. #include "CodecConfig.h"
  34. #ifndef NO_DATA_TRAVELER
  35. #include "DataTraveler.h"
  36. #endif
  37. #if (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  38. #include "WinRtInet.h"
  39. #else
  40. #include "PALinet.h"
  41. #endif
  42. #include "MediaSessionUtil.h"
  43. #include "SipAccount.h"
  44. #include "PALdebuglog.h"
  45. #include "PALsystime.h"
  46. #include "common.h"
  47.  
  48. #include <jni.h>
  49. #include <android/log.h>
  50. #include <android/asset_manager.h>
  51. #include <android/asset_manager_jni.h>
  52. #include <openssl/ssl.h>
  53. #include <openssl/asn1.h>
  54. #include <openssl/bio.h>
  55. #include <openssl/x509.h>
  56. #include <openssl/x509_vfy.h>
  57. #include <openssl/pem.h>
  58. #include <openssl/x509v3.h>
  59. #include <openssl/err.h>
  60. #include <openssl/conf.h>
  61. #include <string.h>
  62.  
  63. using std::string;
  64.  
  65. #ifndef __unix__
  66. #include "EComUtil2.h"
  67. using namespace eyeball;
  68. #endif
  69.  
  70. #if (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  71. #define ToInternalBstr
  72. #else
  73. #define ToInternalBstr  ToBstr
  74. #endif
  75.  
  76. using namespace MediaSessionUtil;
  77.  
  78. #ifndef _WIN32_WCE
  79. #define FIREWALL_INFO_FILENAME  PAL_FILE_IN_LOG_DIR("MediaSession.txt")
  80. #else
  81. #define FIREWALL_INFO_FILENAME  "FirewallInfo.txt"
  82. #endif
  83.  
  84. #define CALL_HISTORY_FILENAME   "eyeball_call_history.log"
  85.  
  86. #define CHECK_POINTER(X) \
  87.     if (NULL == (X))\
  88.         return ThrowError("ERROR: NULL pointer.");
  89.  
  90. #define CHECK_MEDIAFRAMEWORK() \
  91.     if (!m_pFramework->m_mediaFramework)\
  92.         return ThrowError("ERROR: Media Framework control is not registered.");
  93.  
  94. #define CHECK_SIP_ACCOUNT() \
  95.     if (m_iSelectedAccount == -1)\
  96.     return ThrowError("ERROR: No sip account is selected.");
  97.  
  98. #if defined(__unix__)
  99. #define FIRE_EVENT(X, ...)  if(m_CallbackHandler) { m_CallbackHandler->X(__VA_ARGS__); }
  100. #elif (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  101. #define FIRE_EVENT(X, ...)  if(m_CallbackHandler) { m_CallbackHandler->FireEvent##X(__VA_ARGS__); }
  102. #else
  103. #define FIRE_EVENT(X, ...)  { Fire_##X(__VA_ARGS__); }
  104. #endif
  105.  
  106. #define CUSTOM_REGISTRATION_RESPONSE_TIMEOUT 20 // 45
  107. #define CUSTOM_INVITE_RESPONSE_TIMEOUT      32  // used to be 2...
  108. #define CUSTOM_LOGOUT_RESPONSE_TIMEOUT      7   //36
  109.  
  110. #define REGISTRATION_RFRESH_TIMER_ID        1
  111. #define SIGNAL_CHANNEL_KEEP_ALIVE_TIMER_ID  ((REGISTRATION_RFRESH_TIMER_ID) +  (MAXIMUM_SIP_ACCOUNT)      )
  112. #define TRANSACTION_TIMER_ID                ((REGISTRATION_RFRESH_TIMER_ID) + ((MAXIMUM_SIP_ACCOUNT) * 2))
  113. #define REGISTRATION_RESPONSE_TIMER_ID      ((REGISTRATION_RFRESH_TIMER_ID) + ((MAXIMUM_SIP_ACCOUNT) * 3))
  114. #define INVITE_RESPONSE_TIMER_ID            ((REGISTRATION_RFRESH_TIMER_ID) + ((MAXIMUM_SIP_ACCOUNT) * 4))
  115. #define LOGOUT_RESPONSE_TIMER_ID            ((REGISTRATION_RFRESH_TIMER_ID) + ((MAXIMUM_SIP_ACCOUNT) * 5))
  116. #define DATA_CHANNEL_KEEP_ALIVE_TIMER_ID    ((REGISTRATION_RFRESH_TIMER_ID) + ((MAXIMUM_SIP_ACCOUNT) * 6))
  117.  
  118. #ifdef _SUPPORT_EVENT_PACKAGE
  119. #define MWI_RFRESH_TIMER_ID                 REGISTRATION_RFRESH_TIMER_ID + (MAXIMUM_SIP_ACCOUNT * 7)
  120. #endif
  121.  
  122. #define UPDATE_CONF_LIST_TIMER_ID           REGISTRATION_RFRESH_TIMER_ID + (MAXIMUM_SIP_ACCOUNT * 8)
  123.  
  124. // timeout in second
  125. #define REGISTRATION_RESPONSE_TIMEOUT       10 // 10 second
  126. #define INVITE_RESPONSE_TIMEOUT             10 // 10 second
  127. #define LOGOUT_RESPONSE_TIMEOUT             5  // 5 second
  128.  
  129. #define TRANSACTION_TIMER_INTERVAL          1000    // 500
  130.  
  131. #define DATA_CHANNEL_KEEP_ALIVE_PERIOD      10
  132.  
  133. #define MAX_SENT_KEEP_ALIVE_COUNT           3
  134.  
  135. #define KILL_TIMER(X) if (X) {KillTimer(X); (X) = 0;}
  136. #define INVALID_ACCOUNT_ID (-1)
  137.  
  138. #define _CUSTOM_TIMER_
  139.  
  140. int g_AFPPMultiplier = 1;   // AudioFramesPerPacket
  141.  
  142. #if defined(__unix__) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  143. CSessionControl *g_pSessionControl = NULL;
  144. CPostMessage *g_pSipPostMessageControl = NULL;
  145. #endif
  146.  
  147. #ifdef _WIN32_WCE
  148. bool g_AudioPTime60MsInVideoCalls = true;
  149. #endif
  150.  
  151. #if (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  152. static int iPARAM2;
  153. #define SetChannelOption(A, B, C)   SetChannelOption(A, B, &(iPARAM2=C))
  154. #endif
  155.  
  156. //#define SIP_URI_CASE_SENSITIVE
  157.  
  158. //void OpenGLPause(bool bPause);  // Defined in VideoX
  159.  
  160. #if defined(__unix__) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  161. CSessionControl::CSessionControl(CSipCommEventHandler_PTR callback_handler):
  162.     CCustomTimer(this)
  163. {
  164.     g_pSessionControl = this;
  165.     g_pSipPostMessageControl = this;
  166.     m_bWindowOnly = TRUE;
  167.     m_CallbackHandler = callback_handler;
  168.     FinalConstruct();
  169.     BOOL b = false;
  170.     OnCreate(0,0,0,b);
  171. }
  172. #endif
  173.  
  174. #define SAFE_LOG(...)   if(g_pSessionControl) g_pSessionControl->m_pFramework->Log(__VA_ARGS__)
  175. #define DEBUG_LOG_TAG "kaidul_SSL"
  176. #define SSL_ASSERT(X, ...) \
  177.     if(!(X)) { \
  178.         __android_log_print(ANDROID_LOG_DEBUG, DEBUG_LOG_TAG, __VA_ARGS__); \
  179.         SAFE_LOG(__VA_ARGS__); \
  180.         return 0; \
  181.     }
  182.  
  183. #define SSL_LOG(...) \
  184.     __android_log_print(ANDROID_LOG_DEBUG, DEBUG_LOG_TAG, __VA_ARGS__); \
  185.     SAFE_LOG(__VA_ARGS__);
  186.  
  187. static int verify_certificate_hostname(X509 *cert, char *hostname) {
  188.   int                   extcount;
  189.   int           success = 0;
  190.   char                  name[256];
  191.   X509_NAME             *subj;
  192.   const char            *extstr;
  193.   CONF_VALUE            *nval;
  194.   X509_EXTENSION        *ext;
  195.   X509V3_EXT_METHOD     *meth;
  196.   STACK_OF(CONF_VALUE)  *val;
  197.   void          *ext_internal;
  198.  
  199.   if ((extcount = X509_get_ext_count(cert)) > 0) {
  200.     for (int i = 0; !success && i < extcount;  i++) {
  201.       ext = X509_get_ext(cert, i);
  202.       extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
  203.       if (!strcasecmp(extstr, "subjectAltName")) {
  204.         if (!(meth = X509V3_EXT_get(ext))) break;
  205.         const unsigned char *data = ext->value->data;
  206.     ext_internal = X509V3_EXT_d2i(ext);
  207.        
  208.     val = meth->i2v(meth, ext_internal, 0);
  209.         for (int j = 0;  j < sk_CONF_VALUE_num(val);  j++) {
  210.           nval = sk_CONF_VALUE_value(val, j);
  211.           if (!strcasecmp(nval->name, "DNS") && !strcasecmp(nval->value, hostname)) {
  212.             success = 1;
  213.             break;
  214.           }
  215.         }
  216.       }
  217.     }
  218.   }
  219.    
  220.   if (!success && (subj = X509_get_subject_name(cert)) && X509_NAME_get_text_by_NID(subj, NID_commonName, name, sizeof(name)) > 0) {
  221.     name[sizeof(name) - 1] = '\0';
  222.     if (!strcasecmp(name, hostname)) success = 1;
  223.   }
  224.    
  225.   return success;
  226. }
  227.  
  228. static int certificate_verifier_callback(void *ctx, void *arg)
  229. {
  230.     SSL_LOG("Callback called for certificate verification.");
  231.  
  232.         OpenSSL_add_all_algorithms();
  233.     ERR_load_crypto_strings();
  234.    
  235.     char *hostname = "www.smartbabymonitor.ugrow.philips.com";
  236.         X509_STORE_CTX store_ctx = X509_STORE_CTX(*(X509_STORE_CTX*)ctx);
  237.     int rc = X509_verify_cert(&store_ctx);
  238.         X509 *cert = X509_STORE_CTX_get_current_cert(&store_ctx);
  239.         SSL_ASSERT(cert != NULL, "Server certificate invalid.");
  240.     SSL_LOG("Server Certificate valid.");
  241.    
  242.     int err = X509_STORE_CTX_get_error(&store_ctx);
  243.     switch(err) {
  244.         case X509_V_ERR_CERT_NOT_YET_VALID:
  245.         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
  246.                     SSL_ASSERT(false, "Certificate is not valid yet.");
  247.                     break;
  248.             case X509_V_ERR_CERT_HAS_EXPIRED:
  249.             case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
  250.                     SSL_ASSERT(false, "Certificate is expired.");
  251.                     break;
  252.         case X509_V_ERR_CRL_NOT_YET_VALID:
  253.             SSL_ASSERT(false, "Certificate Revocation List is not yet valid.");
  254.                     break;
  255.             case X509_V_ERR_CRL_HAS_EXPIRED:
  256.             SSL_ASSERT(false, "Certificate Revocation List is expired.");
  257.                     break;
  258.         default:
  259.             break;
  260.     }
  261.     SSL_LOG("Certificate is up-to-date.");
  262.     SSL_LOG("CRL list checking success."); 
  263.  
  264.     /* Server Certificate hostname verification */
  265.     SSL_ASSERT(verify_certificate_hostname(cert, hostname) == 1, "Hostname verification failed.");
  266.     SSL_LOG("Hostname verification success.");
  267.    
  268.     /*
  269.     AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
  270.     AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
  271.     const char* filename = "philips_trusted_cert.pem";
  272.     while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
  273.             AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
  274.             char buf[BUFSIZ];
  275.             int nb_read = 0;
  276.             FILE* out = fopen(filename, "w");
  277.             while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
  278.                 fwrite(buf, nb_read, 1, out);
  279.             fclose(out);
  280.             AAsset_close(asset);
  281.     }
  282.     AAssetDir_close(assetDir);
  283.     */
  284.  
  285.     return 1;  
  286.     /////////////////////////////////////////////////////////////////////////////////////////////////////////      
  287.        
  288.         const char *path = "/home/nayeem/Desktop/philips_trusted_cert.pem";
  289.         FILE* fp = fopen(path, "r");
  290.         if(!fp) {
  291.         SAFE_LOG("Unable to open local certificate.");
  292.         __android_log_print(ANDROID_LOG_DEBUG, DEBUG_LOG_TAG, "\nUnable to open local certificate.\n");
  293.             return 0;
  294.         }
  295.         fseek(fp, 0, SEEK_END);
  296.         size_t size = ftell(fp);
  297.         char* data = new char[size];
  298.         rewind(fp);
  299.         fread(data, sizeof(char), size, fp);
  300.         fclose(fp);
  301.  
  302.         BIO *bio = BIO_new(BIO_s_mem());
  303.         BIO_puts(bio, data);
  304.         delete[] data;
  305.  
  306.         X509 *cert2 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
  307.         BIO_free(bio);
  308.        
  309.         if(!cert2) {
  310.                 X509_free(cert);
  311.                 //SAFE_LOG("Local certificate X509 object invalid..");
  312.                 return 0;
  313.         }
  314.  
  315.         EVP_PKEY *pkey = X509_get_pubkey(cert2);
  316.         int result = X509_verify(cert, pkey);
  317.        
  318.     if(result > 0) {
  319.         //SAFE_LOG("Certificate Verification Success.");
  320.         __android_log_print(ANDROID_LOG_DEBUG, DEBUG_LOG_TAG, "\nCertificate Verification Success.\n");
  321.     } else {
  322.         //SAFE_LOG("Certificate Verification Failed.");
  323.         __android_log_print(ANDROID_LOG_DEBUG, DEBUG_LOG_TAG, "\nCertificate Verification Failed.\n");
  324.     }
  325.  
  326.     EVP_PKEY_free(pkey);
  327.         X509_free(cert2);
  328.         X509_free(cert);
  329.              
  330.     return result == 1;
  331. }
  332.  
  333. HRESULT CSessionControl::FinalConstruct()
  334. {
  335.     m_iMaximumAccount = MAXIMUM_SIP_ACCOUNT;
  336.    
  337. #ifdef USE_NSSTREAM_FOR_SIP
  338.     m_pApplicationModeMutex = new PAL::Mutex;
  339. #endif
  340.    
  341.     SipAccount* sipAccount = new SipAccount(this);
  342.     PAL_DB_ASSERT(sipAccount);
  343.  
  344.     m_iSelectedAccount = DEFAULT_ACCOUNT_ID; /* Automatically set selectedAccount to the just-created account */
  345.     m_pFramework = new CFramework(this);
  346.     m_pCallHistory = new CCallHistory(this);
  347.     m_pCallLine = new CCallLine(this);
  348.     m_pCodecConfig = new CCodecConfig;
  349. #ifndef NO_DATA_TRAVELER
  350.     m_pDataTraveler = new CDataTraveler(this);
  351. #endif
  352.  
  353.     PAL_ASSERT(m_pFramework);
  354.     PAL_ASSERT(m_pCallHistory);
  355.     PAL_ASSERT(m_pCallLine);
  356.     PAL_ASSERT(m_pCodecConfig);
  357. #ifndef NO_DATA_TRAVELER
  358.     PAL_ASSERT(m_pDataTraveler);
  359. #endif
  360.    
  361.     /*order is important. First add(..), then Init(..)*/
  362.     AddAccount(m_iSelectedAccount, sipAccount);
  363.     sipAccount->Init(m_iSelectedAccount);
  364.  
  365.     /**Init() not-account-specific objects
  366.     with Selected SipAccnt.*/
  367.  
  368.     m_pFramework->Init(m_iSelectedAccount);
  369.     m_pCallHistory->Init(m_iSelectedAccount);
  370.     m_pCallLine->Init(m_iSelectedAccount);
  371.  
  372. #ifndef NO_DATA_TRAVELER
  373.     /*must call this, so the accountID in DataTraveler is valid.*/
  374.     m_pDataTraveler->SetSipAccountId(m_iSelectedAccount);
  375. #endif
  376.  
  377.     m_pFramework->Log("AFEngine loading...");
  378.    
  379.     m_pAFEngine.reset(new CAnyFirewallEngine);
  380.     PAL_ASSERT(m_pAFEngine.get());
  381.  
  382. #ifdef USE_NSSTREAM_FOR_SIP
  383.     m_pNSsocket.reset(new CNSsocket);
  384.     PAL_ASSERT(m_pNSsocket.get());
  385. #endif
  386.  
  387.     m_bAFEngineInit = false;
  388.  
  389.     LoadAFEngine();
  390.  
  391.     m_pFramework->SetAFEngine(m_pAFEngine, m_iAFEServerStoreID);
  392.  
  393.     SipAccount* sipAccnt = GetSipAccount(m_iSelectedAccount);
  394.    
  395.     RET_ERROR_STR(sipAccnt);
  396.  
  397.     if(m_bAFEngineInit)
  398.     {
  399. #ifdef USE_NSSTREAM_FOR_SIP
  400.         // This must be set before setting AFEngine since setting AFEngine starts thread which uses the NSsocket
  401.         sipAccnt->m_pAgent->SetNSsocket(m_pNSsocket);
  402. #endif
  403.         sipAccnt->m_pAgent->SetAFEngine(m_pAFEngine, m_iAFEServerStoreID);
  404. #ifndef NO_DATA_TRAVELER
  405.         m_pDataTraveler->SetAFEngine(m_pAFEngine, m_iAFEServerStoreID);
  406. #endif
  407.     }
  408.  
  409.     m_iUpdateConferenceListTimer = 0;
  410.  
  411. #ifdef WCE_PLATFORM_STANDARDSDK_500
  412.     m_hNewWindowsMessage = NULL;
  413.     m_hQuitWindowsMessageThread = NULL;
  414.  
  415.     // events
  416.     m_hNewWindowsMessage = new PAL::Event;
  417.     m_hQuitWindowsMessageThread = new PAL::Event;
  418.     PAL_ASSERT(m_hNewWindowsMessage);
  419.     PAL_ASSERT(m_hQuitWindowsMessageThread);
  420.  
  421.     m_pWindowsMessageQueueMutex.reset(new PAL::Mutex);
  422.     PAL_ASSERT(m_pWindowsMessageQueueMutex.get());
  423.  
  424.     m_pWindowsMessageThread.reset(new PAL::Thread(WindowsMessageThread, this));
  425.     PAL_ASSERT(m_pWindowsMessageThread.get());
  426. #endif
  427.  
  428. #ifdef _WIN32_WCE
  429.     MSGQUEUEOPTIONS mqo;
  430.     mqo.dwSize = sizeof(MSGQUEUEOPTIONS);
  431.     mqo.dwFlags = 0;
  432.     mqo.dwMaxMessages = 0;
  433.     mqo.cbMaxMessage = 30;
  434.     mqo.bReadAccess = true;
  435.  
  436.     if (m_hPowerMsgQueue = CreateMsgQueue(NULL, &mqo)) {
  437.         m_hPowerNotifications
  438.           = RequestPowerNotifications(m_hPowerMsgQueue, PBT_RESUME);
  439.  
  440.         if (m_hPowerNotifications == NULL) {
  441.             CloseMsgQueue(m_hPowerMsgQueue);
  442.             m_hPowerMsgQueue = NULL;
  443.         }
  444.     }
  445.  
  446.     if (m_hPowerMsgQueue) {
  447.         m_hQuitSuspendMonitorThread = CreateEvent(NULL, FALSE, FALSE, NULL);
  448.         PAL_ASSERT(m_hQuitSuspendMonitorThread);
  449.  
  450.         m_pSuspendMonitorThread.reset(new PAL::Thread(SuspendMonitorThread, this));
  451.         PAL_ASSERT(m_pSuspendMonitorThread.get());
  452.     }
  453. #endif
  454.    
  455.     m_pAFEngine->SetCertificateVerificationCallback(certificate_verifier_callback);
  456.  
  457.     m_bDisableCalls = false;
  458.     m_pNonBlockingCallMutex = new PAL::Mutex;
  459.    
  460.     if(PAL::IsLogEnabled(PAL::PAL_LOG_MSA))
  461.         m_fp = fopen(PAL_LOG_FILENAME_MSA,"w+");
  462.     else
  463.         m_fp = NULL;
  464.    
  465.     MSA_LOG("starting log...");
  466.     return S_OK;
  467. }
  468.  
  469. #if defined(__unix__) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  470. CSessionControl::~CSessionControl()
  471. {
  472.     BOOL b = false;
  473.     OnDestroy(0,0,0,b);
  474.     FinalRelease();
  475.     g_pSessionControl = NULL;
  476.     g_pSipPostMessageControl = NULL;
  477. }
  478. #endif
  479.  
  480. void CSessionControl::FinalRelease()
  481. {  
  482. #ifdef WCE_PLATFORM_STANDARDSDK_500
  483.     m_hQuitWindowsMessageThread.set();
  484.     m_pWindowsMessageThread->join();
  485.  
  486.     // threads
  487.     m_pWindowsMessageThread.reset();
  488.  
  489.     // mutexs
  490.     m_pWindowsMessageQueueMutex.reset();
  491.  
  492.     delete m_hNewWindowsMessage;
  493.     delete m_hQuitWindowsMessageThread;
  494. #endif
  495.        
  496.     m_bDisableCalls = true;
  497.     JoinNonBlockingCallThreads(true);
  498.  
  499.     //Logout();
  500.     ShutDownAllAccounts(); //shuts down and logs out all SIP accounts
  501.     MSA_LOG("In SessionControl FinalRelease...");
  502.     PAL_DB("Final Release.");
  503.     m_iSelectedAccount = -1; /*reset Selected Account index.*/
  504.  
  505.     for (SipAccountMap::iterator accntIter = m_sipAccountMap.begin(); accntIter != m_sipAccountMap.end(); ++accntIter)
  506.     {
  507.         SipAccount* pAccnt = (SipAccount*)accntIter->second;
  508.         delete pAccnt;
  509.     }
  510.     m_sipAccountMap.clear(); //clear the map.
  511.  
  512.     SAFE_DELETE(m_pCallHistory);
  513.     SAFE_DELETE(m_pCodecConfig);
  514. #ifndef NO_DATA_TRAVELER
  515.     SAFE_DELETE(m_pDataTraveler);
  516. #endif
  517.     SAFE_DELETE(m_pCallLine);
  518.     SAFE_DELETE(m_pNonBlockingCallMutex);
  519.  
  520.     MSA_LOG("Final release done: " + itoa(m_sipAccountMap.size()));
  521.  
  522.     if (m_pAFEngine.get())
  523.     {
  524.         UnloadAFEngine();
  525.         m_pAFEngine.reset();
  526.         MSA_LOG("Anyfirewall library is released.");
  527.     }
  528.  
  529. #ifdef USE_NSSTREAM_FOR_SIP
  530.     SAFE_DELETE(m_pApplicationModeMutex);
  531.  
  532.     if (m_pNSsocket.get())
  533.     {
  534.         m_pNSsocket.reset();
  535.         MSA_LOG("NSsocket object is released.");
  536.     }
  537. #endif
  538.  
  539.     // Close this at the end, otherwise logs cannot be written in Framework's log file after that
  540.     m_pFramework->Close();  //close mediaFramework.
  541.     m_pFramework->Shutdown();
  542.     SAFE_DELETE(m_pFramework);
  543.  
  544.     if(m_fp)
  545.         fclose(m_fp);
  546. }
  547.  
  548. bool CSessionControl::LoadAFEngine()
  549. {
  550.     m_pFramework->Log("Loading AFEngine...");
  551.     if(m_bAFEngineInit){
  552.         m_pFramework->Log("AFEngine already loaded");
  553.         return true;
  554.     }
  555.  
  556.     if(!m_pAFEngine.get())
  557.         return false;
  558.  
  559. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  560.     CLSID clsid = DEF_CLSID_ANYFIREWALL;
  561.     LPOLESTR wszCLSID = NULL;
  562.     HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
  563.  
  564.     tstring sClsID = wszCLSID;
  565.     // Free memory.
  566.     CoTaskMemFree(wszCLSID);
  567.  
  568.     tstring sKey = TEXT("CLSID\\");
  569.     sKey += sClsID;
  570.     sKey += TEXT("\\InprocServer32");
  571.  
  572.     tstring sData;
  573.     tstring sValue;
  574.     GetRegistryEntry(HKEY_CLASSES_ROOT, sKey, sValue, sData);
  575. #endif
  576.  
  577.     m_bAFEngineInit =
  578. #if (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  579.         m_pAFEngine->Init(AF_MODE_STANDARD, true);
  580. #elif defined(WIN32)
  581.         m_pAFEngine->InitDll(_Module.GetModuleInstance(),
  582. #if (AF_DLL_VERSION > 950000 && AF_DLL_VERSION < 9600000)
  583.            AF_MODE_AUTO, true
  584. #else
  585.            sData.mbs()
  586. #endif
  587.        );
  588. #else
  589.         m_pAFEngine->Init(
  590. #if (AF_DLL_VERSION > 950000 && AF_DLL_VERSION < 9600000)
  591.             AF_MODE_AUTO, true
  592. #endif
  593.         );
  594. #endif
  595.  
  596.     if(m_bAFEngineInit)
  597.     {
  598.         m_pFramework->Log("AFEngine loaded.");
  599.         //m_pAFEngine->SetFirewallDetectionPeriod(0);
  600.     }
  601.     else
  602.     {
  603.         m_pFramework->Log("AFEngine cannot load!!!");
  604.     }
  605.  
  606.     PAL_ASSERT(m_bAFEngineInit);
  607.  
  608. #if (AF_DLL_VERSION > 9600000)
  609. #if (AF_DLL_VERSION > 10011600)
  610.     if(PAL::IsLogEnabled(PAL::PAL_LOG_AF_MESSAGE)){
  611.         m_pAFEngine->SetLogFilePath(PAL::GetLogPath().c_str());
  612.     }
  613. #endif
  614.     m_pAFEngine->SetLogFileOptions(5, 2);
  615.     m_iAFEServerStoreID = m_pAFEngine->CreateServerStore(AF_MODE_AUTO, true);
  616.  
  617. #if (AF_DLL_VERSION >= 10011619)
  618.     m_pAFEngine->SetNetworkType(m_iAFEServerStoreID, EAfIPv4Only);
  619. #endif
  620. #endif
  621.  
  622.     int iAfOptionTrue = AF_OPTION_TRUE;
  623. #if (AF_DLL_VERSION >= 10011629)
  624.     m_pAFEngine->SetChannelOption(0, EAfOptionManualMode, &iAfOptionTrue);
  625.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableStun, &iAfOptionTrue);
  626.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableTurn, &iAfOptionTrue);
  627.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableHTTPTunneling, &iAfOptionTrue);
  628.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableUPnP, &iAfOptionTrue);
  629. #else
  630.     m_pAFEngine->SetChannelOption(0, EAfOptionManualMode, iAfOptionTrue);
  631.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableStun, iAfOptionTrue);
  632.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableTurn, iAfOptionTrue);
  633.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableHTTPTunneling, iAfOptionTrue);
  634.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableUPnP, iAfOptionTrue);
  635. #endif
  636.  
  637.     return m_bAFEngineInit;
  638. }
  639.  
  640. void CSessionControl::UnloadAFEngine()
  641. {
  642.     if(m_pFramework)
  643.         m_pFramework->Log("Unloading AFEngine...");
  644.     if(!m_bAFEngineInit){
  645.         if(m_pFramework)
  646.             m_pFramework->Log("AFEngine is not even loaded!!!");
  647.         return;
  648.     }
  649.  
  650.     if (m_pAFEngine.get())
  651.     {
  652. #if (AF_DLL_VERSION > 9600000)
  653.         m_pAFEngine->CloseServerStore(m_iAFEServerStoreID);
  654. #endif
  655.         m_pAFEngine->Release();
  656.     }
  657.  
  658.     m_bAFEngineInit = false;
  659. }
  660.  
  661. #ifdef NO_SIP
  662. STDMETHODIMP CSessionControl::GetAFEngine(void **pAFEngine)
  663. {
  664.     *pAFEngine = (void *)m_pAFEngine.get();
  665.     return S_OK;
  666. }
  667.  
  668. STDMETHODIMP CSessionControl::OpenSession(int iLine, char chAudioPayload, char chVideoPayload, int iAudioRTPChannel, int iAudioRTCPChannel, int iVideoRTPChannel, int iVideoRTCPChannel, bool bCaller)
  669. {
  670.     CallDialog *pDlg = m_pCallLine->GetDialog(iLine);
  671.     if(!pDlg){
  672.         return ThrowError("No dialog found with this line");
  673.     }
  674.    
  675.     SipAccount* sipAccnt = GetSelectedSipAccount();
  676.    
  677.     RET_ERROR_STR(sipAccnt);
  678.     CallDialog &dlg = *pDlg;
  679.    
  680.     dlg.m_iCallStartTime = (int)PAL::getCurrentTimeInMilliSeconds();
  681.     dlg.m_bConf = false;
  682.     dlg.m_iAcct = sipAccnt->m_pAgent->m_iAccnt;
  683.     //only caller can send reinvite.
  684.     dlg.m_bReInvite = true;
  685.    
  686.     m_pCallLine->SetSelectedLine(iLine);
  687.    
  688.     dlg.m_bEnableIceSupport = sipAccnt->m_pAgent->m_bEnableIceSupport;
  689.     dlg.m_bIsSdpInInvite = sipAccnt->m_pAgent->m_bInviteSDP;
  690.     dlg.m_bPhoneCall = false;
  691.    
  692.     if(dlg.m_bPhoneCall)
  693.     {
  694.         dlg.m_bEnableIceSupport = sipAccnt->m_pAgent->m_GatewayPreferences.bEnableICE;
  695.         dlg.m_bIsSdpInInvite = !sipAccnt->m_pAgent->m_GatewayPreferences.bEnableNoSDPINVITE;
  696.     }
  697.    
  698.     dlg.m_bAnonymousCall = false;
  699.     dlg.m_sFromPhoneNumber = sipAccnt->m_pAgent->m_sFromPhoneNumber;
  700.     dlg.m_sMyURI = sipAccnt->m_pAgent->GetUsername() + "@" + sipAccnt->m_pAgent->GetDomainName();
  701.    
  702.     dlg.m_pAgent = sipAccnt->m_pAgent;
  703.     dlg.m_iLine = iLine;
  704.     m_pCallLine->SetPendingLineStatus(dlg);
  705.    
  706.     /////////////////////////////////////////////////////////
  707.     dlg.m_chAudioPayload = chAudioPayload;
  708.     dlg.m_chVideoPayload = chVideoPayload;
  709.     if (dlg.m_chAudioPayload != INVALID_PAYLOAD_TYPE)
  710.     {
  711.         dlg.m_iAudioRTPChannel   = iAudioRTPChannel;
  712.         dlg.m_iAudioRTCPChannel   = iAudioRTCPChannel;
  713.     }
  714.    
  715.     if (dlg.m_chVideoPayload != INVALID_PAYLOAD_TYPE)
  716.     {
  717.         dlg.m_iVideoRTPChannel = iVideoRTPChannel;
  718.         dlg.m_iVideoRTCPChannel = iVideoRTCPChannel;
  719.     }
  720.    
  721. //  dlg.m_iSession = iSession;
  722.     ///////////////////////////////////////
  723.    
  724.     dlg.m_sDisplayName = MediaSessionUtil::GetUserNameFromURI(sipAccnt->m_pAgent->GetUsername());
  725.     dlg.m_iRefferedLine = -1;
  726.    
  727.     dlg.m_sTargetURI = "[email protected]";//dlg.m_sMyURI;
  728.    
  729.     dlg.m_bSrtpCall = sipAccnt->m_pAgent->m_bSrtpCall;
  730.    
  731.     if(dlg.m_bSrtpCall)
  732.     {
  733.         m_pFramework->m_mediaFramework->put_EnableSrtp(TRUE);
  734.     }
  735.     else
  736.     {
  737.         m_pFramework->m_mediaFramework->put_EnableSrtp(FALSE);
  738.     }
  739.    
  740.     dlg.m_bCaller = bCaller;
  741.     dlg.m_callState = CALL_CALLING;
  742.     dlg.m_sTargetID = m_pCallLine->MakeUniqueTargetID(dlg.m_sTargetURI);
  743.     dlg.m_iProxy = sipAccnt->m_pAgent->GetSelectedProxy();
  744.     dlg.m_sProxyAuthentication = sipAccnt->m_pAgent->GetProxyAuthentication();
  745.    
  746. #ifndef _WIN32_WCE
  747.     time_t t;
  748.     time(&t);
  749.     dlg.m_iCallingTime = (long)t;
  750. #else
  751.     GetLocalTime(&dlg.m_stCallingTime);
  752. #endif
  753.     //m_pCallLine->AddDialog(iLine, dlg);
  754.    
  755.     m_pFramework->OpenSession(dlg);
  756.  
  757.     return S_OK;
  758. }
  759.  
  760. STDMETHODIMP CSessionControl::CloseSession(int iLine, char chAudioPayload, char chVideoPayload)
  761. {
  762.     CallDialog *pDlg = m_pCallLine->GetDialog(iLine);
  763.     if(!pDlg){
  764.         return ThrowError("No dialog found with this line");
  765.     }
  766.    
  767.     SipAccount* sipAccnt = GetSelectedSipAccount();
  768.    
  769.     RET_ERROR_STR(sipAccnt);
  770.     CallDialog &dlg = *pDlg;
  771.     dlg.m_chAudioPayload = chAudioPayload;
  772.     dlg.m_chVideoPayload = chVideoPayload;
  773.     sipAccnt->m_pAgent->CloseSession(dlg);
  774.    
  775.     return S_OK;
  776. }
  777.  
  778. STDMETHODIMP CSessionControl::ReleaseLine(int iLine)
  779. {
  780.     m_pCallLine->RemoveLine(iLine);
  781.     return S_OK;
  782. }
  783. #endif
  784.  
  785. LRESULT CSessionControl::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  786. {  
  787.     SipAccount* sipAccnt = GetSelectedSipAccount();
  788.    
  789.     RET_ERROR_STR(sipAccnt);
  790.    
  791. #ifdef CUSTOM_POST_MESSAGE
  792.     m_hWndControl = this;
  793. #else
  794.     m_hWndControl = m_hWnd;
  795. #endif
  796.  
  797.     sipAccnt->m_pAgent->SetAppWindow(m_hWndControl);
  798. #ifndef NO_DATA_TRAVELER
  799.     m_pDataTraveler->SetAppWindow(m_hWndControl);
  800. #endif
  801.     if (m_pFramework->m_mediaFramework)
  802.     {
  803.         m_pFramework->SetAppWindow(m_hWndControl);
  804.         m_pFramework->m_mediaFramework->SetVideoSizeNotify(m_hWndControl, WM_VIDEO_WINDOW_SIZE);
  805.     }
  806.  
  807.     sipAccnt->m_iTransactionTimer = SetTimer(TRANSACTION_TIMER_ID + GetAccountID(sipAccnt) , TRANSACTION_TIMER_INTERVAL);
  808.    
  809.     sipAccnt->m_iDataChannelKeepAliveTimer = SetTimer(
  810.         DATA_CHANNEL_KEEP_ALIVE_TIMER_ID + GetAccountID(sipAccnt),
  811.         DATA_CHANNEL_KEEP_ALIVE_PERIOD * 1000);
  812.  
  813.     return 0;
  814. }
  815.  
  816. LRESULT CSessionControl::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  817. {
  818.     //moved this here from FinalRelease because suspendMonitorThread
  819.     //needs the sipAccountID to callshutdown/logout
  820.     //This code might be duplicate of the code below it.
  821. #ifdef _WIN32_WCE
  822.         if (m_hPowerMsgQueue) {
  823.             StopPowerNotifications(m_hPowerNotifications);
  824.  
  825.             SetEvent(m_hQuitSuspendMonitorThread);
  826.             m_pSuspendMonitorThread->join();
  827.  
  828.             CloseMsgQueue(m_hPowerMsgQueue);
  829.             m_hPowerMsgQueue = NULL;
  830.         }
  831. #endif
  832.     int selectedAccount = -1;
  833.     SipAccountMap::iterator iter = m_sipAccountMap.begin();
  834.     for (; iter != m_sipAccountMap.end(); ++iter)
  835.     {
  836.         m_iSelectedAccount = iter->first; //for EndCall, LogOut, ShutDown
  837.         selectedAccount = m_iSelectedAccount; //save selected account
  838.        
  839.         //set the m_pAgent pointer to the pAgent pointer of the
  840.         //currently active account.
  841.         m_pFramework->Init(m_iSelectedAccount);
  842.         m_pCallHistory->Init(m_iSelectedAccount);
  843.         m_pCallLine->Init(m_iSelectedAccount);
  844. #ifndef NO_DATA_TRAVELER
  845.         m_pDataTraveler->SetSipAccountId(m_iSelectedAccount);
  846. #endif
  847.         Logout();
  848.  
  849.         m_iSelectedAccount = selectedAccount;
  850.  
  851.         Shutdown();
  852.     }
  853.  
  854.     return 0;
  855. }
  856.  
  857. #if defined(__unix__) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  858. LRESULT CSessionControl::MessageHandlers(UINT uMsg, WPARAM wParam, LPARAM lParam)
  859. {
  860.     MESSAGE_HANDLER(WM_FIRE_EVENT, OnFireEvent)
  861.     MESSAGE_HANDLER(WM_KILL_TRANSACTION, OnKillTransaction)
  862.     MESSAGE_HANDLER(WM_VIDEO_WINDOW_SIZE, OnVideoWindowSize)
  863.     MESSAGE_HANDLER(WM_AUDIO, OnAudioEvent)
  864.     MESSAGE_HANDLER(WM_FUNCTION_CALL, OnFunctionCall)
  865.     MESSAGE_HANDLER(WM_TIMER, OnTimer)
  866.  
  867.     // Reaching here means no matching handler found.
  868.     return -1;
  869. }
  870. #endif
  871.  
  872. void CSessionControl::ShutDownAllAccounts()
  873. {
  874.     SipAccountMap::iterator iter = m_sipAccountMap.begin();
  875.     for (; iter != m_sipAccountMap.end(); ++iter)
  876.     {
  877.         //delete SIPAccount object, pAgent, and stop threads.
  878.         ReleaseAccount(iter->second);
  879.     }
  880.  
  881. }
  882. /*sipAccnt specific.*/
  883. LRESULT CSessionControl::OnKillTransaction(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  884. {
  885.     int accnt = *((int*) lParam);
  886.     SipAccount* sipAccnt = GetSipAccount(accnt);
  887.  
  888.     RET_ERROR_STR(sipAccnt);
  889.  
  890.     sipAccnt->m_pAgent->KillTransaction(wParam);
  891.     bHandled = TRUE;
  892.  
  893.     return 0;
  894. }
  895.  
  896. LRESULT CSessionControl::OnDrawVideo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  897. {
  898. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  899.     if (!m_pFramework->m_mediaFramework)
  900.         return E_FAIL;
  901.  
  902.     ATL_DRAWINFO& di = *(ATL_DRAWINFO*)lParam;
  903.     HWND hWnd = HWND(wParam);
  904.     return m_pFramework->m_mediaFramework->DrawVideo(hWnd, lParam);
  905. #else
  906.     return 0;
  907. #endif
  908. }
  909.  
  910. LRESULT CSessionControl::OnVideoWindowSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  911. {
  912.     HWND hWnd = (HWND)wParam;
  913.     int iWidth = LOWORD(lParam);
  914.     int iHeight = HIWORD(lParam);
  915.  
  916.     m_pFramework->Log("OnVideoWindowSize " + tostring(uMsg) + " " + tostring(iWidth) + " x " + tostring(iHeight));
  917.  
  918. #ifdef USE_VARIANT_IN_EVENT
  919.     GeneralSafeArray aMsg(3);
  920.     aMsg.PutNumber(0, (long)hWnd);
  921.     aMsg.PutNumber(1, iWidth);
  922.     aMsg.PutNumber(2, iHeight);
  923.  
  924.     FIRE_EVENT(OnVideoSizeChange, aMsg.GetVariantRef());
  925. #else
  926.     FIRE_EVENT(OnVideoSizeChange, (long)hWnd, iWidth, iHeight);
  927. #endif
  928.     return 0;
  929. }
  930.  
  931. LRESULT CSessionControl::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  932. {
  933.     int accnt = (int)(wParam - 1) % MAXIMUM_SIP_ACCOUNT; //get account id.
  934.     SipAccount* sipAccnt = GetSipAccount(accnt);
  935.  
  936.     RET_ERROR_STR(sipAccnt);
  937.  
  938.     if (wParam == sipAccnt->m_iRegistrationRefreshTimer)
  939.     {
  940.         if (sipAccnt->m_pAgent->RefreshRegistration())
  941.             SetRegistrationResponseTimer(accnt);
  942.     }
  943.     else if (wParam == sipAccnt->m_iSignalChannelKeepAliveTimer)
  944.     {
  945.         if (NULL != sipAccnt->m_pAgent->m_pConnectToSIPServerhread.get())
  946.             return 0;
  947.  
  948.         if (sipAccnt->m_iSentKeepAliveCount >= MAX_SENT_KEEP_ALIVE_COUNT)
  949.         {
  950.             PAL_DB("No response for keep-alive.");
  951.             m_pFramework->Log("No response for keep-alive.");
  952.             sipAccnt->m_iSentKeepAliveCount = 0;
  953.             HandleTimeoutOrError(accnt);           
  954.         }
  955.  
  956.         if (sipAccnt->m_bEnableBindingResponseFailover &&
  957.             sipAccnt->m_iSignalChannelKeepAlivePeriod &&
  958.             sipAccnt->m_pAgent->KeepSignalSocketAlive() )
  959.         {
  960.             sipAccnt->m_iSentKeepAliveCount++;
  961.             PAL_DB2("Sending keep-alive request: ", sipAccnt->m_iSentKeepAliveCount);
  962.         }
  963.         else
  964.         {
  965.             sipAccnt->m_iSentKeepAliveCount = 0;
  966.         }
  967.     }
  968.     else if (wParam == sipAccnt->m_iDataChannelKeepAliveTimer)
  969.     {
  970.         if (NULL == sipAccnt->m_pAgent->m_pConnectToSIPServerhread.get())
  971.             sipAccnt->m_pAgent->KeepDataSocketAlive();
  972.     }
  973.     else if (wParam == sipAccnt->m_iTransactionTimer)
  974.     {
  975.         sipAccnt->m_pAgent->HandleTransactionTimer();
  976.     }
  977.     else if (wParam == sipAccnt->m_iRegistrationResponseTimer)
  978.     {
  979.         if (sipAccnt->m_pAgent->IsDelayingRegistration())
  980.         {
  981.             PAL_DB("Resetting registration timeout...");
  982.             // reset the time-out
  983.             SetRegistrationResponseTimer(accnt);
  984.  
  985.         }
  986.         else
  987.         {/*sipAccnt->m_pAgent->*/
  988.             if (sipAccnt->m_pAgent->HasNextProxyServerIndex()){
  989.                  RegisterFailOver(sipAccnt);
  990.             }else{
  991.                 HandleTimeoutOrError(accnt);
  992.                 PAL_DB("No response for registration.");
  993.                 m_pFramework->Log("No response for registration.");                
  994.             }
  995.         }
  996.     }
  997.     else if (wParam == sipAccnt->m_iInviteResponseTimer)
  998.     {
  999.         PAL_DB("No response for invite.");
  1000.         // Note: no response from other client - no need to panic...
  1001.         KILL_TIMER(sipAccnt->m_iInviteResponseTimer);
  1002.     }
  1003.     else if (wParam == sipAccnt->m_iLogoutResponseTimer)
  1004.     {
  1005.         HandleLogoutTimeoutOrError(accnt);
  1006.     }
  1007. #ifdef _SUPPORT_EVENT_PACKAGE
  1008.     else if(wParam == sipAccnt->m_iMWIRefreshTimer)
  1009.     {
  1010.         //call MWIRefreshTimer.
  1011.         sipAccnt->m_pAgent->RefreshSubscription();
  1012.     }
  1013. #endif
  1014.     else if(wParam == m_iUpdateConferenceListTimer)
  1015.     {
  1016.         KillTimer(wParam);
  1017.         m_pCallLine->NotifyConfList();
  1018.     }
  1019.     else
  1020.     {
  1021.         PAL_DB_ASSERT(0 && "Invalid SipComm timer.");
  1022.         KillTimer(wParam);
  1023.     }
  1024.     return 0;
  1025. }
  1026.  
  1027. #ifdef __unix__
  1028. void CSessionControl::OnWriteLog(int log_type, const std::string &str_log)
  1029. {
  1030.     if ( g_pSessionControl && g_pSessionControl->m_CallbackHandler )
  1031.     {
  1032.         g_pSessionControl->m_CallbackHandler->OnLog(log_type, str_log + "\r\n");
  1033.     }
  1034. }
  1035. #endif
  1036.  
  1037. LRESULT CSessionControl::OnFireEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1038. {
  1039.     StartProfileTimer("OnFireEvent");
  1040.  
  1041.     FireEventData* p = (FireEventData*)wParam;
  1042.  
  1043.     if (!p)
  1044.     {
  1045.         PAL_DB_ASSERT(0);
  1046.         return 0;
  1047.     }
  1048.  
  1049.     int accnt = p->m_iAccnt;
  1050.     SipAccount* sipAccnt = GetSipAccount(accnt);
  1051.  
  1052.     RET_ERROR_STR(sipAccnt);
  1053.  
  1054.    
  1055.     switch (p->m_iEventID)
  1056.     {
  1057.     case EVENT_REGISTER_RESPONSE:
  1058.         {
  1059.             if (p->m_iStatusCode == 401 || p->m_iStatusCode == 407)
  1060.             {
  1061.                 if (sipAccnt->m_pAgent->RegisterWithAuthorization(p->m_iProxy))
  1062.                     break;
  1063.             }
  1064.             if (p->m_iStatusCode == 423)
  1065.             {
  1066.                 if (sipAccnt->m_pAgent->RegisterWithNewExpire(p->m_iProxy))
  1067.                     break;
  1068.             }
  1069.             KILL_TIMER(sipAccnt->m_iRegistrationResponseTimer);
  1070.  
  1071.             bool bRegistered = sipAccnt->m_bRegistered;
  1072.             if (p->m_iResponse == RESPONSE_SUCCESS)
  1073.             {
  1074.                 sipAccnt->m_bRegistered = true;
  1075.                 SetRegistrationRefreshTimer(accnt);
  1076.                 SetSignalChannelKeepAliveTimer(accnt);
  1077.  
  1078. //#ifdef __unix__
  1079. #if 0
  1080.                 if(sipAccnt->m_pAgent->GetTransportMode() != UDP){
  1081. #if 0
  1082.                     int mib[4], ival;
  1083.                     mib[0] = CTL_NET;
  1084.                     mib[1] = AF_INET;
  1085.                     mib[2] = IPPROTO_TCP;
  1086.                     mib[3] = 19;    //TCPCTL_KEEPCNT;
  1087.                     ival = 1; /* Number of keepalive probe attempts (default is 8) */
  1088.                     sysctl(mib, 4, NULL, NULL, &ival, sizeof(ival));
  1089. #endif
  1090. #ifndef USE_NSSTREAM_FOR_SIP
  1091.                     struct timeval tval;
  1092.                     memset(&tval, 0, sizeof(tval));
  1093.                     tval.tv_sec = 30;
  1094.                     struct AfSocketOptionParams afsop;
  1095.                     afsop.iLevel = IPPROTO_TCP; //6;
  1096.                     afsop.iOptName = 4; //TCP_KEEPALIVE;
  1097.                     afsop.pOptVal = (void *)&tval;
  1098.                     afsop.iOptLen = sizeof(tval);
  1099.                     m_pAFEngine->SetChannelOption(sipAccnt->m_pAgent->m_iSipChannel, EAfOptionSocket, (intptr_t)&afsop);
  1100. #endif
  1101.                 }
  1102. #endif
  1103.  
  1104. #if 0
  1105.                 // added by MC -- request immediate keep-alive
  1106. #ifndef __unix__
  1107. #ifndef WCE_PLATFORM_STANDARDSDK_500
  1108.                 PostMessage(WM_TIMER, sipAccnt->m_iSignalChannelKeepAliveTimer, 0);
  1109. #else
  1110.                 SendWindowsMessage(WM_TIMER, sipAccnt->m_iSignalChannelKeepAliveTimer, 0);
  1111. #endif
  1112. #else
  1113.                 SetTimer(sipAccnt->m_iSignalChannelKeepAliveTimer, 0);
  1114. #endif
  1115. #endif
  1116.                 if (!sipAccnt->m_sCallUri.empty())
  1117.                 {
  1118.                     // invite failover
  1119.                     Call(ToInternalBstr(sipAccnt->m_sCallUri), ToInternalBstr(""), VARIANT_FALSE, VARIANT_FALSE);
  1120.                 }
  1121.                 else if (bRegistered)
  1122.                 {
  1123.                     // registered again, need to send target refresh request
  1124.                     sipAccnt->m_pAgent->HandleRegistrationFailover();
  1125.                 }
  1126.                
  1127.             }
  1128.             //if(p->m_iStatusCode == 401)
  1129.             else
  1130.             {
  1131.                 sipAccnt->m_pAgent->CloseConnection();
  1132.             }
  1133.             if (!bRegistered)
  1134.             {
  1135. #ifdef USE_VARIANT_IN_EVENT
  1136.                 GeneralSafeArray aMsg(5);
  1137.                 aMsg.PutNumber(0, p->m_iResponse);
  1138.                 aMsg.PutNumber(1, p->m_iStatusCode);
  1139.                 aMsg.PutString(2, p->m_sReason);
  1140.                 aMsg.PutNumber(3, p->m_iProxy);
  1141.                 aMsg.PutNumber(4, p->m_iAccnt);
  1142.  
  1143.                 FIRE_EVENT(OnRegisterResponse, aMsg.GetVariantRef());              
  1144. #else
  1145.                
  1146.                 FIRE_EVENT(OnRegisterResponse, p->m_iResponse,
  1147.                                         p->m_iStatusCode,
  1148.                                         ToBstr(p->m_sReason),
  1149.                                         p->m_iProxy,
  1150.                                         p->m_iAccnt);
  1151. #endif
  1152.  
  1153.                 //test();
  1154.             }
  1155.             else
  1156.             {
  1157.                 // this is response to failover
  1158.             }
  1159.         }
  1160.         break;
  1161.  
  1162.     case EVENT_CALL_RESPONSE:
  1163.         {
  1164.         MSA_LOG("recieved response for account: " + itoa(accnt));
  1165.            
  1166.         KILL_TIMER(sipAccnt->m_iInviteResponseTimer);
  1167.         sipAccnt->m_sCallUri = "";
  1168.  
  1169.         string sTargetURI = p->m_sTargetURI;
  1170.         string sUsername = MediaSessionUtil::GetUserNameFromURI(sTargetURI);
  1171.         string sDomain = MediaSessionUtil::GetDomainNameFromURI(sTargetURI);
  1172.         char *tmp = __osip_uri_escape_userinfo (sUsername.c_str());
  1173.         sUsername = tmp;
  1174.         osip_free (tmp);
  1175.         if(!sDomain.empty())
  1176.             sUsername += "@" + sDomain;
  1177.  
  1178. #ifdef USE_VARIANT_IN_EVENT
  1179.         GeneralSafeArray aMsg(10);
  1180.         aMsg.PutNumber(0, p->m_iLine);
  1181.         aMsg.PutNumber(1, p->m_iResponse);
  1182.         aMsg.PutNumber(2, p->m_iStatusCode);
  1183.         aMsg.PutString(3, p->m_sReason);
  1184.         aMsg.PutString(4, p->m_sDisplayName);
  1185.         aMsg.PutString(5, sUsername);
  1186.         aMsg.PutNumber(6, p->m_bVideoCall);
  1187.         aMsg.PutNumber(7, p->m_iAccnt);
  1188.         aMsg.PutNumber(8, p->m_bEarlyMedia);
  1189.        
  1190.         if (p->m_iStatusCode == 200)
  1191.         {
  1192.             CallDialog * pCallDialog = m_pCallLine->GetDialog(p->m_iLine);
  1193.             if (pCallDialog)
  1194.             {
  1195.            
  1196.                 if (m_pAFEngine->GetSessionProperty(pCallDialog->m_iSession, EAfSessionNonICEPeer))
  1197.                     aMsg.PutNumber(9, 0); // Peer is Non-ICE
  1198.                 else
  1199.                     aMsg.PutNumber(9, 1); // Peer is ICE agent
  1200.             }
  1201.             else
  1202.             {
  1203.                 aMsg.PutNumber(9, -1); // Unknown
  1204.             }
  1205.         }else
  1206.         {
  1207.                 aMsg.PutNumber(9, -1); // Unknown
  1208.         }
  1209.        
  1210.         FIRE_EVENT(OnCallResponse, aMsg.GetVariantRef());
  1211. #else
  1212.         FIRE_EVENT(OnCallResponse, p->m_iLine,
  1213.                             p->m_iResponse,
  1214.                             p->m_iStatusCode,
  1215.                             ToBstr(p->m_sReason),
  1216.                             ToBstr(p->m_sDisplayName),
  1217.                             ToBstr(sUsername),
  1218.                             ToVB(p->m_bVideoCall),
  1219.                             p->m_iAccnt,
  1220.                             p->m_bEarlyMedia);
  1221. #endif
  1222.  
  1223. #ifdef _SUPPORT_EVENT_PACKAGE
  1224.        
  1225.         if(p->m_iRefferedLine != -1)
  1226.         {
  1227.             PAL_DB("Reffered line existes.");
  1228.             string sBody ="SIP/2.0 ";
  1229.             sBody += itoa(p->m_iStatusCode);
  1230.             sBody +=" ";
  1231.             sBody += p->m_sReason;
  1232.  
  1233.             string sState;
  1234.             if(p->m_iStatusCode < 200) // 1XX response
  1235.                 sState = "active";
  1236.             else
  1237.                 sState = "terminated";
  1238.            
  1239.             int iRet = sipAccnt->m_pAgent->Notify(p->m_iRefferedLine,sBody,sState);
  1240.             if(iRet == -1)
  1241.             {
  1242.                 PAL_DB("Notify sending err.");
  1243.             }
  1244.             else
  1245.             {
  1246.                 PAL_DB("Notify sending success.");
  1247.             }
  1248.        
  1249.         }
  1250.         else
  1251.         {
  1252.             PAL_DB("Referred line doesn't exist.");
  1253.         }
  1254.  
  1255. #endif
  1256.  
  1257.         }
  1258.         break;
  1259.  
  1260.     case EVENT_CALL_AUTHENTICATION:
  1261.         sipAccnt->m_pAgent->CallWithAuthorization(p->m_iLine);
  1262.         break;
  1263.  
  1264.     case EVENT_MAKE_REINVITE:
  1265.         sipAccnt->m_pAgent->SendUpdateReinvite(p->m_iLine);
  1266.         break;
  1267.  
  1268.     case EVENT_MAKE_RELAY_REINVITE:
  1269.         sipAccnt->m_pAgent->SendReinviteRelay(p->m_iLine);
  1270.         break;
  1271.  
  1272.     case EVENT_ICE_CHECK_COMPLETED:
  1273.         sipAccnt->m_pAgent->OpenSessionOnICECompleted(p->m_iLine);
  1274.         break;
  1275.  
  1276.     case EVENT_MOVE_TO_CONFERENCE:
  1277.         {
  1278. #ifdef USE_VARIANT_IN_EVENT
  1279.             GeneralSafeArray aMsg(3);
  1280.             aMsg.PutNumber(0, p->m_iLine);
  1281.             aMsg.PutNumber(1, p->m_iAccnt);
  1282.             aMsg.PutBool(2, p->m_bVideoCall);
  1283.  
  1284.             FIRE_EVENT(OnMoveToConference, aMsg.GetVariantRef());
  1285. #else
  1286.             FIRE_EVENT(OnMoveToConference, p->m_iLine,
  1287.                                     p->m_iAccnt,
  1288.                                     ToVB(p->m_bVideoCall));
  1289. #endif
  1290.         }
  1291.         break;
  1292.  
  1293.     case EVENT_UPDATE_CONFERENCE_LIST:
  1294.         {
  1295. #ifdef USE_VARIANT_IN_EVENT
  1296.             GeneralSafeArray aMsg(2);
  1297.             aMsg.PutNumber(0, p->m_iLine);
  1298.             aMsg.PutNumber(1, p->m_iAccnt);  
  1299.  
  1300.             FIRE_EVENT(OnConferenceMemberListUpdate, aMsg.GetVariantRef());
  1301. #else
  1302.             FIRE_EVENT(OnConferenceMemberListUpdate, p->m_iLine, p->m_iAccnt);
  1303. #endif
  1304.         }
  1305.         break;
  1306.        
  1307.  
  1308.     case EVENT_CALL_REQUEST:
  1309.         {
  1310.             //added to decide wheather the replace call will proceed or not.
  1311.  
  1312.             if (m_pCallLine->NumberOfSecureLines() > 1)
  1313.             {
  1314.                 sipAccnt->m_pAgent->AutoRejectCall(p->m_iLine, true);
  1315.                 break;
  1316.             }
  1317.  
  1318.             if (p->m_bSent)
  1319.             {
  1320.                 sipAccnt->m_pAgent->AutoRejectCall(p->m_iLine, false, true);
  1321.                 break;
  1322.             }
  1323.  
  1324.             if ((p->m_iLine < 0) || (m_pCallLine->GetUserMode() != MODE_AVAILABLE))
  1325.             {
  1326.                 sipAccnt->m_pAgent->AutoRejectCall(p->m_iLine, false);//it will return immediately.
  1327.                 break;
  1328.             }
  1329.  
  1330. #ifdef USE_VARIANT_IN_EVENT
  1331.             GeneralSafeArray aMsg(7);
  1332.             aMsg.PutNumber(0, p->m_iLine);
  1333.             aMsg.PutString(1, p->m_sDisplayName);
  1334.             aMsg.PutString(2, p->m_sTargetURI);
  1335.             aMsg.PutNumber(3, p->m_bVideoCall);
  1336.             aMsg.PutNumber(4, p->m_iSpitRating);
  1337.             aMsg.PutNumber(5, p->m_iAccnt);
  1338.             aMsg.PutString(6, p->m_sReason);
  1339.  
  1340.             FIRE_EVENT(OnCallRequest, aMsg.GetVariantRef());
  1341. #else
  1342.             FIRE_EVENT(OnCallRequest, p->m_iLine,
  1343.                            ToBstr(p->m_sDisplayName),
  1344.                            ToBstr(p->m_sTargetURI),
  1345.                            ToVB(p->m_bVideoCall),
  1346.                            p->m_iSpitRating,
  1347.                            p->m_iAccnt,
  1348.                            ToBstr(p->m_sReason));
  1349. #endif
  1350.         }
  1351.         break;
  1352.  
  1353.     case EVENT_END_CALL:
  1354.        
  1355.         //for supporting call transfer. If call transfer is active, then don't
  1356.         //fire EVENT_END_CALL event to the app.
  1357.         MSA_LOG("Ending call for account: " + itoa(p->m_iAccnt) + " line: " + itoa(p->m_iLine));
  1358.  
  1359.         if(p->m_bSent)//isCallTransfer active
  1360.         {
  1361.             PAL_DB("in EVENT_END_CALL: CallTransfer is enabled. ");
  1362.             if (!CheckCallURI(p->m_sProxyName, sipAccnt))//sCallURI
  1363.             {
  1364. #ifdef _SUPPORT_EVENT_PACKAGE
  1365.                     string sBody ="SIP/2.0 503 Service Unavailable";
  1366.                     sipAccnt->m_pAgent->Notify(p->m_iRefferedLine,sBody,"terminated");
  1367. #endif
  1368.                
  1369. //fire end call event.
  1370. #ifdef USE_VARIANT_IN_EVENT
  1371.                     GeneralSafeArray aMsg(4);
  1372.                     aMsg.PutNumber(0, p->m_iLine);
  1373.                     aMsg.PutString(1, p->m_sDisplayName);
  1374.                     aMsg.PutString(2, p->m_sTargetURI);
  1375.                     aMsg.PutNumber(3, p->m_iAccnt);
  1376.  
  1377.                     FIRE_EVENT(OnEndCall, aMsg.GetVariantRef());
  1378. #else
  1379.                     FIRE_EVENT(OnEndCall, p->m_iLine,
  1380.                                    ToBstr(p->m_sDisplayName),
  1381.                                    ToBstr(p->m_sTargetURI),
  1382.                                    p->m_iAccnt);
  1383. #endif
  1384.             }
  1385.             else
  1386.             {
  1387.                 // attempt to re-use the previously selected line
  1388.                 m_pCallLine->GrabOutboundLine(p->m_iLine);
  1389.  
  1390.                 int iLine = m_pCallLine->GrabOutboundLine();
  1391.                 if (iLine >= 0)
  1392.                 {
  1393.                     sipAccnt->m_pAgent->Call(p->m_sProxyName,iLine,p->m_iRefferedLine);
  1394.                 }
  1395.             }
  1396.         }
  1397.         else
  1398.         {
  1399.             PAL_DB("in EVENT_END_CALL: CallTransfer is disabled. ");
  1400.            
  1401. #ifdef USE_VARIANT_IN_EVENT
  1402.             GeneralSafeArray aMsg(4);
  1403.             aMsg.PutNumber(0, p->m_iLine);
  1404.             aMsg.PutString(1, p->m_sDisplayName);
  1405.             aMsg.PutString(2, p->m_sTargetURI);
  1406.             aMsg.PutNumber(3, p->m_iAccnt);
  1407.  
  1408.             FIRE_EVENT(OnEndCall, aMsg.GetVariantRef());
  1409. #else
  1410.             FIRE_EVENT(OnEndCall, p->m_iLine,
  1411.                            ToBstr(p->m_sDisplayName),
  1412.                            ToBstr(p->m_sTargetURI),
  1413.                            p->m_iAccnt);
  1414. #endif
  1415.         }
  1416.        
  1417.         break;
  1418.  
  1419.     case EVENT_CALL_REDIRECT:
  1420.         // this is final response
  1421.         sipAccnt->m_sCallUri = "";
  1422.         KILL_TIMER(sipAccnt->m_iInviteResponseTimer);
  1423.  
  1424.         // attempt to re-use the previously selected line
  1425.         m_pCallLine->GrabOutboundLine(p->m_iLine);
  1426.         CSessionControl::Call(ToInternalBstr(p->m_sTargetURI), ToInternalBstr(""),  ToBOOL(p->m_bAudioCall), ToBOOL(sipAccnt->m_bAnonymous) );
  1427.         break;
  1428.  
  1429.     case EVENT_REINVITE:
  1430.         sipAccnt->m_pAgent->HandleReinviteRequest(p->m_iLine, p->m_iProxy, (osip_transaction_t*)p->m_pData);
  1431.         break;
  1432.  
  1433.     case EVENT_REINVITE_REQUEST:
  1434.         {
  1435. #ifdef USE_VARIANT_IN_EVENT
  1436.         GeneralSafeArray aMsg(6);
  1437.         aMsg.PutNumber(0, p->m_iLine);
  1438.         aMsg.PutString(1, p->m_sTargetURI);
  1439.         aMsg.PutString(2, p->m_sDisplayName);
  1440.         aMsg.PutNumber(3, p->m_bAudioCall);
  1441.         aMsg.PutNumber(4, p->m_bVideoCall);
  1442.         aMsg.PutNumber(5, p->m_iAccnt);
  1443.  
  1444.         FIRE_EVENT(OnReinviteRequest, aMsg.GetVariantRef());
  1445. #else
  1446.         FIRE_EVENT(OnReinviteRequest, p->m_iLine,
  1447.                                ToBstr(p->m_sTargetURI),
  1448.                                ToBstr(p->m_sDisplayName),
  1449.                                ToVB(p->m_bAudioCall),
  1450.                                ToVB(p->m_bVideoCall),
  1451.                                p->m_iAccnt);
  1452. #endif
  1453.         }
  1454.         break;
  1455.  
  1456.     case EVENT_REINVITE_RESPONSE:
  1457.         {
  1458.        
  1459. #ifdef USE_VARIANT_IN_EVENT
  1460.         GeneralSafeArray aMsg(6);
  1461.         aMsg.PutNumber(0, p->m_iLine);
  1462.         aMsg.PutString(1, p->m_sTargetURI);
  1463.         aMsg.PutString(2, p->m_sDisplayName);
  1464.         aMsg.PutNumber(3, p->m_bAudioCall);
  1465.         aMsg.PutNumber(4, p->m_bVideoCall);
  1466.         aMsg.PutNumber(5, p->m_iAccnt);
  1467.  
  1468.         FIRE_EVENT(OnReinviteResponse, aMsg.GetVariantRef());
  1469. #else
  1470.         FIRE_EVENT(OnReinviteResponse, p->m_iLine,
  1471.                                 ToBstr(p->m_sTargetURI),
  1472.                                 ToBstr(p->m_sDisplayName),
  1473.                                 ToVB(p->m_bAudioCall),
  1474.                                 ToVB(p->m_bVideoCall),
  1475.                                 p->m_iAccnt);
  1476. #endif
  1477.         }
  1478.         break;
  1479.  
  1480.     case EVENT_SIP_MESSAGE:
  1481.         {
  1482.         if (!p->m_bSent)
  1483.         {
  1484.             sipAccnt->m_pAgent->SetSelectedProxy(p->m_iProxy);
  1485.             sipAccnt->m_pAgent->HandleOsipEvent((osip_event_t*)p->m_pData);
  1486.         }
  1487. #ifdef USE_VARIANT_IN_EVENT
  1488.         GeneralSafeArray aMsg(4);
  1489.         aMsg.PutNumber(0, p->m_bSent);
  1490.         aMsg.PutString(1, p->m_sProxyName);
  1491.         aMsg.PutString(2, p->m_sSipMessage);
  1492.         aMsg.PutNumber(3, p->m_iAccnt);
  1493.  
  1494.         FIRE_EVENT(OnSipMessage, aMsg.GetVariantRef());
  1495. #else
  1496.         FIRE_EVENT(OnSipMessage, ToVB(p->m_bSent),
  1497.                           ToBstr(p->m_sProxyName),
  1498.                           ToBstr(p->m_sSipMessage),
  1499.                           p->m_iAccnt);
  1500. #endif
  1501.         }
  1502.         break;
  1503.  
  1504.     case EVENT_BYE_AUTHENTICATION:
  1505.         sipAccnt->m_pAgent->ByeWithAuthorization((osip_message_t*)p->m_pData);
  1506.         break;
  1507.  
  1508. #ifdef _SUPPORT_EVENT_PACKAGE
  1509.     case EVENT_REFER_AUTHENTICATION:
  1510.         sipAccnt->m_pAgent->ReferWithAuthorization(p->m_iLine, (osip_message_t*)p->m_pData);
  1511.         break;
  1512.  
  1513.     case EVENT_SUBSCRIBE_AUTHENTICATION:
  1514.         sipAccnt->m_pAgent->SubscribeWithAuthorization(p->m_iLine, (osip_message_t*)p->m_pData);
  1515.         break;
  1516. #endif
  1517.  
  1518.     case EVENT_TRANSPORT_ERROR:
  1519.         m_pFramework->Log("Transport error event");
  1520.         HandleTimeoutOrError(accnt, true);
  1521.         break;
  1522.  
  1523.     case EVENT_RECV_ERROR:
  1524.         {
  1525.             bool b = sipAccnt->m_pAgent->IsRecvErrorFromProxy(p->m_dwProxyAddr, p->m_wProxyPort);
  1526.             if (!b)
  1527.             {
  1528.                 // connection to proxy is still alive.
  1529.                 SAFE_DELETE(p);
  1530.                 return 0;
  1531.             }
  1532.             m_pFramework->Log("Receive error event");
  1533.             HandleTimeoutOrError(accnt);           
  1534.         }
  1535.         break;
  1536.  
  1537.     case EVENT_NAT_FAILURE:
  1538.         if (sipAccnt->m_pAgent->RefreshRegistration())
  1539.             SetRegistrationResponseTimer(accnt);
  1540.         break;
  1541.  
  1542.  
  1543.     case EVENT_RECEIVED_KEEP_ALIVE:
  1544.         sipAccnt->m_iSentKeepAliveCount = 0;
  1545.         break;
  1546.  
  1547.     case EVENT_LOGOUT_COMPLETE:
  1548.         {
  1549. #ifdef USE_VARIANT_IN_EVENT
  1550.             GeneralSafeArray aMsg(1);
  1551.             aMsg.PutNumber(0, accnt);
  1552.             FIRE_EVENT(OnLogoutComplete, aMsg.GetVariantRef());
  1553. #else
  1554.             FIRE_EVENT(OnLogoutComplete, accnt);
  1555. #endif
  1556.             if(sipAccnt->m_bAccountRemoved)
  1557.             {
  1558.                 m_iSelectedAccount = p->m_iAccnt;
  1559.                 Shutdown();
  1560.                
  1561.                 //delete dynamic memory allocated in SipAccount.
  1562.                 ReleaseAccount(sipAccnt);
  1563.                 m_sipAccountMap.erase(p->m_iAccnt);
  1564.                 SAFE_DELETE(sipAccnt);
  1565.                 m_iSelectedAccount = INVALID_ACCOUNT_ID;
  1566.                 MSA_LOG("Account: " + itoa(p->m_iAccnt) + " is now removed...");
  1567.             }
  1568.         }
  1569.         break;
  1570.  
  1571. #ifdef _SUPPORT_EVENT_PACKAGE
  1572.  
  1573.     case EVENT_SUBCRIBE_RESPONSE:
  1574.         {
  1575.             PAL_DB("EVENT_SUBCRIBE_RESPONSE: ");
  1576.  
  1577. #ifdef USE_VARIANT_IN_EVENT
  1578.             GeneralSafeArray aMsg(5);
  1579.             aMsg.PutNumber(0, p->m_iStatusCode); //response code
  1580.             aMsg.PutString(1, p->m_sReason); //reason string
  1581.             aMsg.PutNumber(2,p->m_iLine);//eventType
  1582.             aMsg.PutNumber(3,p->m_iAccnt);
  1583. #endif
  1584.            
  1585.             switch(p->m_iLine)//eventType
  1586.             {
  1587.             case EVENT_MWI:
  1588.                 {
  1589.                     if(p->m_iResponse > 0) // this field contains the expiry period of the sub. req.
  1590.                     {
  1591.                         SetMWIRefreshTimer(accnt);
  1592. #ifdef USE_VARIANT_IN_EVENT
  1593.                         aMsg.PutNumber(4,1);
  1594. #endif
  1595.                     }
  1596.                     else if(p->m_iResponse == 0)
  1597.                     {
  1598.                         PAL_DB("MWI Timer is killed");
  1599.                         KILL_TIMER(sipAccnt->m_iMWIRefreshTimer);
  1600. #ifdef USE_VARIANT_IN_EVENT
  1601.                         aMsg.PutNumber(4,0);
  1602. #endif
  1603.                     }
  1604.                     else
  1605.                     {
  1606. #ifdef USE_VARIANT_IN_EVENT
  1607.                         aMsg.PutNumber(4,-1);
  1608. #endif
  1609.                     }
  1610.                 }
  1611.                 break;
  1612.  
  1613.             case EVENT_REFER:
  1614.                 break;
  1615.  
  1616.             case EVENT_CONFERENCE:
  1617.                 break;
  1618.  
  1619.             case EVENT_CML:
  1620.                 break;
  1621.             }
  1622.             //it should not fire for refresh MWI subscription.
  1623.  
  1624. #ifdef USE_VARIANT_IN_EVENT
  1625.             FIRE_EVENT(OnSubscribeResponse, aMsg.GetVariantRef());
  1626. #else
  1627.             FIRE_EVENT(OnSubscribeResponse, p->m_iStatusCode,
  1628.                                      ToBstr(p->m_sReason),
  1629.                                      p->m_iLine,
  1630.                                      p->m_iAccnt);
  1631. #endif     
  1632.  
  1633.         }
  1634.         break;
  1635.     case EVENT_NOTIFY_REQUEST:
  1636.         {
  1637.                
  1638.             PAL_DB2("in EVENT_NOTIFY_REQUEST: ", p->m_sSipMessage.c_str());
  1639.             //now need to separate 3 notification events: MWI, REFER, CONFERENCE.
  1640.             switch(p->m_iLine) //eventType
  1641.             {
  1642.             case EVENT_MWI:
  1643.                 {
  1644. #ifdef USE_VARIANT_IN_EVENT
  1645.                     GeneralSafeArray aMsg(5);
  1646.                     aMsg.PutBool(0,p->m_bSent); //messages
  1647.                     aMsg.PutString(1, p->m_sDisplayName); // account
  1648.                     aMsg.PutString(2, p->m_sProxyName);  // message class
  1649.                     aMsg.PutString(3, p->m_sSipMessage); //new/old
  1650.                     aMsg.PutString(4, p->m_sTargetURI);  //urgent new/old
  1651.  
  1652.  
  1653.                     FIRE_EVENT(OnMessageWaitingIndication, aMsg.GetVariantRef());
  1654. #else
  1655.                     FIRE_EVENT(OnMessageWaitingIndication, ToVB(p->m_bSent),
  1656.                                ToBstr(p->m_sDisplayName),
  1657.                                ToBstr(p->m_sProxyName),
  1658.                                ToBstr(p->m_sSipMessage),
  1659.                                ToBstr(p->m_sTargetURI));
  1660. #endif
  1661.                 }
  1662.                 break;
  1663.             case EVENT_REFER:
  1664.                 {
  1665. #ifdef USE_VARIANT_IN_EVENT
  1666.                     GeneralSafeArray aMsg(3);
  1667.                     aMsg.PutString(0,p->m_sReason); //package name.
  1668.                     aMsg.PutString(1, p->m_sSipMessage); // message-body
  1669.                     aMsg.PutNumber(2, p->m_iAccnt);
  1670.  
  1671.                     FIRE_EVENT(OnRefer, aMsg.GetVariantRef());
  1672. #else
  1673.                     FIRE_EVENT(OnRefer, ToBstr(p->m_sReason),
  1674.                                  ToBstr(p->m_sSipMessage),
  1675.                                  p->m_iAccnt);
  1676. #endif
  1677.                 }
  1678.                 break;
  1679.             case EVENT_CONFERENCE:
  1680.                 {
  1681. #ifdef USE_VARIANT_IN_EVENT
  1682.                     GeneralSafeArray aMsg(3);
  1683.                     aMsg.PutString(0,p->m_sReason); //package name.
  1684.                     aMsg.PutString(1, p->m_sSipMessage); // message-body
  1685.                     aMsg.PutNumber(2, p->m_iAccnt);
  1686. #endif
  1687.                 }
  1688.                 break;
  1689.  
  1690.             case EVENT_CML:
  1691.                 {
  1692.                     PAL_DB("conference member list notify request...");
  1693.                 }
  1694.                 break;
  1695.             }
  1696.         }
  1697.         break;
  1698.  
  1699.     case EVENT_REFER_REQUEST:
  1700.         {
  1701.             PAL_DB("EVENT_REFER_REQUEST");
  1702.             //1st send sync notify. This may not be a requirement.
  1703.             string sBody = "SIP/2.0 100 Trying";
  1704.             sBody +="\n";
  1705.             sipAccnt->m_pAgent->Notify(p->m_iLine,sBody,"active");
  1706.  
  1707. #if 0 // for call transfer purpose.
  1708. #ifdef USE_VARIANT_IN_EVENT
  1709.             GeneralSafeArray aMsg(5);
  1710.             aMsg.PutNumber(0,p->m_iLine);
  1711.             aMsg.PutString(1,p->m_sDisplayName);//from header.
  1712.             aMsg.PutString(2,p->m_sTargetURI); // refer uri.
  1713.             aMsg.PutString(3, p->m_sReason);//method name.
  1714.             aMsg.PutNumber(4, p->m_iAccnt);
  1715.  
  1716.             FIRE_EVENT(OnReferRequest, aMsg.GetVariantRef());
  1717. #else
  1718.             FIRE_EVENT(OnReferRequest, p->m_iLine,
  1719.                                 ToBstr(p->m_sDisplayName),
  1720.                                 ToBstr(p->m_sTargetURI),
  1721.                                 ToBstr(p->m_sReason),
  1722.                                 p->m_iAccnt);
  1723. #endif
  1724. #endif 
  1725.         }
  1726.         break;
  1727.  
  1728.     case EVENT_OPTION_RESPONSE:
  1729.         {
  1730.             PAL_DB(" OPTION RESPONSE");
  1731. #ifdef USE_VARIANT_IN_EVENT
  1732.             GeneralSafeArray aMsg(6);
  1733.             aMsg.PutString(0,p->m_sDisplayName);//methods
  1734.             aMsg.PutString(1,p->m_sTargetURI); // content type
  1735.             aMsg.PutString(2, p->m_sProxyName);//codec
  1736.             aMsg.PutNumber(3,p->m_iStatusCode); // status code
  1737.             aMsg.PutString(4, p->m_sReason);//reason string
  1738.             aMsg.PutNumber(5, p->m_iAccnt);
  1739.  
  1740.             FIRE_EVENT(OnOptionResponse, aMsg.GetVariantRef());
  1741. #else
  1742.             FIRE_EVENT(OnOptionResponse, ToBstr(p->m_sDisplayName),
  1743.                                   ToBstr(p->m_sTargetURI),
  1744.                                   ToBstr(p->m_sProxyName),
  1745.                                   p->m_iStatusCode,
  1746.                                   ToBstr(p->m_sReason),
  1747.                                   p->m_iAccnt);
  1748. #endif
  1749.         }
  1750.         break;
  1751. #endif  // _SUPPORT_EVENT_PACKAGE
  1752.  
  1753.     case EVENT_FIREWALL_STATUS_CHANGE:
  1754.         {
  1755.             PAL_DB(" FIREWALL STATUS CHANGE");
  1756. #ifdef USE_VARIANT_IN_EVENT
  1757.             GeneralSafeArray aMsg(6);
  1758.             aMsg.PutNumber(0,p->m_iLine);
  1759.             aMsg.PutString(1,p->m_sDisplayName);
  1760.             aMsg.PutString(2,p->m_sTargetURI);
  1761.             aMsg.PutBool(3,p->m_bVideoCall);
  1762.             aMsg.PutString(4,p->m_sReason);
  1763.             aMsg.PutNumber(5, p->m_iAccnt);
  1764.  
  1765.             FIRE_EVENT(OnFirewallStatusChange, aMsg.GetVariantRef());
  1766. #else
  1767.             FIRE_EVENT(OnFirewallStatusChange, p->m_iLine,
  1768.                                         ToBstr(p->m_sDisplayName),
  1769.                                         ToBstr(p->m_sTargetURI),
  1770.                                         ToVB(p->m_bVideoCall),
  1771.                                         ToBstr(p->m_sReason),
  1772.                                         p->m_iAccnt);
  1773. #endif
  1774.         }
  1775.         break;
  1776.  
  1777. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  1778.     case EVENT_BANDWIDTH_WARNING:
  1779.         {
  1780.             PAL_DB(" BANDWIDTH_WARNING");
  1781. #ifdef USE_VARIANT_IN_EVENT
  1782.             GeneralSafeArray aMsg(6);
  1783.             aMsg.PutNumber(0,p->m_iLine);
  1784.             aMsg.PutString(1,p->m_sDisplayName);
  1785.             aMsg.PutString(2,p->m_sTargetURI);
  1786.             aMsg.PutBool(3,p->m_bVideoCall);
  1787.             aMsg.PutString(4,p->m_sReason);
  1788.             aMsg.PutNumber(5, p->m_iAccnt);
  1789.  
  1790.             FIRE_EVENT(OnBandwidthWarning, aMsg.GetVariantRef());
  1791. #else
  1792.             FIRE_EVENT(OnBandwidthWarning, p->m_iLine,
  1793.                                     ToBstr(p->m_sDisplayName),
  1794.                                     ToBstr(p->m_sTargetURI),
  1795.                                     ToVB(p->m_bVideoCall),
  1796.                                     ToBstr(p->m_sReason),
  1797.                                     p->m_iAccnt);
  1798. #endif
  1799.         }
  1800.         break;
  1801. #endif
  1802.  
  1803.     case EVENT_CONFERENCE_JOIN:
  1804.         {
  1805.             m_pCallLine->NotifyConfList();
  1806.             SetUpdateConferenceListTimer();
  1807.         }
  1808.         break;
  1809.  
  1810.     case EVENT_CONFERENCE_QUERY:
  1811.         {
  1812.             m_pCallLine->QueryConfClient(p->m_iLine);          
  1813.         }
  1814.         break;
  1815.  
  1816.     case EVENT_TEXT_MESSAGE:
  1817.         {
  1818.             //PAL_DB(" TEXT MESSAGE");
  1819. #ifdef USE_VARIANT_IN_EVENT
  1820.             GeneralSafeArray aMsg(4);
  1821.             BSTR bstrMsg = SysAllocStringByteLen((
  1822.                 LPCSTR)(p->m_sSipMessage).data(),
  1823.                 (p->m_sSipMessage).size());
  1824.  
  1825.             aMsg.PutString(0,p->m_sDisplayName);
  1826.             aMsg.PutString(1,p->m_sTargetURI);
  1827.             aMsg.PutBstr(2, (CComBSTR&)bstrMsg);
  1828.             aMsg.PutNumber(3, p->m_iAccnt);
  1829.              
  1830.            
  1831.             FIRE_EVENT(OnTextMessage, aMsg.GetVariantRef());
  1832. #else
  1833.             FIRE_EVENT(OnTextMessage,
  1834.                                 ToBstr(p->m_sDisplayName),
  1835.                                 ToBstr(p->m_sTargetURI),
  1836.                                 ToBstr(p->m_sSipMessage),
  1837.                                 p->m_iAccnt);
  1838. #endif
  1839.         }
  1840.         break;
  1841.     case EVENT_MESSAGE_USER_NOT_FOUND:
  1842.         break;
  1843.        
  1844. #ifndef NO_DATA_TRAVELER
  1845.     case EVENT_DATATRANSFER_REQUEST:
  1846.         {
  1847. #ifdef USE_VARIANT_IN_EVENT
  1848.             GeneralSafeArray aMsg(2);
  1849.             aMsg.PutString(0,p->m_sTargetURI);
  1850.             aMsg.PutNumber(1, p->m_iAccnt);
  1851.             FIRE_EVENT(OnDataRequest, aMsg.GetVariantRef());
  1852. #else
  1853.             FIRE_EVENT(OnDataRequest, ToBstr(p->m_sTargetURI), p->m_iAccnt);
  1854. #endif
  1855.         }
  1856.         break;
  1857.        
  1858.     case EVENT_DATATRANSFER_UPDATE:
  1859.         {  
  1860.             int id = p->m_iLine;
  1861.             int iSendStats = 0;
  1862.             int iRecvStats = 0;
  1863.  
  1864.             int iretSend = m_pDataTraveler->GetSendStatus(id, iSendStats);
  1865.             int iretRecv = m_pDataTraveler->GetRecvStatus(id, iRecvStats);
  1866.             if(iretRecv > 0)
  1867.             {
  1868. #ifdef USE_VARIANT_IN_EVENT
  1869.                 m_pFramework->Log("GetRecvStatus > 0");
  1870.                 GeneralSafeArray aMsg(4);
  1871.                 aMsg.PutString(0,p->m_sTargetURI);
  1872.                 aMsg.PutString(1,"Recv Status");
  1873.                 aMsg.PutString(2, "Data");
  1874.                 aMsg.PutNumber(3, p->m_iAccnt);
  1875.                 FIRE_EVENT(OnDataUpdate, aMsg.GetVariantRef());
  1876. #else
  1877.                 FIRE_EVENT(OnDataUpdate, ToBstr(p->m_sTargetURI),
  1878.                                    ToBstr("Recv Status"),
  1879.                                    ToBstr("Data"),
  1880.                                    p->m_iAccnt);
  1881. #endif
  1882.             }
  1883.             if(iretRecv == 0)
  1884.             {
  1885.                 m_pFramework->Log("GetRecvStatus == 0");
  1886. #ifdef USE_VARIANT_IN_EVENT
  1887.                 GeneralSafeArray aMsg(4);
  1888.                 aMsg.PutString(0, p->m_sTargetURI);
  1889.                 aMsg.PutString(1,"Recv Status");
  1890.                 aMsg.PutString(2, "Close");
  1891.                 aMsg.PutNumber(3, p->m_iAccnt);
  1892.                 FIRE_EVENT(OnDataUpdate, aMsg.GetVariantRef());
  1893. #else
  1894.                 FIRE_EVENT(OnDataUpdate, ToBstr(p->m_sTargetURI),
  1895.                                    ToBstr("Recv Status"),
  1896.                                    ToBstr("Close"),
  1897.                                    p->m_iAccnt);
  1898. #endif
  1899.             }
  1900.             if(iretRecv < 0)
  1901.             {
  1902.                 m_pFramework->Log("GetRecvStatus < 0");
  1903.  
  1904. #ifdef USE_VARIANT_IN_EVENT
  1905.                 GeneralSafeArray aMsg(4);
  1906.                 aMsg.PutString(0,p->m_sTargetURI);
  1907.                 aMsg.PutString(1,"Recv Status");
  1908.                 aMsg.PutString(2, itoa(iRecvStats));
  1909.                 aMsg.PutNumber(3, p->m_iAccnt);
  1910.  
  1911.                 FIRE_EVENT(OnDataUpdate, aMsg.GetVariantRef());
  1912. #else
  1913.                 FIRE_EVENT(OnDataUpdate, ToBstr(p->m_sTargetURI),
  1914.                                    ToBstr("Recv Status"),
  1915.                                    ToBstr(itoa(iRecvStats)),
  1916.                                    p->m_iAccnt);
  1917. #endif
  1918.             }
  1919.             if(iSendStats >= 0)
  1920.             {
  1921.                 m_pFramework->Log("GetSendStatus = " + itoa(iSendStats));
  1922. #ifdef USE_VARIANT_IN_EVENT
  1923.                 GeneralSafeArray aMsg(4);
  1924.                 aMsg.PutString(0,p->m_sTargetURI);
  1925.                 aMsg.PutString(1,"Send Status");
  1926.                 aMsg.PutString(2, itoa(iSendStats));
  1927.                 aMsg.PutNumber(3, p->m_iAccnt);
  1928.  
  1929.                 FIRE_EVENT(OnDataUpdate, aMsg.GetVariantRef());
  1930. #else
  1931.                 FIRE_EVENT(OnDataUpdate, ToBstr(p->m_sTargetURI),
  1932.                                    ToBstr("Send Status"),
  1933.                                    ToBstr(itoa(iSendStats)),
  1934.                                    p->m_iAccnt);
  1935. #endif
  1936.             }
  1937.         }
  1938.         break;
  1939. #endif
  1940.     case EVENT_SIP_CONNECTION_LOST:
  1941.         m_pFramework->Log("SIP connection lost event");
  1942.         HandleTimeoutOrError(accnt, true);     
  1943.         break;
  1944.  
  1945.     case EVENT_SRTP_NOT_ENABLED:
  1946.         {
  1947. #ifdef USE_VARIANT_IN_EVENT
  1948.             GeneralSafeArray aMsg(3);
  1949.             aMsg.PutNumber(0, p->m_iLine);
  1950.             aMsg.PutNumber(1, p->m_iAccnt);
  1951.             aMsg.PutString(2, p->m_sTargetURI);
  1952.  
  1953.             FIRE_EVENT(OnSRTPDisabled, aMsg.GetVariantRef());
  1954. #else
  1955.             FIRE_EVENT(OnSRTPDisabled, p->m_iLine, p->m_iAccnt, ToBstr(p->m_sTargetURI));
  1956. #endif
  1957.         }
  1958.         break;
  1959.     }
  1960.    
  1961.     SAFE_DELETE(p);
  1962.  
  1963.     bHandled = TRUE;
  1964.  
  1965.     StopProfileTimer("OnFireEvent");
  1966.     return 0;
  1967. }
  1968.  
  1969. #if defined(__unix__) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  1970. LRESULT CSessionControl::OnAudioEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1971. {
  1972.     switch (wParam) {
  1973.         case WM_AUDIO_NO_DATA:
  1974.             ThrowError("no audio data received");
  1975.             break;
  1976.            
  1977.         case WM_INVALID_MEDIA:
  1978.             ThrowError("invalid media");
  1979.             break;
  1980.  
  1981. #ifdef PHILIPS
  1982.     case WM_REMOTE_SOUND_LEVEL:
  1983.         FIRE_EVENT(OnRemoteSoundLevel, lParam);
  1984.         break;
  1985. #endif
  1986.  
  1987.         default:
  1988.             return -1;
  1989.     }
  1990.  
  1991.     return 0;
  1992. }
  1993.  
  1994. LRESULT CSessionControl::OnFunctionCall(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1995. {
  1996.     switch (wParam) {
  1997.         case WM_FC_SIP_END_CALL:
  1998.             EndCall(lParam == 1);
  1999.             break;
  2000.            
  2001.         default:
  2002.             return -1;
  2003.     }
  2004.    
  2005.     return 0;
  2006. }
  2007. #endif
  2008.  
  2009. void CSessionControl::HandleLogoutTimeoutOrError(int iAccnt)
  2010. {
  2011.     SipAccount* sipAccnt = GetSipAccount(iAccnt);
  2012.  
  2013.     RET_IF_NULL(sipAccnt);
  2014.  
  2015.     MSA_LOG("timer: " + itoa(sipAccnt->m_iLogoutResponseTimer));
  2016.     KILL_TIMER(sipAccnt->m_iLogoutResponseTimer);
  2017.     if (sipAccnt->m_pAgent->Logout(true/*failover*/))
  2018.     {
  2019. #ifdef _CUSTOM_TIMER_
  2020.         sipAccnt->m_iLogoutResponseTimer = SetTimer(
  2021.             LOGOUT_RESPONSE_TIMER_ID + GetAccountID(sipAccnt),
  2022.             CUSTOM_LOGOUT_RESPONSE_TIMEOUT*1000);
  2023. #else
  2024.         sipAccnt->m_iLogoutResponseTimer = SetTimer(
  2025.             LOGOUT_RESPONSE_TIMER_ID + GetAccountID(sipAccnt),
  2026.             LOGOUT_RESPONSE_TIMEOUT*1000);
  2027. #endif
  2028.     }
  2029.     else
  2030.     {
  2031.         PAL_DB("No response for logout.");
  2032.         m_pFramework->Log("No response for logout. restore session network");
  2033.         sipAccnt->m_pAgent->HandleTimeoutOrError();
  2034.         sipAccnt->m_pAgent->RestoreSessionNetwork();
  2035.         HandleLogoutComplete(iAccnt);
  2036.     }
  2037. }
  2038.  
  2039. void CSessionControl::HandleTimeoutOrError(int iAccnt, bool bSipConnectionLost /* = false */)
  2040. {
  2041.     SipAccount* sipAccnt = GetSipAccount(iAccnt);
  2042.  
  2043.     RET_IF_NULL(sipAccnt);
  2044.  
  2045.     // transport error fired from transaction layer
  2046.     // recv error
  2047.     // x - invite response times out (no longer called)
  2048.     // register response times out
  2049.     // register renew times out
  2050.     // stun keep alive times out
  2051.  
  2052.     KILL_TIMER(sipAccnt->m_iRegistrationResponseTimer);
  2053.     KILL_TIMER(sipAccnt->m_iInviteResponseTimer);
  2054.     KILL_TIMER(sipAccnt->m_iRegistrationRefreshTimer);
  2055.     KILL_TIMER(sipAccnt->m_iSignalChannelKeepAliveTimer);
  2056. #ifdef _SUPPORT_EVENT_PACKAGE
  2057.     KILL_TIMER(sipAccnt->m_iMWIRefreshTimer);
  2058. #endif
  2059.     KILL_TIMER(m_iUpdateConferenceListTimer);
  2060.  
  2061.     if (sipAccnt->m_iLogoutResponseTimer)
  2062.     {
  2063.         HandleLogoutTimeoutOrError(iAccnt);
  2064.         return;
  2065.     }
  2066.  
  2067.     if (!sipAccnt->m_sCallUri.empty())
  2068.     {
  2069.         sipAccnt->m_pAgent->HandleCallTimeoutOrError();
  2070.     }
  2071.  
  2072.     // close framework and call line
  2073.     // reset registration state to idle
  2074.     // register to a new server if available
  2075.     // start response timer
  2076.     // start refresh-response timer?
  2077.  
  2078.     // reinvite  if invite failed
  2079.     // fire no response during the first registration
  2080.     // fire connection lost during the rest registration
  2081.     if (sipAccnt->m_pAgent->HandleTimeoutOrError())
  2082.     {
  2083.         PAL_DB("Sip account already IDLE.");
  2084.         return;
  2085.     }
  2086.  
  2087.     m_pFramework->Log("HandleTimeoutOrError. restore session network");
  2088.     sipAccnt->m_pAgent->RestoreSessionNetwork();
  2089.  
  2090.     if (sipAccnt->m_bRegistered)
  2091.     {
  2092.         sipAccnt->m_bRegistered = false;
  2093.         sipAccnt->m_sCallUri = "";
  2094.         sipAccnt->m_pAgent->Logout(false);
  2095.  
  2096. #ifdef USE_VARIANT_IN_EVENT
  2097.         GeneralSafeArray aMsg(1);
  2098.         aMsg.PutNumber(0, iAccnt);
  2099.         FIRE_EVENT(OnConnectionLost, aMsg.GetVariantRef());
  2100. #else
  2101.         FIRE_EVENT(OnConnectionLost, iAccnt);
  2102. #endif
  2103.         sipAccnt->m_pAgent->LogText("Connection Lost for account " + itoa(iAccnt));
  2104.     }
  2105.     else
  2106.     {
  2107.         if (sipAccnt->m_pAgent->HasNextProxyServerIndex()){
  2108.                  RegisterFailOver(sipAccnt);
  2109.         }
  2110.         else{
  2111.             FireEventData* p = new FireEventData;
  2112.             PAL_ASSERT(p);
  2113.             p->m_iAccnt = iAccnt;
  2114.             p->m_iEventID = EVENT_REGISTER_RESPONSE;
  2115.  
  2116.             if (bSipConnectionLost)
  2117.             {
  2118.                 p->m_iResponse = RESPONSE_FAILURE;
  2119.                 p->m_sReason = "Tcp connection error.";
  2120.             }
  2121.             else
  2122.             {
  2123.                 p->m_iResponse = RESPONSE_TIMEOUT;
  2124.                 p->m_sReason = "Registration timed out.";
  2125.             }
  2126.             sipAccnt->m_pAgent->ResetRegistrationState();
  2127.             sipAccnt->m_pAgent->FireEvent(p);
  2128.         }
  2129.     }
  2130. }
  2131.  
  2132. void CSessionControl::HandleRefreshRegistrationComplete(int iAccnt)
  2133. {
  2134.     SipAccount* sipAccnt = GetSipAccount(iAccnt);
  2135.  
  2136.     RET_IF_NULL(sipAccnt);
  2137.  
  2138.     KILL_TIMER(sipAccnt->m_iRegistrationResponseTimer);
  2139. }
  2140.  
  2141. void CSessionControl::HandleLogoutComplete(int iAccnt)
  2142. {
  2143.     SipAccount* sipAccnt = GetSipAccount(iAccnt);
  2144.     RET_IF_NULL(sipAccnt);
  2145.    
  2146.     MSA_LOG("########### tttttimer: " + itoa(sipAccnt->m_iLogoutResponseTimer));
  2147.     KILL_TIMER(sipAccnt->m_iLogoutResponseTimer);
  2148.     sipAccnt->m_pAgent->RestoreSessionNetwork();
  2149.  
  2150.     FireEventData* p = new FireEventData;
  2151.     PAL_ASSERT(p);
  2152.     p->m_iAccnt = iAccnt;
  2153.     p->m_iEventID = EVENT_LOGOUT_COMPLETE;
  2154.     sipAccnt->m_pAgent->FireEvent(p);
  2155.     sipAccnt->m_pAgent->CloseConnection();
  2156. }
  2157.  
  2158. #ifdef _WIN32_WCE
  2159. HRESULT CSessionControl::ThrowError(const string& sError)
  2160. {
  2161.     CComBSTR bstr = ToBstr(sError);
  2162.     Fire_OnWinMobileError(bstr);
  2163.     return E_FAIL;
  2164. }
  2165. #else
  2166. HRESULT CSessionControl::ThrowError(const string& sError)
  2167. {
  2168. #if defined(__unix__) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  2169.     FIRE_EVENT(OnError, ToBstr(sError));
  2170.     return E_FAIL;
  2171. #else
  2172.     return Error(ToBstr(sError), IID_ISipComm, E_FAIL);
  2173. #endif
  2174. }
  2175. #endif
  2176.  
  2177. STDMETHODIMP CSessionControl::SetProxyServer(int iIndex, BSTR bstrProxyServer, int iProxyPort)
  2178. {
  2179.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2180.  
  2181.     RET_ERROR_STR(sipAccnt);
  2182.    
  2183.     string sProxyServer = TruncateSpace(ToStringA(bstrProxyServer));
  2184.     sipAccnt->m_SipSetting.m_sProxyServer = sProxyServer;
  2185.     sipAccnt->m_SipSetting.m_iProxyPort = iProxyPort;
  2186.     sipAccnt->m_SipSetting.m_iProxyIndex = iIndex;
  2187.     sipAccnt->m_pAgent->SetProxy(iIndex, sProxyServer, iProxyPort);
  2188.     return S_OK;
  2189. }
  2190.  
  2191. STDMETHODIMP CSessionControl::SetAccount(int iIndex, BSTR bstrSipUri, BSTR bstrAuthenticationID, BSTR bstrPassword)
  2192. {
  2193.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2194.    
  2195.     RET_ERROR_STR(sipAccnt);
  2196.    
  2197. #ifdef SIP_URI_CASE_SENSITIVE
  2198.     string sURI = TruncateSpace(ToStringA(bstrSipUri));
  2199.     string sAuthID = TruncateSpace(ToStringA(bstrAuthenticationID));
  2200. #else
  2201.     string sURI = tolower(TruncateSpace(ToStringA(bstrSipUri)));
  2202.     string sAuthID = tolower(TruncateSpace(ToStringA(bstrAuthenticationID)));
  2203. #endif
  2204.    
  2205.     if (sURI.empty())
  2206.         return ThrowError("ERROR: No SIP URI is given.");
  2207.  
  2208.     if (!MediaSessionUtil::IsValidSIPURI(sURI))
  2209.         return ThrowError("ERROR: Invalid SIP URI.");
  2210.  
  2211.     MSA_LOG("Account: " + sURI + " accnt: " + itoa(m_iSelectedAccount));
  2212.  
  2213.     string sPassword = TruncateSpace(ToStringA(bstrPassword));
  2214.  
  2215.     sipAccnt->m_SipSetting.m_sSipUri = sURI;
  2216.     sipAccnt->m_SipSetting.m_sAuthID = sAuthID;
  2217.     sipAccnt->m_SipSetting.m_sPassword = sPassword;
  2218.  
  2219.     sipAccnt->m_pAgent->SetAccount(
  2220.         iIndex,
  2221.         sURI,
  2222.         sAuthID,
  2223.         sPassword);
  2224.     return S_OK;
  2225. }
  2226.  
  2227. STDMETHODIMP CSessionControl::SetDomain(int iIndex, BSTR bstrDomain)
  2228. {
  2229.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2230.  
  2231.     RET_ERROR_STR(sipAccnt);
  2232.  
  2233.     string sDomain = TruncateSpace(ToStringA(bstrDomain));
  2234.  
  2235.     if (!AreURICharactersValid(sDomain))
  2236.         return ThrowError("ERROR: Invalid characters in domain.");
  2237.  
  2238.     sipAccnt->m_SipSetting.m_sDomain = sDomain;
  2239.     sipAccnt->m_pAgent->SetDomain(iIndex, sDomain);
  2240.     return S_OK;
  2241. }
  2242.  
  2243. STDMETHODIMP CSessionControl::SetDisplayName(int iIndex, BSTR bstrDisplayName)
  2244. {
  2245.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2246.  
  2247.     RET_ERROR_STR(sipAccnt);
  2248.  
  2249.     string sDisplayName = TruncateSpace(ToStringA(bstrDisplayName));
  2250.    
  2251.     sipAccnt->m_SipSetting.m_sDisplayName = sDisplayName;
  2252.     sipAccnt->m_pAgent->SetDisplayName(iIndex, sDisplayName);
  2253.     return S_OK;
  2254. }
  2255.  
  2256. STDMETHODIMP CSessionControl::Register()
  2257. {
  2258.     m_pFramework->Log("Registering for account " + tostring(m_iSelectedAccount));
  2259. #ifndef USE_NSSTREAM_FOR_SIP
  2260.     if (!m_bAFEngineInit)
  2261.     {
  2262.         if (m_pAFEngine->VersionCheckFailed())
  2263.         {
  2264.             return ThrowError("ERROR: AnyFirewallEngine version mismatch");
  2265.         }
  2266.         if (!m_pAFEngine->LoadLibraryFailed())
  2267.         {
  2268.             return ThrowError("ERROR: License expired");
  2269.         }
  2270.         return ThrowError("ERROR: AnyFirewallEngine failed to load");
  2271.     }
  2272. #endif
  2273.  
  2274.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2275.     RET_ERROR_STR(sipAccnt);
  2276.  
  2277.     StartProfileTimer("Register"); 
  2278.  
  2279.     sipAccnt->Configure();  //re-initialize an account's state in case
  2280.                             //it was altered during an error.
  2281.  
  2282.     HRESULT hr = sipAccnt->m_pAgent->Register();
  2283.     if (FAILED(hr))
  2284.     {
  2285.         return hr;
  2286.     }
  2287.  
  2288.     sipAccnt->m_bRegistered = false;
  2289.     SetRegistrationResponseTimer(m_iSelectedAccount);
  2290.  
  2291.     StopProfileTimer("Register");
  2292.     return S_OK;
  2293. }
  2294.  
  2295. void CSessionControl::RegisterFailOver(SipAccount* sipAccnt)
  2296. {
  2297.     StartProfileTimer("Register"); 
  2298.     sipAccnt->m_pAgent->ResetRegistrationState();
  2299. //  sipAccnt->Configure();  //re-initialize an account's state in case
  2300.                             //it was altered during an error.
  2301. //  sipAccnt->m_pAgent->HandleTimeoutOrError();
  2302.     HRESULT hr = sipAccnt->m_pAgent->Register();
  2303.     if (FAILED(hr))
  2304.     {
  2305.         return;
  2306.     }
  2307.  
  2308.     sipAccnt->m_bRegistered = false;
  2309.     SetRegistrationResponseTimer(m_iSelectedAccount);
  2310.  
  2311.     StopProfileTimer("Register");
  2312.     return;
  2313. }
  2314.  
  2315. STDMETHODIMP CSessionControl::SetGatewayPreferences(VARIANT_BOOL bLocalMCLine, VARIANT_BOOL bEnableICE, VARIANT_BOOL bEnableNoSDPINVITE, VARIANT_BOOL bSupportSymmetricRTP)
  2316. {
  2317.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2318.  
  2319.     RET_ERROR_STR(sipAccnt);
  2320.  
  2321.     sipAccnt->m_pAgent->SetGatewayPreferences(Tobool(bLocalMCLine), Tobool(bEnableICE), Tobool(bEnableNoSDPINVITE), Tobool(bSupportSymmetricRTP));
  2322.  
  2323.     return S_OK;
  2324. }
  2325.  
  2326. STDMETHODIMP CSessionControl::Call(BSTR bstrCallURI, BSTR bstrDomain, VARIANT_BOOL bAnonymous, VARIANT_BOOL bPhone, VARIANT_BOOL bConf)
  2327. {
  2328.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2329.  
  2330.     RET_ERROR_STR(sipAccnt);
  2331.    
  2332.     StartProfileTimer("Call");
  2333.  
  2334.     m_pFramework->Log("API Call()");
  2335.  
  2336.     CHECK_MEDIAFRAMEWORK();
  2337.  
  2338. #ifdef SIP_URI_CASE_SENSITIVE
  2339.     string sCallURI = TruncateSpace(ToStringA(bstrCallURI));
  2340. #else
  2341.     string sCallURI = tolower(TruncateSpace(ToStringA(bstrCallURI)));
  2342. #endif
  2343.     if (sCallURI.empty())
  2344.         return ThrowError("ERROR: No SIP URI is given.");
  2345.  
  2346.     if (!CheckCallURI(sCallURI, sipAccnt))
  2347.         return ThrowError("ERROR: Invalid SIP URI.");
  2348.  
  2349.     if (!sipAccnt->m_pAgent->IsRegistered())
  2350.         return ThrowError("ERROR: Not registered yet.");
  2351.  
  2352.     string sDomain = tolower(TruncateSpace(ToStringA(bstrDomain)));
  2353.     if(!sDomain.empty())
  2354.         sCallURI += "@" + sDomain;
  2355.    
  2356.     string sHostPart = MediaSessionUtil::GetDomainNameFromURI(sCallURI);
  2357.     string sCallee = sCallURI;
  2358.     if (sHostPart.empty())
  2359.     {
  2360.         sCallee += "@" + sipAccnt->m_pAgent->GetDomainName();
  2361.     }
  2362.  
  2363.     if(m_pCallLine->IsDialogExists(sCallee))
  2364.         return ThrowError("ERROR: Already in call.");
  2365.  
  2366.     int iLineStatus = m_pCallLine->IsCallValid( -1, Tobool(bConf));
  2367.    
  2368.     if( -1 == iLineStatus)
  2369.         return ThrowError("ERROR: Only one line can be active at a time.");
  2370.     else if ( -2 == iLineStatus)
  2371.         return ThrowError("ERROR: Active conference.");
  2372.     else if( -3 == iLineStatus)
  2373.         return ThrowError("ERROR: Part of a remote conference.");
  2374.  
  2375.     if((sipAccnt->m_pAgent->IsSrtpEnabled() ) && (m_pCallLine->NumberOfSecureLines() > 0))
  2376.         return ThrowError("ERROR: Only one SRTP call can be established at a time.");
  2377.  
  2378.     m_pFramework->Log((string)"### Call to =  " + sCallURI);
  2379.  
  2380.     if (!sipAccnt->m_pAgent->SmartSelectProxy(sCallURI))
  2381.         return ThrowError("ERROR: No proxy selected to make call.");
  2382.  
  2383.     int iLine = m_pCallLine->GrabOutboundLine();
  2384.     if (iLine < 0)
  2385.         return ThrowError("ERROR: No line is available to make call.");
  2386.  
  2387.     if (m_pCodecConfig->GetAudioFormats().empty() && m_pCodecConfig->GetVideoFormats().empty() )
  2388.     {
  2389.         m_pFramework->Log("Audio and Video codec are empty");
  2390.         return ThrowError("ERROR: Audio and video codec are empty.");
  2391.     }
  2392.  
  2393.     MakeNonBlockingCall(sipAccnt, sCallURI, iLine, -1, "", Tobool(bConf), Tobool(bAnonymous), Tobool(bPhone));
  2394.  
  2395.     m_pFramework->Log("API Call() returned");
  2396.     StopProfileTimer("Call");
  2397.  
  2398.     return S_OK;
  2399. }
  2400.  
  2401. void CSessionControl::MakeNonBlockingCall(
  2402.     SipAccount* sipAccnt,
  2403.     const std::string& sCallURI,
  2404.     int iLine,
  2405.     int iRefferedLine /* = -1 */,
  2406.     const std::string& sReplaceInfo /* = "" */,
  2407.     bool bConf /* = false */,
  2408.     bool bAnonymous /* = false */,
  2409.     bool bPhone /* = false */)
  2410. {
  2411.     NonBlockingCallInfo* pInfo = new NonBlockingCallInfo;
  2412.     pInfo->pControl = this;
  2413.     pInfo->sipAccnt = sipAccnt;
  2414.     pInfo->sCallURI = sCallURI;
  2415.     pInfo->iLine = iLine;
  2416.     pInfo->iRefferedLine = iRefferedLine;
  2417.     pInfo->sReplaceInfo = sReplaceInfo;
  2418.     pInfo->bConf = bConf;
  2419.     pInfo->bAnonymous = bAnonymous;
  2420.     pInfo->bPhone = bPhone;
  2421.     pInfo->pThread = NULL;
  2422.     pInfo->bThreadDone = false;
  2423.  
  2424. #if 0 //blocking
  2425.     PAL::Thread* pThread
  2426.         = new PAL::Thread(CSessionControl::NonBlockingCallThread, pInfo);
  2427.  
  2428.     if (pThread)
  2429.     {
  2430.         pThread->join();
  2431.         delete pThread;
  2432.     }
  2433. #else //non-blocking
  2434.     { PAL::Critical_Section cs(*m_pNonBlockingCallMutex);
  2435.  
  2436.         if (m_bDisableCalls)
  2437.         {
  2438.             delete pInfo;
  2439.         }
  2440.         else
  2441.         {
  2442.             PAL::Thread* pThread
  2443.                 = new PAL::Thread(CSessionControl::NonBlockingCallThread, pInfo);
  2444.  
  2445.             if (pThread)
  2446.             {
  2447.                 pInfo->pThread = pThread;
  2448.                 m_lsNonBlockingCallThreads.push_back(pInfo);
  2449.             }
  2450.         }
  2451.     } //end of critical section
  2452. #endif
  2453. }
  2454.  
  2455. void* CSessionControl::NonBlockingCallThread(void* arg)
  2456. {
  2457.     SET_CURRENT_THREAD_NAME;
  2458.     NonBlockingCallInfo* p = (NonBlockingCallInfo*)arg;
  2459.     if (!p)
  2460.     {
  2461.         PAL_DB_ASSERT(0 && "Bad argument to NonBlockingCallThread");
  2462.         return NULL;
  2463.     }
  2464.  
  2465.     //Wait on mutex for thread info to be pushed onto the list
  2466.     //Delete any old threads
  2467.     p->pControl->JoinNonBlockingCallThreads(false);
  2468.  
  2469.     p->sipAccnt->m_pAgent->Call(
  2470.         p->sCallURI,
  2471.         p->iLine,
  2472.         p->iRefferedLine,
  2473.         p->sReplaceInfo,
  2474.         p->bConf,
  2475.         p->bAnonymous,
  2476.         p->bPhone);
  2477.  
  2478.     p->sipAccnt->m_sCallUri = p->sCallURI;
  2479.     if (p->sipAccnt->m_iInviteResponseTimer)
  2480.     {
  2481.         p->pControl->KillTimer(p->sipAccnt->m_iInviteResponseTimer);
  2482.         p->sipAccnt->m_iInviteResponseTimer = 0;
  2483.     }
  2484.  
  2485. #ifdef _CUSTOM_TIMER_
  2486.     p->sipAccnt->m_iInviteResponseTimer = p->pControl->SetTimer(
  2487.          INVITE_RESPONSE_TIMER_ID + p->pControl->GetAccountID(p->sipAccnt),
  2488.          CUSTOM_INVITE_RESPONSE_TIMEOUT*1000);
  2489. #else
  2490.     p->sipAccnt->m_iInviteResponseTimer = p->pControl->SetTimer(
  2491.         INVITE_RESPONSE_TIMER_ID + p->pControl->GetAccountID(p->sipAccnt),
  2492.         INVITE_RESPONSE_TIMEOUT*1000);
  2493. #endif     
  2494.  
  2495.     p->bThreadDone = true;
  2496.  
  2497.     return NULL;
  2498. }
  2499.  
  2500. void CSessionControl::MakeNonBlockingRespondCall(
  2501.     SipAccount* sipAccnt,
  2502.     int iLine,
  2503.     bool bAccept,
  2504.     bool bConf)
  2505. {
  2506.     NonBlockingRespondCallInfo* pInfo = new NonBlockingRespondCallInfo;
  2507.     pInfo->pControl = this;
  2508.     pInfo->sipAccnt = sipAccnt;
  2509.     pInfo->iLine = iLine;
  2510.     pInfo->bAccept = bAccept;
  2511.     pInfo->bConf = bConf;
  2512.     pInfo->pThread = NULL;
  2513.     pInfo->bThreadDone = false;
  2514.  
  2515. #if 0 //blocking
  2516.     PAL::Thread* pThread
  2517.         = new PAL::Thread(CSessionControl::NonBlockingRespondCallThread, pInfo);
  2518.  
  2519.     if (pThread)
  2520.     {
  2521.         pThread->join();
  2522.         delete pThread;
  2523.     }
  2524. #else //non-blocking
  2525.     { PAL::Critical_Section cs(*m_pNonBlockingCallMutex);
  2526.  
  2527.         if (m_bDisableCalls)
  2528.         {
  2529.             delete pInfo;
  2530.         }
  2531.         else
  2532.         {
  2533.             PAL::Thread* pThread
  2534.                 = new PAL::Thread(CSessionControl::NonBlockingRespondCallThread, pInfo);
  2535.  
  2536.             if (pThread)
  2537.             {
  2538.                 pInfo->pThread = pThread;
  2539.                 m_lsNonBlockingRespondCallThreads.push_back(pInfo);
  2540.             }
  2541.         }
  2542.     } //end of critical section
  2543. #endif
  2544. }
  2545.  
  2546. void* CSessionControl::NonBlockingRespondCallThread(void* arg)
  2547. {
  2548.     SET_CURRENT_THREAD_NAME;
  2549.     NonBlockingRespondCallInfo* p = (NonBlockingRespondCallInfo*)arg;
  2550.     if (!p)
  2551.     {
  2552.         PAL_DB_ASSERT(0 && "Bad argument to NonBlockingRespondCallThread");
  2553.         return NULL;
  2554.     }
  2555.  
  2556.     //Wait on mutex for thread info to be pushed onto the list
  2557.     //Delete any old threads
  2558.     p->pControl->JoinNonBlockingCallThreads(false);
  2559.  
  2560.     p->sipAccnt->m_pAgent->RespondCall(
  2561.         p->iLine,
  2562.         p->bAccept,
  2563.         p->bConf);
  2564.  
  2565.     p->bThreadDone = true;
  2566.  
  2567.     return NULL;
  2568. }
  2569.  
  2570. void CSessionControl::JoinNonBlockingCallThreads(bool bWait)
  2571. {
  2572.     { PAL::Critical_Section cs(*m_pNonBlockingCallMutex);
  2573.  
  2574.         //Close Call Threads
  2575.         {
  2576.             std::list<NonBlockingCallInfo*>::iterator iter;
  2577.             std::list<NonBlockingCallInfo*>::iterator iterEnd;
  2578.            
  2579.             iter    = m_lsNonBlockingCallThreads.begin();
  2580.             iterEnd = m_lsNonBlockingCallThreads.end();
  2581.  
  2582.             //Close threads that are "done"
  2583.             while (iter != iterEnd)
  2584.             {
  2585.                 NonBlockingCallInfo* pInfo = (*iter);
  2586.                 if (pInfo)
  2587.                 {
  2588.                     if (bWait || pInfo->bThreadDone)
  2589.                     {
  2590.                         //Thread is finished
  2591.                         if (pInfo->pThread)
  2592.                         {
  2593.                             pInfo->pThread->join();
  2594.                             delete pInfo->pThread;
  2595.                         }
  2596.                         delete pInfo;
  2597.                         m_lsNonBlockingCallThreads.erase(iter++);
  2598.                     }
  2599.                     else
  2600.                     {
  2601.                         ++iter;
  2602.                     }
  2603.                 }
  2604.                 else
  2605.                 {
  2606.                     //erase NULL pointer
  2607.                     PAL_DB_ASSERT(0 && "NULL in nonblocking call thread list");
  2608.                     m_lsNonBlockingCallThreads.erase(iter++);
  2609.                 }
  2610.             }
  2611.         } //Done Close Call Threads
  2612.  
  2613.         //Close RespondCall Threads
  2614.         {
  2615.             std::list<NonBlockingRespondCallInfo*>::iterator iter;
  2616.             std::list<NonBlockingRespondCallInfo*>::iterator iterEnd;
  2617.            
  2618.             iter    = m_lsNonBlockingRespondCallThreads.begin();
  2619.             iterEnd = m_lsNonBlockingRespondCallThreads.end();
  2620.  
  2621.             //Close threads that are "done"
  2622.             while (iter != iterEnd)
  2623.             {
  2624.                 NonBlockingRespondCallInfo* pInfo = (*iter);
  2625.                 if (pInfo)
  2626.                 {
  2627.                     if (bWait || pInfo->bThreadDone)
  2628.                     {
  2629.                         //Thread is finished
  2630.                         if (pInfo->pThread)
  2631.                         {
  2632.                             pInfo->pThread->join();
  2633.                             delete pInfo->pThread;
  2634.                         }
  2635.                         delete pInfo;
  2636.                         m_lsNonBlockingRespondCallThreads.erase(iter++);
  2637.                     }
  2638.                     else
  2639.                     {
  2640.                         ++iter;
  2641.                     }
  2642.                 }
  2643.                 else
  2644.                 {
  2645.                     //erase NULL pointer
  2646.                     PAL_DB_ASSERT(0 && "NULL in nonblocking respond call thread list");
  2647.                     m_lsNonBlockingRespondCallThreads.erase(iter++);
  2648.                 }
  2649.             }
  2650.         }//Done Close RespondCall Threads
  2651.     } //end of critical section
  2652. }
  2653.  
  2654. #ifdef _SUPPORT_EVENT_PACKAGE
  2655. STDMETHODIMP CSessionControl::ReferredCall(BSTR bstrCallURI, BSTR bstrRefferedLine, VARIANT_BOOL bAccept)
  2656. {
  2657.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2658.  
  2659.     RET_ERROR_STR(sipAccnt);
  2660.    
  2661.     string sLine = tolower(TruncateSpace(ToStringA(bstrRefferedLine)));
  2662.     string sBody = "SIP/2.0 503 Service Unavailable";
  2663.  
  2664.     int iLineNo = atoi(sLine.c_str());
  2665.     PAL_DB2("Line no: ", iLineNo);
  2666.  
  2667.     //check wheather SDK got the permission from user.
  2668.     if(!ToBOOL(bAccept))
  2669.     {
  2670.         PAL_DB("User didn't give permission");
  2671.         int iRet = sipAccnt->m_pAgent->Notify(iLineNo,sBody,"terminated");
  2672.         if(iRet == -1)
  2673.         {
  2674.             PAL_DB("Notify sending err.");
  2675.         }
  2676.         else
  2677.         {
  2678.             PAL_DB("Notify sending success.");
  2679.         }
  2680.        
  2681.         return S_OK;
  2682.     }
  2683.  
  2684.     CHECK_MEDIAFRAMEWORK();
  2685.  
  2686.     string sCallURI = tolower(TruncateSpace(ToStringA(bstrCallURI)));
  2687.     if (sCallURI.empty())
  2688.     {
  2689.         sipAccnt->m_pAgent->Notify(iLineNo,sBody,"terminated");
  2690.         return ThrowError("ERROR: No SIP URI is given");
  2691.     }
  2692.  
  2693.     if (!CheckCallURI(sCallURI, sipAccnt))
  2694.     {
  2695.         sipAccnt->m_pAgent->Notify(iLineNo,sBody,"terminated");
  2696.         return ThrowError("ERROR: Invalid SIP URI.");
  2697.     }
  2698.  
  2699.     if (!sipAccnt->m_pAgent->IsRegistered())
  2700.     {
  2701.         sipAccnt->m_pAgent->Notify(iLineNo,sBody,"terminated");
  2702.         return ThrowError("ERROR: Not registered yet.");
  2703.     }
  2704.  
  2705.     int iLine = m_pCallLine->GrabOutboundLine();
  2706.     if (iLine < 0)
  2707.     {
  2708.         sipAccnt->m_pAgent->Notify(iLineNo,sBody,"terminated");
  2709.         return ThrowError("ERROR: No line is avaialable to make call.");
  2710.     }
  2711.  
  2712.     if (m_pCodecConfig->GetAudioFormats().empty() && m_pCodecConfig->GetVideoFormats().empty() )
  2713.     {
  2714.         m_pFramework->Log("Audio and Video codec are empty");
  2715.         return ThrowError("ERROR: Audio and video codec are empty.");
  2716.     }
  2717.  
  2718.     MakeNonBlockingCall(sipAccnt,sCallURI,iLine,iLineNo);
  2719.     return S_OK;
  2720. }
  2721. #endif //_SUPPORT_EVENT_PACKAGE
  2722.  
  2723. //TBD: try to determine the account ID from the URI.
  2724. STDMETHODIMP CSessionControl::TransferCall(BSTR bstrTransferURI)
  2725. {
  2726.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2727.  
  2728.     RET_ERROR_STR(sipAccnt);
  2729.  
  2730.     string sReferURI = tolower(TruncateSpace(ToStringA(bstrTransferURI)));
  2731.  
  2732.     if (sReferURI.empty())
  2733.         return ThrowError("ERROR: No SIP URI is given ");
  2734.  
  2735.     if (!CheckCallURI(sReferURI, sipAccnt))
  2736.         return ThrowError("ERROR: Invalid SIP URI.");
  2737.  
  2738.     if (!sipAccnt->m_pAgent->IsRegistered())
  2739.         return ThrowError("ERROR: Not registered yet.");
  2740.  
  2741.     int iSelectedLine = m_pCallLine->GetSelectedLine();
  2742.     string sTargetURI;
  2743.     if ( !sipAccnt->m_pAgent->GetCallTransferParams(iSelectedLine, sTargetURI,false) ) //callee
  2744.     {
  2745.         if ( !sipAccnt->m_pAgent->GetCallTransferParams(iSelectedLine, sTargetURI, true) ) //caller
  2746.         {
  2747.             PAL_DB("User is not callee. Call Transfer failed");
  2748.             return ThrowError("ERROR: Call Transfer failed.");
  2749.         }
  2750.     }
  2751.  
  2752.     if( sTargetURI.empty() )
  2753.     {
  2754.         return ThrowError("ERROR: TargetURI is empty Call Transfer.");
  2755.     }
  2756.  
  2757. #ifdef _SUPPORT_EVENT_PACKAGE
  2758.     int iRet = sipAccnt->m_pAgent->Refer(sTargetURI,sReferURI,"invite");
  2759.     if (iRet < 0)
  2760.         return ThrowError("ERROR: Refer failed in Call Transfer.");
  2761. #endif
  2762.  
  2763.     return S_OK;
  2764. }
  2765.  
  2766. STDMETHODIMP CSessionControl::EndCall(VARIANT_BOOL bAllCall)
  2767. {
  2768.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2769.     RET_ERROR_STR(sipAccnt);
  2770.  
  2771.     StartProfileTimer("EndCall");
  2772.     m_pFramework->Log("End Call");
  2773.  
  2774.     /////////////////////////////////////////
  2775.     sipAccnt->m_sCallUri = "";
  2776.     KILL_TIMER(sipAccnt->m_iInviteResponseTimer);
  2777.     //if endAllCalls, end calls on the selected sip account
  2778.     if (ToBOOL(bAllCall))
  2779.     {
  2780.         sipAccnt->m_pAgent->EndAllCall();
  2781.     }
  2782.     else
  2783.     {
  2784.         //else end the call on the selected line.
  2785.         CallDialog* p = m_pCallLine->GetSelectedDialog();
  2786.         if (!p)
  2787.         {
  2788.             // Maybe still in Call thread, so no CallDialog is still present in m_pCallLine
  2789.             // So make sure the Call thead finishes its operation thereby adding its CallDialog
  2790.             m_pFramework->Log("Trying to end a call but dialog doesn't exist. Waiting for all Call threads to exit...");
  2791.             JoinNonBlockingCallThreads(true);
  2792.             p = m_pCallLine->GetSelectedDialog();
  2793.             m_pFramework->Log("Waiting done.");
  2794.         }
  2795.  
  2796.         if (!p)
  2797.             return ThrowError("ERROR: EndCall::Invalid Line");
  2798.  
  2799.         SipAccount* sipAccnt = GetSipAccount(p->m_iAcct);
  2800.         RET_ERROR_STR(sipAccnt);
  2801.         sipAccnt->m_pAgent->EndCall();
  2802.     }
  2803.  
  2804.     StopProfileTimer("EndCall");
  2805.  
  2806.     return S_OK;
  2807. }
  2808.  
  2809. STDMETHODIMP CSessionControl::RespondCall(int iLine, VARIANT_BOOL bAccept,  VARIANT_BOOL bConf)
  2810. {
  2811.     CallDialog* p = m_pCallLine->GetDialog(iLine);
  2812.     if (!p)
  2813.     {
  2814.         return ThrowError("ERROR: RespondCall::Invalid Line");
  2815.     }
  2816.  
  2817.     if( Tobool(bAccept))
  2818.     {
  2819.         int iLineStatus = m_pCallLine->IsCallValid(iLine, Tobool(bConf));
  2820.  
  2821.         if( -1 == iLineStatus)
  2822.             return ThrowError("ERROR: Another one-one call Active.");
  2823.         else if ( -2 == iLineStatus)
  2824.             return ThrowError("ERROR: Active conference.");
  2825.         else if( -3 == iLineStatus)
  2826.             return ThrowError("ERROR: Part of a remote conference.");
  2827.  
  2828.     }
  2829.  
  2830.     SipAccount* sipAccnt = GetSipAccount(p->m_iAcct);
  2831.  
  2832.     RET_ERROR_STR(sipAccnt);
  2833.  
  2834.     CHECK_MEDIAFRAMEWORK();
  2835.  
  2836.     MakeNonBlockingRespondCall(sipAccnt, iLine, Tobool(bAccept), Tobool(bConf));
  2837.     return S_OK;
  2838. }
  2839.  
  2840. STDMETHODIMP CSessionControl::Subscribe(BSTR bstrCallURI)
  2841. {
  2842.  
  2843.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2844.  
  2845.     RET_ERROR_STR(sipAccnt);
  2846.  
  2847.     string sCallURI = tolower(TruncateSpace(ToStringA(bstrCallURI)));
  2848.    
  2849.     if (sCallURI.empty())
  2850.         return ThrowError("ERROR: No SIP URI is given");
  2851.    
  2852.     if (!CheckCallURI(sCallURI, sipAccnt))
  2853.         return ThrowError("ERROR: Invalid SIP URI.");
  2854.    
  2855.     if (!sipAccnt->m_pAgent->IsRegistered())
  2856.         return ThrowError("ERROR: Not registered yet.");
  2857.    
  2858.     int iLine = sipAccnt->m_pAgent->Subscribe(sCallURI);   
  2859.     if (iLine < 0)
  2860.         return ThrowError("ERROR: Subscribe failed.");
  2861.    
  2862.     return S_OK;
  2863. }
  2864.  
  2865. #ifdef _SUPPORT_EVENT_PACKAGE
  2866. STDMETHODIMP CSessionControl::MWISubscribe(BSTR bstrResourceURI)
  2867. {
  2868.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2869.  
  2870.     RET_ERROR_STR(sipAccnt);
  2871.  
  2872.     string sResourceURI = tolower(TruncateSpace(ToStringA(bstrResourceURI)));
  2873.  
  2874.     if (sResourceURI.empty())
  2875.         return ThrowError("ERROR: No SIP URI is given");
  2876.    
  2877.     if (!sipAccnt->m_pAgent->IsRegistered())
  2878.         return ThrowError("ERROR: Not registered yet.");
  2879.        
  2880.     int iLine = sipAccnt->m_pAgent->MwiSubscribe(sResourceURI);
  2881.     if (iLine < 0)
  2882.         return ThrowError("ERROR: MWI Subscribe already done.");
  2883.    
  2884.     return S_OK;
  2885.  
  2886. }
  2887. STDMETHODIMP CSessionControl::MWIUnSubscribe()
  2888. {
  2889.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2890.  
  2891.     RET_ERROR_STR(sipAccnt);
  2892.  
  2893.     int iLine = sipAccnt->m_pAgent->UnSubscribe(); 
  2894.     if (iLine < 0)
  2895.         return ThrowError("ERROR: Not Subscribe yet.");
  2896.    
  2897.     KILL_TIMER(sipAccnt->m_iMWIRefreshTimer);
  2898.     return S_OK;
  2899. }
  2900.  
  2901. STDMETHODIMP CSessionControl::Refer(BSTR bstrCallURI,BSTR bstrReferURI,BSTR bstrMethod)
  2902. {
  2903.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2904.  
  2905.     RET_ERROR_STR(sipAccnt);
  2906.  
  2907.     string sCallURI = tolower(TruncateSpace(ToStringA(bstrCallURI)));
  2908.    
  2909.     if (sCallURI.empty())
  2910.         return ThrowError("ERROR: No SIP URI is given");
  2911.  
  2912.     if (!CheckCallURI(sCallURI, sipAccnt))
  2913.         return ThrowError("ERROR: Invalid SIP URI.");
  2914.  
  2915.     if (!sipAccnt->m_pAgent->IsRegistered())
  2916.         return ThrowError("ERROR: Not registered yet.");
  2917.    
  2918.     string sReferURI = tolower(TruncateSpace(ToStringA(bstrReferURI)));
  2919.  
  2920.     if (sReferURI.empty())
  2921.         return ThrowError("ERROR: No SIP URI is given.");
  2922.  
  2923.     if (!CheckCallURI(sReferURI, sipAccnt))
  2924.         return ThrowError("ERROR: Invalid SIP URI.");
  2925.  
  2926.     if (!sipAccnt->m_pAgent->IsRegistered())
  2927.         return ThrowError("ERROR: Not registered yet.");
  2928.  
  2929.     string sMethod = tolower(TruncateSpace(ToStringA(bstrMethod)));
  2930.     int iLine = sipAccnt->m_pAgent->Refer(sCallURI,sReferURI,"invite");
  2931.  
  2932.     if (iLine < 0)
  2933.         return ThrowError("ERROR: Refer failed.");
  2934.  
  2935.  
  2936.     return S_OK;
  2937. }
  2938.  
  2939. STDMETHODIMP CSessionControl::Option(BSTR bstrCallURI)
  2940. {
  2941.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2942.  
  2943.     RET_ERROR_STR(sipAccnt);
  2944.  
  2945.     string sCallURI = tolower(TruncateSpace(ToStringA(bstrCallURI)));
  2946.    
  2947.     if (sCallURI.empty())
  2948.         return ThrowError("ERROR: No SIP URI is given.");
  2949.    
  2950.     if (!CheckCallURI(sCallURI, sipAccnt))
  2951.         return ThrowError("ERROR: Invalid SIP URI.");
  2952.    
  2953.     if (!sipAccnt->m_pAgent->IsRegistered())
  2954.         return ThrowError("ERROR: Not registered yet.");
  2955.    
  2956.     int iLine = sipAccnt->m_pAgent->Option(sCallURI);  
  2957.     if (iLine < 0)
  2958.         return ThrowError("ERROR: Option failed.");
  2959.    
  2960.     return S_OK;
  2961. }
  2962.  
  2963. STDMETHODIMP CSessionControl::ReplaceCall(BSTR bstrCallURI,BSTR bstrDialogInfo)
  2964. {
  2965.     SipAccount* sipAccnt = GetSelectedSipAccount();
  2966.  
  2967.     RET_ERROR_STR(sipAccnt);
  2968.  
  2969.     CHECK_MEDIAFRAMEWORK();
  2970.  
  2971.     string sCallURI = tolower(TruncateSpace(ToStringA(bstrCallURI)));
  2972.     if (sCallURI.empty())
  2973.         return ThrowError("ERROR: No SIP URI is given.");
  2974.  
  2975.     if (!CheckCallURI(sCallURI, sipAccnt))
  2976.         return ThrowError("ERROR: Invalid SIP URI.");
  2977.  
  2978.     if (!sipAccnt->m_pAgent->IsRegistered())
  2979.         return ThrowError("ERROR: Not registered yet.");
  2980.  
  2981.     string sDialogInfo = TruncateSpace(ToStringA(bstrDialogInfo));
  2982.     PAL_DB2("Dialog Info: ", sDialogInfo.c_str());
  2983.  
  2984.     int iLine = m_pCallLine->GrabOutboundLine();
  2985.     if (iLine < 0)
  2986.         return ThrowError("ERROR: No line is available to make call.");
  2987.  
  2988.     if (m_pCodecConfig->GetAudioFormats().empty() && m_pCodecConfig->GetVideoFormats().empty() )
  2989.     {
  2990.         m_pFramework->Log("Audio and Video codec are empty");
  2991.         return ThrowError("ERROR: Audio and video codec are empty.");
  2992.     }
  2993.  
  2994.     MakeNonBlockingCall(sipAccnt,sCallURI,iLine,-1,sDialogInfo);
  2995.     return S_OK;
  2996. }
  2997. #endif
  2998.  
  2999. //Dhaka 4-6-2005
  3000. STDMETHODIMP CSessionControl::Notify(BSTR bstrCallURI)
  3001. {
  3002.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3003.  
  3004.     RET_ERROR_STR(sipAccnt);
  3005.  
  3006.     CHECK_MEDIAFRAMEWORK();
  3007.  
  3008.     string sCallURI = tolower(TruncateSpace(ToStringA(bstrCallURI)));
  3009.  
  3010.     int iLine = sipAccnt->m_pAgent->Notify(sCallURI);  
  3011.     if (iLine < 0)
  3012.         return ThrowError("ERROR: Notify failed.");
  3013.     return S_OK;
  3014. }
  3015.  
  3016.  
  3017. STDMETHODIMP CSessionControl::SendDTMF(BSTR bstrKey)
  3018. {
  3019.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3020.  
  3021.     RET_ERROR_STR(sipAccnt);
  3022.  
  3023.     CHECK_MEDIAFRAMEWORK();
  3024.    
  3025.     string sKey = ToString(bstrKey).mbs();
  3026.  
  3027.     char cDigit = atoi(sKey.c_str());
  3028.     if ((cDigit >= 10) || (cDigit < 0))
  3029.     {
  3030.         return S_FALSE;
  3031.     }
  3032.  
  3033.     if (cDigit == 0)
  3034.     {
  3035.         if (sKey == "*")
  3036.             cDigit = '*';
  3037.         else if (sKey == "#")
  3038.             cDigit = '#';
  3039.         else
  3040.             cDigit = '0';
  3041.     }
  3042.     else
  3043.     {
  3044.         cDigit = sKey.at(0);
  3045.     }
  3046.    
  3047.     if(sipAccnt->m_iSipInfoDtmf == 0)                   //RFC 2833
  3048.         sipAccnt->m_pAgent->SendDTMF(cDigit, false);
  3049.     else if(sipAccnt->m_iSipInfoDtmf == 1)              //SIP INFO
  3050.         sipAccnt->m_pAgent->SendSipInfoDTMF(cDigit);
  3051.     else                                                //inband
  3052.         sipAccnt->m_pAgent->SendDTMF(cDigit, true);
  3053.  
  3054.     return S_OK;
  3055. }
  3056.  
  3057. STDMETHODIMP CSessionControl::get_IsLineIdle(VARIANT_BOOL* pVal)
  3058. {
  3059.     CHECK_POINTER(pVal);
  3060.     *pVal = m_pCallLine->IsLineIdle();
  3061.     return S_OK;
  3062. }
  3063.  
  3064.  
  3065. STDMETHODIMP CSessionControl::GetLineStatus(BSTR *pVal)
  3066. {
  3067.     CHECK_POINTER(pVal);
  3068.     int i = m_pCallLine->GetCallStatus();
  3069.     string s;
  3070.     switch (i)
  3071.     {
  3072.     case CALL_IDLE:
  3073.         s = "idle";
  3074.         break;
  3075.  
  3076.     case CALL_CALLING:
  3077.         s = "calling";
  3078.         break;
  3079.  
  3080.     case CALL_RINGING:
  3081.         s = "ringing";
  3082.         break;
  3083.  
  3084.     case CALL_PROCEEDING:
  3085.         s = "proceeding";
  3086.         break;
  3087.  
  3088.     case CALL_COMPLETED:
  3089.         s = "established";
  3090.         break;
  3091.     }
  3092.  
  3093.     if (m_pCallLine->IsLineHeld())
  3094.         s = "on hold";  // red
  3095.  
  3096.     // for Zunnun
  3097.     CallDialog* pDlg = m_pCallLine->GetSelectedDialog();
  3098.     if (NULL != pDlg)
  3099.     {
  3100.         if(pDlg->m_bHold && pDlg->m_bRemoteHold)
  3101.         {
  3102.             s = "on hold by both";  //
  3103.         }
  3104.         else if(pDlg->m_bRemoteHold)
  3105.         {
  3106.             s = "on hold by remote";  // orange
  3107.         }
  3108.     }
  3109.  
  3110.     BstrFromString(pVal, s);
  3111.  
  3112.     return S_OK;
  3113. }
  3114.  
  3115.  
  3116. STDMETHODIMP CSessionControl::GetDisplayName(BSTR *pVal)
  3117. {
  3118.     CHECK_POINTER(pVal);
  3119.     string s = m_pCallLine->GetDisplayName();
  3120.     BstrFromString(pVal, s);
  3121.     return S_OK;
  3122. }
  3123.  
  3124. STDMETHODIMP CSessionControl::GetCallURI(BSTR *pVal)
  3125. {
  3126.     CHECK_POINTER(pVal);
  3127.     string s = m_pCallLine->GetTargetURI();
  3128.     BstrFromString(pVal, s);
  3129.     return S_OK;
  3130. }
  3131.  
  3132. STDMETHODIMP CSessionControl::get_HoldLine(VARIANT_BOOL *pVal)
  3133. {
  3134.     CHECK_POINTER(pVal);
  3135.     *pVal = ToVB(m_pCallLine->IsLineHeld());
  3136.     return S_OK;
  3137. }
  3138.  
  3139. STDMETHODIMP CSessionControl::get_LineStatusChanging(VARIANT_BOOL *pVal)
  3140. {
  3141.     CHECK_POINTER(pVal);
  3142.     *pVal = ToVB(m_pCallLine->IsLineStatusChanging());
  3143.     return S_OK;
  3144. }
  3145.  
  3146. STDMETHODIMP CSessionControl::GetFirewallStatus(int iLine, BSTR* pVal)
  3147. {
  3148.     CHECK_POINTER(pVal);
  3149.  
  3150.     CallDialog* pDlg = m_pCallLine->GetDialog(iLine);
  3151.     if (pDlg == NULL) {
  3152.         tstring status = "";
  3153.         BstrFromString(pVal, status);
  3154.     }
  3155.     else {
  3156.         string sFirewallStatus = pDlg->m_sFirewallStatus;
  3157.         if(sFirewallStatus == "UDP Relay" || sFirewallStatus == "TCP Relay" || sFirewallStatus == "HTTP Relay")
  3158.         {
  3159.             sFirewallStatus = "Relay";
  3160.         }else if (sFirewallStatus == "Eyeball")
  3161.         {
  3162.             sFirewallStatus = "";
  3163.         }
  3164.         BstrFromString(pVal, sFirewallStatus);
  3165.     }
  3166.  
  3167.     return S_OK;
  3168. }
  3169.  
  3170. STDMETHODIMP CSessionControl::SendTextMessage(BSTR bstrURI, BSTR bstrText)
  3171. {
  3172.     //GET AGENT, FROM THERE GET DOMAIN, APPEND IT...
  3173.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3174.  
  3175.     RET_ERROR_STR(sipAccnt);
  3176.  
  3177.     string sURI = tolower(TruncateSpace(ToStringA(bstrURI)));
  3178.     if (sURI.empty())
  3179.         return ThrowError("ERROR: No SIP URI is given.");
  3180.  
  3181.     if (!CheckCallURI(sURI, sipAccnt))
  3182.         return ThrowError("ERROR: Invalid SIP URI.");
  3183.  
  3184.     if (!sipAccnt->m_pAgent->IsRegistered())
  3185.         return ThrowError("ERROR: Not registered yet.");
  3186.  
  3187. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  3188.     int nLen = SysStringByteLen(bstrText);
  3189.     const char* pBuf = (const char*)bstrText;
  3190. #else
  3191.     int nLen = bstrText.length();
  3192.     const char* pBuf = bstrText.c_str();
  3193. #endif
  3194.  
  3195.     string sData;
  3196.     sData.assign(pBuf, nLen);
  3197.  
  3198.     sipAccnt->m_pAgent->SendUserMessage(ToStringA(bstrURI), sData);
  3199.     return S_OK;
  3200. }
  3201.  
  3202. STDMETHODIMP CSessionControl::SendData(BSTR bstrURI, BSTR bstrData)
  3203. {
  3204.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3205.     RET_ERROR_STR(sipAccnt);
  3206.  
  3207.     string sURI = tolower(TruncateSpace(ToStringA(bstrURI)));
  3208.     if (sURI.empty())
  3209.         return ThrowError("ERROR: No SIP URI is given.");
  3210.  
  3211.     if (!CheckCallURI(sURI, sipAccnt))
  3212.         return ThrowError("ERROR: Invalid SIP URI.");
  3213.  
  3214.     if (!sipAccnt->m_pAgent->IsRegistered())
  3215.         return ThrowError("ERROR: Not registered yet.");
  3216.  
  3217. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  3218.     if (NULL == bstrData)
  3219. #else
  3220.     if ( bstrData.length() == 0 )
  3221. #endif
  3222.     {
  3223.         return ThrowError("ERROR: NULL data");
  3224.     }
  3225.  
  3226. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  3227.     int nLen = SysStringByteLen(bstrData);
  3228.     const char* pBuf = (const char*)bstrData;
  3229. #else
  3230.     int nLen = bstrData.length();
  3231.     const char* pBuf = bstrData.c_str();
  3232. #endif
  3233.  
  3234.     string sData;
  3235.     sData.assign(pBuf, nLen);
  3236.    
  3237.     m_pFramework->Log("DATATRANSFER send data size = " + itoa(nLen));
  3238.    
  3239.     if(!sipAccnt->m_pAgent->SendUserData(ToStringA(bstrURI), sData))
  3240.         return ThrowError("ERROR: Failed to send data");
  3241.  
  3242.     return S_OK;
  3243. }
  3244.  
  3245. STDMETHODIMP CSessionControl::RespondData(BSTR bstrURI, VARIANT_BOOL bAccept)
  3246. {
  3247. #ifndef NO_DATA_TRAVELER
  3248.     //bstrURI is guaranteed to be in "user@domain" form
  3249.     //if application passes to us what it recieved in
  3250.     //OnDataUpdate event.
  3251.  
  3252.     CDataDialog *p = NULL;
  3253.     p = m_pDataTraveler->FindDataDialog(ToStringA(bstrURI));
  3254.     if(!p)
  3255.     {
  3256.         return ThrowError("ERROR: URI is malformed.");
  3257.     }
  3258.     SipAccount* sipAccnt = GetSipAccount(p->m_iAccnt);
  3259.    
  3260.     RET_ERROR_STR(sipAccnt);
  3261.  
  3262.     string sURI = tolower(TruncateSpace(ToStringA(bstrURI)));
  3263.  
  3264.     if (sURI.empty())
  3265.         return ThrowError("ERROR: No SIP URI is given.");
  3266.  
  3267.     if (!CheckCallURI(sURI, sipAccnt))
  3268.         return ThrowError("ERROR: Invalid SIP URI.");
  3269.  
  3270.     if (!sipAccnt->m_pAgent->IsRegistered())
  3271.         return ThrowError("ERROR: Not registered yet.");
  3272.  
  3273.     sipAccnt->m_pAgent->RespondUserData(ToStringA(bstrURI), Tobool(bAccept));
  3274. #endif
  3275.     return S_OK;
  3276. }
  3277.  
  3278. STDMETHODIMP CSessionControl::EndData(BSTR bstrURI)
  3279. {
  3280. #ifndef NO_DATA_TRAVELER
  3281.     //we end data on selected account.
  3282.     //If user provides "user@domain" bstrURI, we can
  3283.     //end it on any account. TBD.
  3284.  
  3285.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3286.  
  3287.     RET_ERROR_STR(sipAccnt);
  3288.  
  3289.     string sURI = tolower(TruncateSpace(ToStringA(bstrURI)));
  3290.     if (sURI.empty())
  3291.         return ThrowError("ERROR: No SIP URI is given.");
  3292.  
  3293.     if (!CheckCallURI(sURI, sipAccnt))
  3294.         return ThrowError("ERROR: Invalid SIP URI.");
  3295.  
  3296.     if (!sipAccnt->m_pAgent->IsRegistered())
  3297.         return ThrowError("ERROR: Not registered yet.");
  3298.  
  3299.  
  3300.     sipAccnt->m_pAgent->EndUserData(ToStringA(bstrURI));
  3301. #endif
  3302.     return S_OK;
  3303. }
  3304.  
  3305. STDMETHODIMP CSessionControl::RecvData(BSTR bstrURI, BSTR* pVal)
  3306. {
  3307. #ifndef NO_DATA_TRAVELER
  3308.     //bstrURI is guaranteed to be in "user@domain" form
  3309.     //if application passes to us what it recieved in
  3310.     //OnDataUpdate event.
  3311.  
  3312.     CDataDialog *p = NULL;
  3313.     p = m_pDataTraveler->FindDataDialog(ToStringA(bstrURI));
  3314.     if(!p)
  3315.     {
  3316.         return ThrowError("ERROR: URI is malformed.");
  3317.     }
  3318.     SipAccount* sipAccnt = GetSipAccount(p->m_iAccnt);
  3319.    
  3320.     RET_ERROR_STR(sipAccnt);
  3321.  
  3322.     string sURI = tolower(TruncateSpace(ToStringA(bstrURI)));
  3323.     if (sURI.empty())
  3324.         return ThrowError("ERROR: No SIP URI is given.");
  3325.  
  3326.     if (!CheckCallURI(sURI, sipAccnt))
  3327.         return ThrowError("ERROR: Invalid SIP URI.");
  3328.  
  3329.     if (!sipAccnt->m_pAgent->IsRegistered())
  3330.         return ThrowError("ERROR: Not registered yet.");
  3331.  
  3332.     string recvData;
  3333.     sipAccnt->m_pAgent->RecvUserData(ToStringA(bstrURI), recvData);
  3334.  
  3335.     m_pFramework->Log("DATATRANSFER RecvData, size = " + itoa(recvData.size()));
  3336. #ifndef __unix__
  3337.     *pVal = SysAllocStringByteLen((LPCSTR)recvData.data(), recvData.size());
  3338. #endif
  3339. #endif
  3340.     return S_OK;
  3341. }
  3342.  
  3343. STDMETHODIMP CSessionControl::put_HoldMediaInLine(VARIANT_BOOL bAudio, VARIANT_BOOL bVideo)
  3344. {
  3345.     CHECK_MEDIAFRAMEWORK();
  3346.  
  3347.     return m_pCallLine->HoldMedia(Tobool(bAudio), Tobool(bVideo)) ? S_OK : E_FAIL;
  3348. }
  3349.  
  3350. STDMETHODIMP CSessionControl::put_HoldLine(VARIANT_BOOL newVal)
  3351. {
  3352.     CHECK_MEDIAFRAMEWORK();
  3353.  
  3354.     return m_pCallLine->HoldLine(Tobool(newVal)) ? S_OK : E_FAIL;
  3355. }
  3356.  
  3357. STDMETHODIMP CSessionControl::put_HoldConference(VARIANT_BOOL newVal)
  3358. {
  3359.     CHECK_MEDIAFRAMEWORK();
  3360.  
  3361.     //for unhold conf, check pre-condition
  3362.     if( false == Tobool(newVal) )
  3363.     {
  3364.         if(m_pCallLine->IsAnyActiveCall(-1))
  3365.             return S_OK;
  3366.     }
  3367.    
  3368.     m_pFramework->m_mediaFramework->put_HoldConference(ToVB(newVal));
  3369.     return S_OK;
  3370. }
  3371.  
  3372. STDMETHODIMP CSessionControl::get_HoldConference(VARIANT_BOOL *pVal)
  3373. {
  3374.     CHECK_MEDIAFRAMEWORK();
  3375.     CHECK_POINTER(pVal);
  3376.  
  3377.     m_pFramework->m_mediaFramework->get_HoldConference(pVal);
  3378.  
  3379.     return S_OK;
  3380. }
  3381.  
  3382.  
  3383. STDMETHODIMP CSessionControl::put_ConferenceLine(VARIANT_BOOL newVal)
  3384. {
  3385.     //move to conference
  3386.     CHECK_MEDIAFRAMEWORK();
  3387.    
  3388.     CallDialog* pDlg = m_pCallLine->GetSelectedDialog();
  3389.    
  3390.     if(!pDlg)  
  3391.         return S_OK;
  3392.  
  3393.     bool bConf = Tobool(newVal);
  3394.    
  3395.     m_pFramework->Log("Putting line " + tostring(pDlg->m_iLine) + " conference state to " + tostring(bConf) + ". Old state conf " + tostring(pDlg->m_bConf) + ", remote conf " + tostring(pDlg->m_bRemoteConf) + ", hold " + tostring(pDlg->m_bHold) + ", remote hold " + tostring(pDlg->m_bRemoteHold));
  3396.  
  3397.     if(bConf)                   //move to conference
  3398.     {
  3399.         if(pDlg->m_bConf)       //already in conference
  3400.             return S_OK;
  3401.        
  3402.         if(/*pDlg->m_bRemoteHold ||*/ pDlg->m_bRemoteConf) 
  3403.             return S_OK;
  3404.  
  3405.         if(pDlg->m_bHold)       //unhold first
  3406.             m_pCallLine->HoldLine(false);
  3407.  
  3408.         if(m_pCallLine->NumberOfSecureLines() > 0)
  3409.             return ThrowError("ERROR: Cannot add secure line to conference.");
  3410.        
  3411.         m_pFramework->MoveToConference(pDlg);
  3412.     }
  3413.     else    //remove from conference
  3414.     {
  3415.         if(!pDlg->m_bConf)  //already removed from conf.
  3416.             return S_OK;
  3417.  
  3418.         m_pCallLine->NotifyConfRemove(pDlg->m_iLine);
  3419.         m_pFramework->RemoveFromConference(pDlg);
  3420.         m_pCallLine->HoldLine(true);
  3421.      
  3422.     }
  3423.    
  3424.     return S_OK;
  3425. }
  3426.  
  3427. STDMETHODIMP CSessionControl::get_ConferenceLine(VARIANT_BOOL *pVal)
  3428. {
  3429.     CHECK_MEDIAFRAMEWORK();
  3430.     CHECK_POINTER(pVal);
  3431.    
  3432.     *pVal = VARIANT_FALSE;
  3433.  
  3434.     CallDialog* pDlg = m_pCallLine->GetSelectedDialog();
  3435.    
  3436.     if(!pDlg)  
  3437.         return S_OK;
  3438.  
  3439.     if(pDlg->m_bConf)
  3440.         *pVal = VARIANT_TRUE;
  3441.  
  3442.     return S_OK;
  3443. }
  3444.  
  3445.  
  3446. STDMETHODIMP CSessionControl::get_NoSdpInvite(VARIANT_BOOL *pVal)
  3447. {
  3448.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3449.  
  3450.     RET_ERROR_STR(sipAccnt);
  3451.  
  3452.     CHECK_POINTER(pVal);
  3453.     *pVal = ToVB(sipAccnt->m_pAgent->GetNoSdpInvite());
  3454.     return S_OK;
  3455. }
  3456.  
  3457. STDMETHODIMP CSessionControl::put_NoSdpInvite(VARIANT_BOOL newVal)
  3458. {
  3459.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3460.     RET_ERROR_STR(sipAccnt);
  3461.     sipAccnt->m_pAgent->SetNoSdpInvite(Tobool(newVal));
  3462.     return S_OK;
  3463. }
  3464.  
  3465.  
  3466. STDMETHODIMP CSessionControl::get_MuteSender(VARIANT_BOOL *pVal)
  3467. {
  3468.     CHECK_MEDIAFRAMEWORK();
  3469.     CHECK_POINTER(pVal);
  3470.     m_pFramework->m_mediaFramework->get_Mute(pVal);
  3471.     return S_OK;
  3472. }
  3473.  
  3474. STDMETHODIMP CSessionControl::put_MuteSender(VARIANT_BOOL newVal)
  3475. {
  3476.     CHECK_MEDIAFRAMEWORK();
  3477.     m_pFramework->m_mediaFramework->put_Mute(newVal);
  3478.     return S_OK;
  3479. }
  3480.  
  3481. STDMETHODIMP CSessionControl::get_SelectedLine(int *pVal)
  3482. {
  3483.     CHECK_POINTER(pVal);
  3484.     *pVal = m_pCallLine->GetSelectedLine();
  3485.     return S_OK;
  3486. }
  3487.  
  3488. STDMETHODIMP CSessionControl::put_SelectedLine(int newVal)
  3489. {
  3490.     if(m_pCallLine->GetSelectedLine() != newVal){
  3491.         m_pCallLine->SetSelectedLine(newVal);
  3492.         m_pFramework->Log("### Selected Line =  " + itoa(newVal));
  3493.     }
  3494.     return S_OK;
  3495. }
  3496.  
  3497. STDMETHODIMP CSessionControl::get_ConferenceLine(int *pVal)
  3498. {
  3499.     CHECK_POINTER(pVal);
  3500.     *pVal = m_pCallLine->GetConferenceLine();
  3501.     return S_OK;
  3502. }
  3503.  
  3504. STDMETHODIMP CSessionControl::put_ConferenceLine(int newVal)
  3505. {
  3506.     m_pCallLine->SetConferenceLine(newVal);
  3507.     return S_OK;
  3508. }
  3509.  
  3510. STDMETHODIMP CSessionControl::get_MaximumLine(int *pVal)
  3511. {
  3512.     CHECK_POINTER(pVal);
  3513.     *pVal = m_pCallLine->GetMaximumLine();
  3514.     return S_OK;
  3515. }
  3516.  
  3517. STDMETHODIMP CSessionControl::put_MaximumLine(int newVal)
  3518. {
  3519.     m_pCallLine->SetMaximumLine(newVal);
  3520.     return S_OK;
  3521. }
  3522.  
  3523. STDMETHODIMP CSessionControl::get_UserMode(BSTR *pVal)
  3524. {
  3525.     CHECK_POINTER(pVal);
  3526.     int iMode = m_pCallLine->GetUserMode();
  3527.     string sMode;
  3528.     switch (iMode)
  3529.     {
  3530.     case MODE_AVAILABLE:
  3531.         sMode = "available";
  3532.         break;
  3533.  
  3534.     case MODE_AWAY:
  3535.         sMode = "away";
  3536.         break;
  3537.  
  3538.     case MODE_DND:
  3539.         sMode = "DND";
  3540.         break;
  3541.     }
  3542.  
  3543.     BstrFromString(pVal, sMode);
  3544.     return S_OK;
  3545. }
  3546.  
  3547. STDMETHODIMP CSessionControl::put_UserMode(BSTR newVal)
  3548. {
  3549.     string sMode = tolower(ToStringA(newVal));
  3550.     int iMode;
  3551.     if (sMode == "available")
  3552.     {
  3553.         iMode = MODE_AVAILABLE;
  3554.     }
  3555.     else if (sMode == "away")
  3556.     {
  3557.         iMode = MODE_AWAY;
  3558.     }
  3559.     else if (sMode == "dnd")
  3560.     {
  3561.         iMode = MODE_DND;
  3562.     }
  3563.     else
  3564.     {
  3565.         return ThrowError("ERROR: Invalid user mode.");
  3566.     }
  3567.  
  3568.     m_pCallLine->SetUserMode(iMode);
  3569.     return S_OK;
  3570. }
  3571.  
  3572. STDMETHODIMP CSessionControl::get_CallHistorySize(VARIANT_BOOL bDialed, int *pVal)
  3573. {
  3574.     CHECK_POINTER(pVal);
  3575.     *pVal = m_pCallHistory->GetHistorySize(Tobool(bDialed));
  3576.     return S_OK;
  3577. }
  3578.  
  3579. STDMETHODIMP CSessionControl::put_CallHistorySize(VARIANT_BOOL bDialed, int newVal)
  3580. {
  3581.     if (newVal < 0)
  3582.         return ThrowError("ERROR: Invalid call history size.");
  3583.  
  3584.     m_pCallHistory->SetHistorySize(Tobool(bDialed), newVal);
  3585.     return S_OK;
  3586. }
  3587.  
  3588. #ifdef USE_VARIANT_IN_EVENT
  3589. STDMETHODIMP CSessionControl::GetCallHistory(VARIANT_BOOL bDialed, SAFEARRAY **pVal)
  3590. #else
  3591. STDMETHODIMP CSessionControl::GetCallHistory(VARIANT_BOOL bDialed, std::vector<std::string> *pVal)
  3592. #endif
  3593. {
  3594.     CHECK_POINTER(pVal);
  3595.  
  3596.     CallHistoryList callList;
  3597.     m_pCallHistory->GetCallHistory(Tobool(bDialed), callList);
  3598.  
  3599.     CallHistoryList::iterator iter = callList.begin();
  3600. #ifdef USE_VARIANT_IN_EVENT
  3601.     GeneralSafeArray aMsg(callList.size() * 4);
  3602.     for (int i = 0; iter != callList.end(); iter++)
  3603.     {  
  3604.         CallHistoryElement& v = *iter;
  3605.         aMsg.PutString(i++, v.m_sDisplayName);
  3606.         aMsg.PutString(i++, v.m_sTargetURI);
  3607.         aMsg.PutString(i++, v.m_sCallingTime);
  3608.         aMsg.PutNumber(i++, v.m_iDuration);
  3609.     }
  3610.  
  3611.     aMsg.Detach(pVal);
  3612. #else
  3613.     pVal->clear();
  3614.     for(; iter != callList.end(); iter++)
  3615.     {
  3616.         CallHistoryElement& v = *iter;
  3617.         pVal->push_back(v.m_sDisplayName);
  3618.         pVal->push_back(v.m_sTargetURI);
  3619.         pVal->push_back(v.m_sCallingTime);
  3620.         pVal->push_back(itoa(v.m_iDuration));
  3621.     }
  3622. #endif
  3623.     return S_OK;
  3624. }
  3625.  
  3626. #if defined(WIN32) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  3627. STDMETHODIMP CSessionControl::GetCallDetail(int iLine, SAFEARRAY **pVal)
  3628. {
  3629.    
  3630.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3631.  
  3632.     RET_ERROR_STR(sipAccnt);
  3633.    
  3634.     CHECK_POINTER(pVal);
  3635.  
  3636.     if (!sipAccnt->m_pAgent->IsRegistered())
  3637.         return ThrowError("ERROR: Not registered yet.");
  3638.  
  3639.     vector<string> vCallInfo;
  3640.     int iRet = sipAccnt->m_pAgent->GetCallDetail(iLine,vCallInfo);
  3641.     if( iRet != 0 )
  3642.         return ThrowError("ERROR: Line Doesn't exists.");
  3643.  
  3644.     int iSize = vCallInfo.size();
  3645.     GeneralSafeArray aMsg(iSize);
  3646.  
  3647.     /*
  3648.     * aMsg(0) contains Called ID.If P-Called-Party-ID header not present,
  3649.     * then it is empty string.
  3650.     * aMsg(1,2 or more) contains Caller ID.
  3651.     * sizeof(aMsg) = 1 + #PAID present in INVITE message.
  3652.     */
  3653.  
  3654.     for(int i=0; i< iSize; i++)
  3655.     {
  3656.         aMsg.PutString(i, vCallInfo[i]);
  3657.     }
  3658.    
  3659.     aMsg.Detach(pVal);
  3660.     return S_OK;
  3661. }
  3662. #endif
  3663.  
  3664. STDMETHODIMP CSessionControl::get_ForwardURI(BSTR *pVal)
  3665. {
  3666.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3667.  
  3668.     RET_ERROR_STR(sipAccnt);
  3669.  
  3670.     CHECK_POINTER(pVal);
  3671.     BstrFromString(pVal, sipAccnt->m_pAgent->m_sForwardURI);
  3672.     return S_OK;
  3673. }
  3674.  
  3675. STDMETHODIMP CSessionControl::put_ForwardURI(BSTR newVal)
  3676. {
  3677.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3678.  
  3679.     RET_ERROR_STR(sipAccnt);
  3680.  
  3681.     sipAccnt->m_pAgent->SetForwardURI(ToStringA(newVal));
  3682.     return S_OK;
  3683. }
  3684.  
  3685. STDMETHODIMP CSessionControl::ForwardCall(int iLine, BSTR bstrURI, BSTR bstrReason)
  3686. {
  3687.     CallDialog* p = m_pCallLine->GetDialog(iLine);
  3688.     if (!p)
  3689.     {
  3690.         return ThrowError("ERROR: ForwardCall::Invalid Line");
  3691.     }
  3692.  
  3693.     SipAccount* sipAccnt = GetSipAccount(p->m_iAcct);
  3694.     RET_ERROR_STR(sipAccnt);
  3695.  
  3696.     string sURI = ToStringA(bstrURI);
  3697.     if (sURI.empty())
  3698.         return ThrowError("ERROR: ForwardCall::Invalid URI.");
  3699.  
  3700.     string sReason = ToStringA(bstrReason);
  3701.  
  3702.     sipAccnt->m_pAgent->ForwardCall(iLine, sURI, sReason);
  3703.     return S_OK;
  3704. }
  3705.  
  3706. STDMETHODIMP CSessionControl::get_CallHistoryFileName(BSTR *pVal)
  3707. {
  3708.     CHECK_POINTER(pVal);
  3709.     BstrFromString(pVal, m_pCallHistory->GetFileName());
  3710.     return S_OK;
  3711. }
  3712.  
  3713. STDMETHODIMP CSessionControl::put_CallHistoryFileName(BSTR newVal)
  3714. {
  3715.     m_pCallHistory->SetFileName(ToString(newVal));
  3716. #ifdef __unix__
  3717.     m_pCallHistory->LoadCallHistory();
  3718. #endif
  3719.     return S_OK;
  3720. }
  3721.  
  3722. STDMETHODIMP CSessionControl::RemoveCallHistory(VARIANT_BOOL bDialed, int iIndex)
  3723. {
  3724.     m_pCallHistory->RemoveCallHistory(Tobool(bDialed), iIndex);
  3725.     m_pCallHistory->SaveCallHistory();
  3726.     return S_OK;
  3727. }
  3728.  
  3729.  
  3730. STDMETHODIMP CSessionControl::GrabLine(int iLineToGrab, int *iLineGrabbed)
  3731. {
  3732.     CHECK_POINTER(iLineGrabbed);
  3733. #ifdef NO_SIP
  3734.     *iLineGrabbed = -1;
  3735.     if(m_pCallLine->GetDialog(iLineToGrab)){
  3736.         return ThrowError("Line is already in use.");
  3737.     }
  3738.     if(iLineToGrab >= 0 && iLineToGrab < m_pCallLine->GetMaximumLine()){
  3739.         *iLineGrabbed = iLineToGrab;
  3740.     }
  3741.     if(*iLineGrabbed == -1){
  3742.         for (int i = 0; i < m_pCallLine->GetMaximumLine(); i++)
  3743.         {
  3744.             if (!m_pCallLine->GetDialog(i))
  3745.             {
  3746.                 *iLineGrabbed = i;
  3747.                 break;
  3748.             }
  3749.         }
  3750.     }
  3751.     if(*iLineGrabbed >= 0 && *iLineGrabbed < m_pCallLine->GetMaximumLine()){
  3752.         CallDialog dlg;
  3753.         m_pCallLine->AddDialog(*iLineGrabbed, dlg);
  3754.     }
  3755.     else{
  3756.         return ThrowError("Error in grabbling line.");
  3757.     }
  3758. #else
  3759.     *iLineGrabbed = m_pCallLine->GrabOutboundLine(iLineToGrab);
  3760. #endif
  3761.  
  3762.     m_pFramework->Log((string)"### Grab Line =  " + itoa(iLineToGrab) + " Grabbed = " + itoa(*iLineGrabbed));
  3763.     return S_OK;
  3764. }
  3765.  
  3766. STDMETHODIMP CSessionControl::ReleaseLine()
  3767. {
  3768.     m_pCallLine->FreeOutboundLine();    
  3769.     return S_OK;
  3770. }
  3771.  
  3772. STDMETHODIMP CSessionControl::get_EnablePreview(VARIANT_BOOL *pVal)
  3773. {
  3774.     CHECK_POINTER(pVal);
  3775.     CHECK_MEDIAFRAMEWORK();
  3776.     m_pFramework->m_mediaFramework->get_EnablePreview(pVal);
  3777.     return S_OK;
  3778. }
  3779.  
  3780. STDMETHODIMP CSessionControl::put_EnablePreview(VARIANT_BOOL newVal)
  3781. {
  3782.     CHECK_MEDIAFRAMEWORK();
  3783.     m_pFramework->m_mediaFramework->put_EnablePreview(newVal);
  3784.     return S_OK;
  3785. }
  3786.  
  3787. STDMETHODIMP CSessionControl::get_ImageSize(int *pVal)
  3788. {
  3789. #ifndef __NOVIDEO__
  3790.     CHECK_POINTER(pVal);
  3791.     CHECK_MEDIAFRAMEWORK();
  3792.  
  3793.     m_pFramework->m_mediaFramework->get_ImageSize(pVal);
  3794. #endif
  3795.     return S_OK;
  3796. }
  3797.  
  3798. STDMETHODIMP CSessionControl::put_ImageSize(int newVal)
  3799. {
  3800. #ifndef __NOVIDEO__
  3801.     CHECK_MEDIAFRAMEWORK();
  3802.    
  3803.     //if (INVALID_IMAGE_SIZE(newVal))
  3804.     //  return ThrowError("ERROR: Image size out of range.");
  3805.  
  3806.   m_pFramework->m_mediaFramework->put_ImageSize(newVal);
  3807. #endif
  3808.   return S_OK;
  3809. }
  3810.  
  3811. #if defined(__unix__) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  3812. STDMETHODIMP CSessionControl::AttachVideoWindow(int iLine, void *pWnd)
  3813. {
  3814. #if !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  3815.     CHECK_MEDIAFRAMEWORK();
  3816.    
  3817.     if (iLine == -1)
  3818.         m_pFramework->m_mediaFramework->SetPreviewWindow(pWnd);
  3819.    
  3820.     CallDialog* p = m_pCallLine->GetDialog(iLine);
  3821.     if (!p)
  3822.     {
  3823.         return S_OK;//Dont throw Error. We use line = -1 for attaching preview window.
  3824.     }
  3825.    
  3826.     SipAccount* sipAccnt = GetSipAccount(p->m_iAcct);
  3827.    
  3828.     RET_ERROR_STR(sipAccnt);
  3829.    
  3830.     sipAccnt->m_pAgent->AttachVideoWindow(iLine, 0, pWnd);
  3831. #endif
  3832.     return S_OK;
  3833. }
  3834. #else
  3835. STDMETHODIMP CSessionControl::AttachVideoWindow(int iLine, int nWnd)
  3836. {  
  3837.     CHECK_MEDIAFRAMEWORK();
  3838.    
  3839.     HWND hWnd = (HWND)nWnd;  // convert type
  3840.  
  3841.     if ((!hWnd) || (!::IsWindow(hWnd)))
  3842.     {
  3843. #ifndef _WIN32_WCE
  3844.         return Error("Invalid window handle");
  3845. #else
  3846.         return ThrowError("ERROR: Invalid window handle");
  3847. #endif
  3848.     }
  3849.     DWORD dwProcessId = 0;
  3850.     GetWindowThreadProcessId(hWnd, &dwProcessId);
  3851.     if (dwProcessId != GetWindowProcessID())
  3852.     {
  3853. #ifndef _WIN32_WCE
  3854.         return Error("Invalid window handle");
  3855. #else
  3856.         return ThrowError("ERROR: Invalid window handle");
  3857. #endif
  3858.     }
  3859.     ::PostMessage(hWnd, WM_CONFIG_VIDEO_WINDOW, WPARAM(WPARAM_SET_HANDLE), LPARAM(m_hWnd));
  3860.    
  3861.     if (iLine == -1)
  3862.         m_pFramework->m_mediaFramework->SetPreviewWindow(hWnd);
  3863.  
  3864.     CallDialog* p = m_pCallLine->GetDialog(iLine);
  3865.     if (!p)
  3866.     {
  3867.         return S_OK;//Dont throw Error. We use line = -1 for attaching preview window.
  3868.     }
  3869.  
  3870.     SipAccount* sipAccnt = GetSipAccount(p->m_iAcct);
  3871.  
  3872.     RET_ERROR_STR(sipAccnt);
  3873.  
  3874.     sipAccnt->m_pAgent->AttachVideoWindow(iLine, 0, hWnd);
  3875.  
  3876.     return S_OK;
  3877. }
  3878. #endif
  3879.  
  3880. STDMETHODIMP CSessionControl::AttachVideoWindowEx(int iLine, int iIndex, int hWnd)
  3881. {
  3882. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  3883.     CHECK_MEDIAFRAMEWORK();
  3884.    
  3885.     if (HWND(hWnd))
  3886.     {
  3887.         ::PostMessage(
  3888.             HWND(hWnd),
  3889.             WM_CONFIG_VIDEO_WINDOW,
  3890.             WPARAM(WPARAM_SET_HANDLE),
  3891.             LPARAM(m_hWnd));
  3892.     }
  3893.    
  3894.     if (iLine == -1)
  3895.         m_pFramework->m_mediaFramework->SetPreviewWindow((HWND)hWnd);
  3896.  
  3897.     CallDialog* p = m_pCallLine->GetDialog(iLine);
  3898.     if (!p)
  3899.     {
  3900.         return S_OK;//Dont throw Error. We use line = -1 for attaching preview window.
  3901.     }
  3902.  
  3903.     SipAccount* sipAccnt = GetSipAccount(p->m_iAcct);
  3904.  
  3905.     RET_ERROR_STR(sipAccnt);
  3906.  
  3907.  
  3908.     sipAccnt->m_pAgent->AttachVideoWindow(iLine, iIndex, (HWND)hWnd);
  3909. #endif
  3910.     return S_OK;
  3911. }
  3912.  
  3913. HRESULT CSessionControl::LoadCallHistory()
  3914. {
  3915.     return m_pCallHistory->LoadCallHistory();
  3916. }
  3917.  
  3918. HRESULT CSessionControl::SaveCallHistory()
  3919. {
  3920.     return m_pCallHistory->SaveCallHistory();
  3921. }
  3922.  
  3923. /**Logout of the selectedSipAccount.
  3924. * it also ends the call(s) associated with it.
  3925. */
  3926. STDMETHODIMP CSessionControl::Logout()
  3927. {
  3928.     m_pFramework->Log("Logging out account " + tostring(m_iSelectedAccount));
  3929.     MSA_LOG("Logging out account: " + itoa(m_iSelectedAccount));
  3930.     SipAccount* sipAccnt = GetSelectedSipAccount();
  3931.  
  3932.     RET_ERROR_STR(sipAccnt);
  3933.  
  3934.     //if we cancelled a pre-mature registration, that has not
  3935.     //finished firewall detection process, stop the detection thread.
  3936.     if(sipAccnt->m_pAgent->m_pConnectToSIPServerhread.get())
  3937.     {
  3938.         sipAccnt->m_pAgent->CloseConnection();
  3939.         sipAccnt->m_pAgent->CloseLoginDnsChannel();
  3940.         sipAccnt->m_pAgent->StopConnectToSIPServer();
  3941.     }
  3942.    
  3943.     KILL_TIMER(sipAccnt->m_iRegistrationResponseTimer);
  3944.     KILL_TIMER(sipAccnt->m_iRegistrationRefreshTimer);
  3945.     KILL_TIMER(sipAccnt->m_iSignalChannelKeepAliveTimer);
  3946. #ifdef _SUPPORT_EVENT_PACKAGE
  3947.     KILL_TIMER(sipAccnt->m_iMWIRefreshTimer);
  3948. #endif
  3949.     KILL_TIMER(m_iUpdateConferenceListTimer);
  3950.  
  3951.     EndCall(VARIANT_TRUE);
  3952.     if (sipAccnt->m_pAgent->Logout(false/*failover*/))
  3953.     {
  3954. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  3955.         if (m_hWnd)
  3956. #endif
  3957.         {
  3958. #ifdef _CUSTOM_TIMER_
  3959.             sipAccnt->m_iLogoutResponseTimer = SetTimer(
  3960.                 LOGOUT_RESPONSE_TIMER_ID + GetAccountID(sipAccnt),
  3961.                 CUSTOM_LOGOUT_RESPONSE_TIMEOUT * 1000);
  3962.  
  3963.             MSA_LOG("######################### Timer = " + itoa(LOGOUT_RESPONSE_TIMER_ID + GetAccountID(sipAccnt)));
  3964. #else
  3965.             sipAccnt->m_iLogoutResponseTimer = SetTimer(
  3966.                 LOGOUT_RESPONSE_TIMER_ID + GetAccountID(sipAccnt),
  3967.                 LOGOUT_RESPONSE_TIMEOUT * 1000);
  3968. #endif
  3969.         }
  3970.     }
  3971.  
  3972.     sipAccnt->m_bRegistered = false;
  3973.     MSA_LOG("Logged out account: " + itoa(m_iSelectedAccount));
  3974.     return S_OK;
  3975. }
  3976.  
  3977. STDMETHODIMP CSessionControl::IsVideoCall(VARIANT_BOOL *pVal)
  3978. {
  3979.     CHECK_MEDIAFRAMEWORK();
  3980.     CHECK_POINTER(pVal);
  3981.    
  3982.     *pVal = ToVB(m_pCallLine->HasMedia(false));
  3983.     return S_OK;
  3984. }
  3985.  
  3986. STDMETHODIMP CSessionControl::IsAudioCall(VARIANT_BOOL *pVal)
  3987. {
  3988.     CHECK_MEDIAFRAMEWORK();
  3989.     CHECK_POINTER(pVal);
  3990.    
  3991.     *pVal = ToVB(m_pCallLine->HasMedia(true));
  3992.     return S_OK;
  3993. }
  3994.  
  3995. STDMETHODIMP CSessionControl::IsIncomingCall(VARIANT_BOOL *pVal)
  3996. {
  3997.     CHECK_MEDIAFRAMEWORK();
  3998.     CHECK_POINTER(pVal);
  3999.    
  4000.     *pVal = ToVB(m_pCallLine->IsIncomingCall());
  4001.     return S_OK;
  4002. }
  4003.  
  4004.  
  4005. STDMETHODIMP CSessionControl::SetAnonymous(VARIANT_BOOL pVal) //7-6
  4006. {
  4007.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4008.  
  4009.     RET_ERROR_STR(sipAccnt);
  4010.    
  4011.     sipAccnt->m_bAnonymous = Tobool(pVal);
  4012.     return S_OK;
  4013. }
  4014.  
  4015. STDMETHODIMP CSessionControl::get_TransportMode(BSTR *pbstrTrasportMode)
  4016. {
  4017.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4018.  
  4019.     RET_ERROR_STR(sipAccnt);
  4020.    
  4021.     CHECK_POINTER(pbstrTrasportMode);
  4022.     int iTransportMode = sipAccnt->m_pAgent->GetTransportMode();
  4023.  
  4024.     switch(iTransportMode)
  4025.     {
  4026.     case UDP:
  4027.         BstrFromString(pbstrTrasportMode, "udp");
  4028.         break;
  4029.     case TCP:
  4030.         BstrFromString(pbstrTrasportMode, "tcp");
  4031.         break;
  4032.     case TLS:
  4033.         BstrFromString(pbstrTrasportMode, "tls");
  4034.         break; 
  4035.     }
  4036.    
  4037.     return S_OK;   
  4038. }
  4039.  
  4040. STDMETHODIMP CSessionControl::put_TransportMode(BSTR bstrTrasportMode)
  4041. {
  4042.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4043.  
  4044.     RET_ERROR_STR(sipAccnt);
  4045.    
  4046.     string sMode = TruncateSpace(ToStringA(bstrTrasportMode));
  4047.  
  4048.     if (sMode.empty())
  4049.         return ThrowError("ERROR: Empty Transport Mode.");
  4050.  
  4051.     if(sipAccnt->m_pAgent->IsRegistered())
  4052.     {
  4053.         return ThrowError("ERROR: Must be logged out first.");
  4054.     }
  4055.  
  4056.     if(!_stricmp(sMode.c_str(),"udp"))
  4057.     {
  4058.         sipAccnt->m_pAgent->SetTransportMode(UDP);
  4059.     }
  4060.     else if(!_stricmp(sMode.c_str(),"tcp"))
  4061.     {
  4062.         sipAccnt->m_pAgent->SetTransportMode(TCP);
  4063.     }
  4064.     else if(!_stricmp(sMode.c_str(),"tls"))
  4065.     {
  4066.         sipAccnt->m_pAgent->SetTransportMode(TLS);
  4067.     }
  4068.     else
  4069.     {
  4070.         return ThrowError(sMode +" Transport Mode not supported.");
  4071.     }
  4072.  
  4073.  
  4074.     return S_OK;
  4075. }
  4076.  
  4077. STDMETHODIMP CSessionControl::get_KeepAliveMethod(BSTR *pbstrMethod)
  4078. {
  4079.     CHECK_POINTER(pbstrMethod);
  4080.  
  4081.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4082.  
  4083.     if(sipAccnt->m_pAgent->GetKeepAliveMethod())
  4084.     {
  4085.         BstrFromString(pbstrMethod, "STUN");
  4086.     }
  4087.     else
  4088.     {
  4089.         BstrFromString(pbstrMethod, "SIP");
  4090.     }
  4091.  
  4092.     return S_OK;   
  4093. }
  4094.  
  4095. STDMETHODIMP CSessionControl::put_KeepAliveMethod(BSTR bstrMethod)
  4096. {  
  4097.     string sMode = TruncateSpace(ToStringA(bstrMethod));
  4098.  
  4099.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4100.  
  4101.     if(!_stricmp(sMode.c_str(),"stun"))
  4102.     {
  4103.         sipAccnt->m_pAgent->SetKeepAliveMethod(true);
  4104.     }
  4105.     else
  4106.     {
  4107.         sipAccnt->m_pAgent->SetKeepAliveMethod(false);
  4108.     }
  4109.  
  4110.     return S_OK;
  4111. }
  4112.  
  4113. STDMETHODIMP CSessionControl::AudioFramesPerPacket(int iValue)
  4114. {
  4115.     if(iValue<1 || iValue>3)
  4116.         return ThrowError("ERROR: Input range is 1-3");
  4117.     g_AFPPMultiplier = iValue;
  4118.    
  4119.     return S_OK;
  4120. }
  4121.  
  4122. STDMETHODIMP CSessionControl::SetTURNUsernamePassword(BSTR bstrUsername, BSTR bstrPassword)
  4123. {
  4124.     m_sTurnUsername = ToStringA(bstrUsername);
  4125.     m_sTurnPassword = ToStringA(bstrPassword);
  4126.  
  4127.     SetTURNUsernamePassword();
  4128.     return S_OK;
  4129. }
  4130.  
  4131. void CSessionControl::SetTURNUsernamePassword()
  4132. {
  4133.     m_pAFEngine->SetTURNUsernamePassword(
  4134. #if (AF_DLL_VERSION > 9600000)
  4135.         m_iAFEServerStoreID,
  4136. #endif
  4137.         m_sTurnUsername, m_sTurnPassword);
  4138. }
  4139.  
  4140. string CSessionControl::CreateHost(EServerType eServerType, const string &sProtocol)
  4141. {
  4142.     if(m_lstNATTraversalServers.find(eServerType) == m_lstNATTraversalServers.end())
  4143.         return "";
  4144.  
  4145.     string sHost;
  4146. #if (AF_DLL_VERSION > 950000)
  4147.     struct AfConnectionParams connParams;
  4148.     connParams.iRTO = 500;
  4149.     connParams.iRc = 1;
  4150.     connParams.iRm = 16;
  4151.     connParams.iTi = 3000;
  4152. #endif
  4153.  
  4154.     for(set<pair<string, int> >::const_iterator iter = m_lstNATTraversalServers[eServerType].begin(); iter != m_lstNATTraversalServers[eServerType].end(); iter++)
  4155.     {
  4156.         sHost += m_pAFEngine->CreateHost(AF_HOST_PUBLIC, iter->first, iter->second, sProtocol
  4157. #if (AF_DLL_VERSION > 950000)      
  4158.             , &connParams
  4159. #endif 
  4160.             );
  4161.     }
  4162.  
  4163.     return sHost;
  4164. }
  4165.  
  4166. STDMETHODIMP CSessionControl::SetNATTraversalServer(int iServerType, BSTR bstrAddr, int iPort, VARIANT_BOOL bDone)
  4167. {
  4168.     m_pFramework->Log("Setting AFS: iServerType = " + tostring(iServerType) + " " + ToStringA(bstrAddr) + ":" + tostring(iPort) + ", bDone = " + tostring(bDone));
  4169.     EServerType eServerType = (EServerType)iServerType;
  4170.     string sServerName = TruncateSpace(ToStringA(bstrAddr));
  4171.  
  4172.     if(sServerName.length() > 0 && iPort > 0){
  4173.         if(eServerType == eServerSRV)
  4174.         {
  4175.             SipAccount* sipAccnt = GetSelectedSipAccount();
  4176.             RET_ERROR_STR(sipAccnt);
  4177.  
  4178.             sipAccnt->m_SipSetting.m_sSrvDomain = sServerName;
  4179.             sipAccnt->m_pAgent->SetSrvDomain(0, sServerName);
  4180.  
  4181.             // Only one server can be set for SRV, hence clear its list
  4182.             m_lstNATTraversalServers[eServerSRV].clear();
  4183.         }
  4184.  
  4185.         m_lstNATTraversalServers[eServerType].insert(make_pair(sServerName, iPort));
  4186.     }
  4187.  
  4188.     if(Tobool(bDone) == false)
  4189.         return S_OK;
  4190.  
  4191.     map<EServerType, set<pair<string, int> > >::const_iterator iter = m_lstNATTraversalServers.find(eServerHttpProxy);
  4192.     if(iter != m_lstNATTraversalServers.end())
  4193.     {
  4194.         PAL_DB2("HTTP Proxy address: ", iter->second.begin()->first.c_str());
  4195.         PAL_DB2("HTTP Proxy port : ", iter->second.begin()->second);
  4196.  
  4197. #if (AF_DLL_VERSION > 9600000)
  4198.         m_pAFEngine->SetHTTPProxy(m_iAFEServerStoreID, CreateHost(eServerHttpProxy, AF_PROTOCOL_TCP),
  4199.             m_pAFEngine->GetHTTPProxyUsername(m_iAFEServerStoreID),
  4200.             m_pAFEngine->GetHTTPProxyPassword(m_iAFEServerStoreID),
  4201.             m_pAFEngine->GetHTTPProxyDomain(m_iAFEServerStoreID));
  4202. #else
  4203.         m_pAFEngine->SetHTTPProxy(CreateHost(eServerHttpProxy, AF_PROTOCOL_TCP),
  4204.             m_pAFEngine->GetHTTPProxyUsername(),
  4205.             m_pAFEngine->GetHTTPProxyPassword(),
  4206.             m_pAFEngine->GetHTTPProxyDomain());
  4207. #endif
  4208.     }
  4209.  
  4210.     string sStunServers = CreateHost(eServerStunUdp, AF_PROTOCOL_UDP) + CreateHost(eServerStunTcp, AF_PROTOCOL_TCP);
  4211.     string sTurnServers = CreateHost(eServerTurnUdp, AF_PROTOCOL_UDP) + CreateHost(eServerTurnTcp, AF_PROTOCOL_TCP);
  4212.  
  4213.     iter = m_lstNATTraversalServers.find(eServerSRV);
  4214.     if(iter != m_lstNATTraversalServers.end())
  4215.     {
  4216.         string sDomain = iter->second.begin()->first;
  4217.         if(sDomain.length() > 0){
  4218. #if (AF_DLL_VERSION > 950000)
  4219.             struct AfConnectionParams connParams;
  4220.             connParams.iRTO = 500;
  4221.             connParams.iRc = 1;
  4222.             connParams.iRm = 16;
  4223.             connParams.iTi = 3000;
  4224. #endif
  4225.  
  4226.             sStunServers += m_pAFEngine->CreateHost(AF_HOST_DNS_SRV, "_stun._udp." + sDomain, 0, AF_PROTOCOL_UDP
  4227. #if (AF_DLL_VERSION > 950000)      
  4228.                 , &connParams
  4229. #endif 
  4230.                 );
  4231.  
  4232.             sStunServers += m_pAFEngine->CreateHost(AF_HOST_DNS_SRV, "_stun._tcp." + sDomain, 0, AF_PROTOCOL_TCP
  4233. #if (AF_DLL_VERSION > 950000)      
  4234.                 , &connParams
  4235. #endif 
  4236.                 );
  4237.  
  4238.             sTurnServers += m_pAFEngine->CreateHost(AF_HOST_DNS_SRV, "_turn._udp." + sDomain, 0, AF_PROTOCOL_UDP
  4239. #if (AF_DLL_VERSION > 950000)      
  4240.                 , &connParams
  4241. #endif 
  4242.                 );     
  4243.  
  4244.             sTurnServers += m_pAFEngine->CreateHost(AF_HOST_DNS_SRV, "_turn._tcp." + sDomain, 0, AF_PROTOCOL_TCP
  4245. #if (AF_DLL_VERSION > 950000)      
  4246.                 , &connParams
  4247. #endif 
  4248.                 );     
  4249.         }
  4250.     }
  4251.  
  4252.     m_pAFEngine->SetSTUNServer(
  4253. #if (AF_DLL_VERSION > 9600000)
  4254.         m_iAFEServerStoreID,
  4255. #endif
  4256.         sStunServers);
  4257.  
  4258.     m_pAFEngine->SetTURNServer(
  4259. #if (AF_DLL_VERSION > 9600000)
  4260.         m_iAFEServerStoreID,
  4261. #endif
  4262.         sTurnServers);
  4263.  
  4264. #if (AF_DLL_VERSION > 950000)
  4265.         AfFirewallDetectionParams param;
  4266.         param.iDetectUdpConnectivity = 1;
  4267.         param.iDetectTcpConnectivity = 1;
  4268.         param.iDetectProxyConnectivity = 1;
  4269.         param.iDetectUPnPConnectivity = 1;
  4270.         param.iCheckTurnCredentials = 0;
  4271.         param.iUPnPDeviceDiscoveryTimeout = 500;
  4272.         m_pAFEngine->DetectConnectivity(
  4273. #if (AF_DLL_VERSION > 9600000)
  4274.             m_iAFEServerStoreID,
  4275. #endif
  4276.             /*NULL*/&param);
  4277. #else  
  4278.         m_pAFEngine->DetectConnectivity();
  4279. #endif
  4280.    
  4281.     m_pFramework->Log("DetectConnectivity called");
  4282.     return S_OK;
  4283. }
  4284.  
  4285. STDMETHODIMP CSessionControl::GetStunServerAddr(int iIndex, BSTR* pVal)
  4286. {
  4287.     string sNewStunServers;
  4288.     string sStunServers = m_pAFEngine->GetSTUNServer(
  4289. #if (AF_DLL_VERSION > 9600000)
  4290.         m_iAFEServerStoreID
  4291. #endif
  4292.         );
  4293.     int iNumServers = m_pAFEngine->GetHostListSize(sStunServers);
  4294.     int iNumUdpServers = 0;
  4295.     for (int i = 0; i < iNumServers; i++)
  4296.     {
  4297.         string sHost = m_pAFEngine->GetHostFromList(sStunServers, i);
  4298.         if (m_pAFEngine->GetHostProtocol(sHost) == AF_PROTOCOL_UDP)
  4299.         {
  4300.             sNewStunServers += sHost;
  4301.             iNumUdpServers++;
  4302.         }
  4303.     }
  4304.  
  4305.     int nMapIndex = 0;
  4306.     string sAddr;
  4307.     if (iNumUdpServers > 0)
  4308.     {
  4309.         nMapIndex = (iIndex % iNumUdpServers);
  4310.         string sHost = m_pAFEngine->GetHostFromList(sNewStunServers, nMapIndex);
  4311.         string sAddr = m_pAFEngine->GetHostAddress(sHost);
  4312.     }
  4313.  
  4314.     BstrFromString(pVal, sAddr);
  4315.     return S_OK;
  4316. }
  4317.  
  4318. STDMETHODIMP CSessionControl::GetStunServerPort(int iIndex, int* pVal)
  4319. {
  4320.     string sNewStunServers;
  4321.     string sStunServers = m_pAFEngine->GetSTUNServer(
  4322. #if (AF_DLL_VERSION > 9600000)
  4323.         m_iAFEServerStoreID
  4324. #endif
  4325.         );
  4326.     int iNumServers = m_pAFEngine->GetHostListSize(sStunServers);
  4327.     int iNumUdpServers = 0;
  4328.     for (int i = 0; i < iNumServers; i++)
  4329.     {
  4330.         string sHost = m_pAFEngine->GetHostFromList(sStunServers, i);
  4331.         if (m_pAFEngine->GetHostProtocol(sHost) == AF_PROTOCOL_UDP)
  4332.         {
  4333.             sNewStunServers += sHost;
  4334.             iNumUdpServers++;
  4335.         }
  4336.     }
  4337.  
  4338.     int nMapIndex = 0;
  4339.     int nPort = 0;
  4340.     if (iNumUdpServers > 0)
  4341.     {
  4342.         nMapIndex = (iIndex % iNumUdpServers);
  4343.         string sHost = m_pAFEngine->GetHostFromList(sNewStunServers, nMapIndex);
  4344.         nPort        = m_pAFEngine->GetHostPort(sHost);
  4345.     }
  4346.  
  4347.     *pVal = nPort;
  4348.     return S_OK;
  4349. }
  4350.  
  4351. STDMETHODIMP CSessionControl::GetHttpProxyAddr(BSTR* pVal)
  4352. {
  4353.     string sProxy = m_pAFEngine->GetHTTPProxy(
  4354. #if (AF_DLL_VERSION > 9600000)
  4355.         m_iAFEServerStoreID
  4356. #endif
  4357.         );
  4358.     string sAddr  = m_pAFEngine->GetHostAddress(sProxy);
  4359.     BstrFromString(pVal, sAddr);
  4360.     return S_OK;
  4361. }
  4362.  
  4363. STDMETHODIMP CSessionControl::GetHttpProxyPort(int* pVal)
  4364. {
  4365.     string sProxy = m_pAFEngine->GetHTTPProxy(
  4366. #if (AF_DLL_VERSION > 9600000)
  4367.         m_iAFEServerStoreID
  4368. #endif
  4369.         );
  4370.     int nPort     = m_pAFEngine->GetHostPort(sProxy);
  4371.     *pVal         = nPort;
  4372.     return S_OK;
  4373. }
  4374.  
  4375. STDMETHODIMP CSessionControl::SetHttpProxyAuthentication(BSTR bstrUserName, BSTR bstrPassword, BSTR bstrDomain)
  4376. {
  4377.     string sUserName = TruncateSpace(ToStringA(bstrUserName));
  4378.     string sPassword = TruncateSpace(ToStringA(bstrPassword));
  4379.     string sDomain = TruncateSpace(ToStringA(bstrDomain));
  4380.  
  4381.     m_pAFEngine->SetHTTPProxy(
  4382. #if (AF_DLL_VERSION > 9600000)
  4383.         m_iAFEServerStoreID,
  4384. #endif
  4385.         m_pAFEngine->GetHTTPProxy(
  4386. #if (AF_DLL_VERSION > 9600000)
  4387.         m_iAFEServerStoreID
  4388. #endif
  4389.         ),
  4390.         sUserName, sPassword, sDomain);
  4391.  
  4392.     return S_OK;
  4393. }
  4394.  
  4395. STDMETHODIMP CSessionControl::GetHttpProxyUserName(BSTR* pVal)
  4396. {
  4397.     string s = m_pAFEngine->GetHTTPProxyUsername(
  4398. #if (AF_DLL_VERSION > 9600000)
  4399.         m_iAFEServerStoreID
  4400. #endif
  4401.         );
  4402.     BstrFromString(pVal, s);
  4403.     return S_OK;
  4404. }
  4405.  
  4406. STDMETHODIMP CSessionControl::GetHttpProxyPassword(BSTR* pVal)
  4407. {
  4408.     string s = m_pAFEngine->GetHTTPProxyPassword(
  4409. #if (AF_DLL_VERSION > 9600000)
  4410.         m_iAFEServerStoreID
  4411. #endif
  4412.         );
  4413.     BstrFromString(pVal, s);
  4414.     return S_OK;
  4415. }
  4416.  
  4417. STDMETHODIMP CSessionControl::GetHttpProxyDomain(BSTR* pVal)
  4418. {
  4419.     string s = m_pAFEngine->GetHTTPProxyDomain(
  4420. #if (AF_DLL_VERSION > 9600000)
  4421.         m_iAFEServerStoreID
  4422. #endif
  4423.         );
  4424.     BstrFromString(pVal, s);
  4425.     return S_OK;
  4426. }
  4427.  
  4428.  
  4429. #if 0
  4430. STDMETHODIMP CSessionControl::DetectFirewall()
  4431. {
  4432.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4433.  
  4434.     RET_ERROR_STR(sipAccnt);
  4435.  
  4436.     sipAccnt->m_pAgent->StartConnectToSIPServer();
  4437.  
  4438.     return S_OK;
  4439. }
  4440. #endif
  4441.  
  4442. bool CSessionControl::CheckCallURI(const string& sURI, SipAccount* sipAccnt)
  4443. {
  4444.     //SipAccount* sipAccnt = GetSelectedSipAccount();
  4445.  
  4446.     if (sipAccnt == NULL)
  4447.         return false;
  4448.    
  4449.     if (sURI.empty())
  4450.         return false;
  4451.  
  4452.     if (sURI.length() > MAX_SIP_URI_LENGTH)
  4453.         return false;  // maximum length exceeded
  4454.  
  4455.     if (!AreURICharactersValid(sURI))
  4456.         return false;
  4457.  
  4458.     int iPos = sURI.find("@");
  4459.  
  4460.     // the first char is "@"
  4461.     if (iPos == 0)
  4462.         return false;
  4463.  
  4464.     // the last char is "@"
  4465.     if (iPos == sURI.size() - 1)
  4466.         return false;
  4467.  
  4468.  
  4469.     if (iPos == string::npos)
  4470.     {
  4471.         if (sURI == sipAccnt->m_pAgent->GetDisplayName())
  4472.             return false;
  4473.  
  4474.         if (sURI == sipAccnt->m_pAgent->GetUsername())
  4475.             return false;
  4476.     }
  4477.     else
  4478.     {
  4479.         string sContact = sipAccnt->m_pAgent->GetUsername();
  4480.         sContact += "@";
  4481.         sContact += sipAccnt->m_pAgent->GetProxyName();
  4482.  
  4483.         if (sContact == sURI)
  4484.             return false;
  4485.     }
  4486.  
  4487.     return true;
  4488. }
  4489.  
  4490. STDMETHODIMP CSessionControl::get_Framerate(int *pVal)
  4491. {
  4492. #ifndef __NOVIDEO__
  4493.     CHECK_POINTER(pVal);
  4494.     CHECK_MEDIAFRAMEWORK();
  4495.  
  4496.     m_pFramework->m_mediaFramework->get_FrameRate(pVal);
  4497. #endif
  4498.     return S_OK;
  4499. }
  4500.  
  4501. STDMETHODIMP CSessionControl::put_Framerate(int newVal)
  4502. {
  4503. #ifndef __NOVIDEO__
  4504.     CHECK_MEDIAFRAMEWORK();
  4505.    
  4506.     if (newVal < 0 || newVal > 30)
  4507.         return ThrowError("ERROR: Framerate out of range.");
  4508.  
  4509.     m_pFramework->m_mediaFramework->put_FrameRate(newVal);
  4510. #endif
  4511.     return S_OK;
  4512. }
  4513.  
  4514.  
  4515. STDMETHODIMP CSessionControl::SetOutboundProxy(BSTR bstrProxyServer, int iProxyPort)
  4516. {
  4517.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4518.  
  4519.     RET_ERROR_STR(sipAccnt);
  4520.  
  4521.     sipAccnt->m_pAgent->SetOutboundProxy(ToStringA(bstrProxyServer), iProxyPort);
  4522.     return S_OK;
  4523. }
  4524.  
  4525. STDMETHODIMP CSessionControl::EnableRegistration(int iIndex, VARIANT_BOOL bEnable)
  4526. {
  4527.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4528.  
  4529.     RET_ERROR_STR(sipAccnt);
  4530.  
  4531.     sipAccnt->m_pAgent->EnableRegistration(iIndex, Tobool(bEnable));
  4532.     return S_OK;
  4533. }
  4534.  
  4535. #ifdef USE_VARIANT_IN_EVENT
  4536. STDMETHODIMP CSessionControl::GetVideoCaptureDeviceName(SAFEARRAY **pVal)
  4537. #else
  4538. STDMETHODIMP CSessionControl::GetVideoCaptureDeviceName(std::vector<std::string> *pVal)
  4539. #endif
  4540. {
  4541.     CHECK_MEDIAFRAMEWORK();
  4542.     CHECK_POINTER(pVal);
  4543.  
  4544.     m_pFramework->m_mediaFramework->GetVideoCaptureDeviceName(pVal);
  4545.     return S_OK;
  4546. }
  4547.  
  4548. #ifdef USE_VARIANT_IN_EVENT
  4549. STDMETHODIMP CSessionControl::GetAudioCaptureDeviceName(SAFEARRAY **pVal)
  4550. #else
  4551. STDMETHODIMP CSessionControl::GetAudioCaptureDeviceName(std::vector<std::string> *pVal)
  4552. #endif
  4553. {
  4554.     CHECK_MEDIAFRAMEWORK();
  4555.     CHECK_POINTER(pVal);
  4556.  
  4557.     m_pFramework->m_mediaFramework->GetAudioCaptureDeviceName(pVal);
  4558.     return S_OK;
  4559. }
  4560.  
  4561. #ifdef USE_VARIANT_IN_EVENT
  4562. STDMETHODIMP CSessionControl::GetVideoCaptureInputName(SAFEARRAY **pVal)
  4563. #else
  4564. STDMETHODIMP CSessionControl::GetVideoCaptureInputName(std::vector<std::string> *pVal)
  4565. #endif
  4566. {
  4567.     CHECK_MEDIAFRAMEWORK();
  4568.     CHECK_POINTER(pVal);
  4569.  
  4570.     m_pFramework->m_mediaFramework->GetVideoCaptureInputName(pVal);
  4571.     return S_OK;
  4572. }
  4573.  
  4574. STDMETHODIMP CSessionControl::SetVideoSource()
  4575. {
  4576. #ifndef __unix__
  4577.     CHECK_MEDIAFRAMEWORK();
  4578.  
  4579.     m_pFramework->m_mediaFramework->SetVideoSource();
  4580. #endif
  4581.     return S_OK;
  4582. }
  4583.  
  4584. #ifdef USE_VARIANT_IN_EVENT
  4585. STDMETHODIMP CSessionControl::GetAudioPlaybackDeviceName(SAFEARRAY **pVal)
  4586. #else
  4587. STDMETHODIMP CSessionControl::GetAudioPlaybackDeviceName(std::vector<std::string> *pVal)
  4588. #endif
  4589. {
  4590.     CHECK_MEDIAFRAMEWORK();
  4591.     CHECK_POINTER(pVal);
  4592.  
  4593.     m_pFramework->m_mediaFramework->GetAudioPlaybackDeviceName(pVal);
  4594.     return S_OK;
  4595. }
  4596.  
  4597. STDMETHODIMP CSessionControl::HasCamera(VARIANT_BOOL *pVal)
  4598. {
  4599.     CHECK_MEDIAFRAMEWORK();
  4600.     CHECK_POINTER(pVal);
  4601.  
  4602.     m_pFramework->m_mediaFramework->HasCamera(pVal);
  4603.     return S_OK;
  4604. }
  4605.  
  4606. STDMETHODIMP CSessionControl::HasMicrophone(VARIANT_BOOL *pVal)
  4607. {
  4608.     CHECK_MEDIAFRAMEWORK();
  4609.     CHECK_POINTER(pVal);
  4610.  
  4611.     m_pFramework->m_mediaFramework->HasMicrophone(pVal);
  4612.     return S_OK;
  4613. }
  4614.  
  4615. #if defined(__unix__) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  4616. STDMETHODIMP CSessionControl::SetCamera(const std::string &sCamera)
  4617. {
  4618. #ifndef __NOVIDEO__
  4619.     CHECK_MEDIAFRAMEWORK();
  4620.  
  4621.         string _sCamera = tolower(sCamera);
  4622.         if(_sCamera != "front" && _sCamera != "back")
  4623.             return ThrowError("ERROR: Invalid camera");
  4624.  
  4625.     m_pFramework->m_mediaFramework->SetCamera(_sCamera);
  4626. #endif
  4627.     return S_OK;
  4628. }
  4629.  
  4630. STDMETHODIMP CSessionControl::ChangeCameraParameters(int nFrameRate, int nBitRate, int nKeyFrameInterval, int nRotateAngle)
  4631. {
  4632. #ifndef __NOVIDEO__
  4633.     CHECK_MEDIAFRAMEWORK();
  4634.    
  4635.     m_pFramework->m_mediaFramework->ChangeCameraParameters(nFrameRate, nBitRate, nKeyFrameInterval, nRotateAngle);
  4636. #endif
  4637.     return S_OK;
  4638. }
  4639. #endif
  4640.  
  4641. STDMETHODIMP CSessionControl::get_VideoCaptureDevice(int *pVal)
  4642. {
  4643.     CHECK_MEDIAFRAMEWORK();
  4644.     CHECK_POINTER(pVal);
  4645.  
  4646.     m_pFramework->m_mediaFramework->get_VideoCaptureDevice(pVal);
  4647.     return S_OK;
  4648. }
  4649.  
  4650. STDMETHODIMP CSessionControl::put_VideoCaptureDevice(int newVal)
  4651. {
  4652.     CHECK_MEDIAFRAMEWORK();
  4653.  
  4654.     m_pFramework->m_mediaFramework->put_VideoCaptureDevice(newVal);
  4655.     return S_OK;
  4656. }
  4657.  
  4658. STDMETHODIMP CSessionControl::get_VideoCaptureInput(int *pVal)
  4659. {
  4660.     CHECK_MEDIAFRAMEWORK();
  4661.     CHECK_POINTER(pVal);
  4662.  
  4663.     m_pFramework->m_mediaFramework->get_VideoCaptureInput(pVal);
  4664.     return S_OK;
  4665. }
  4666.  
  4667. STDMETHODIMP CSessionControl::put_VideoCaptureInput(int newVal)
  4668. {
  4669.     CHECK_MEDIAFRAMEWORK();
  4670.  
  4671.     m_pFramework->m_mediaFramework->put_VideoCaptureInput(newVal);
  4672.     return S_OK;
  4673. }
  4674.  
  4675. STDMETHODIMP CSessionControl::get_AudioCaptureDevice(int *pVal)
  4676. {
  4677.     CHECK_MEDIAFRAMEWORK();
  4678.     CHECK_POINTER(pVal);
  4679.  
  4680.     m_pFramework->m_mediaFramework->get_AudioCaptureDevice(pVal);
  4681.     return S_OK;
  4682. }
  4683.  
  4684. STDMETHODIMP CSessionControl::put_AudioCaptureDevice(int newVal)
  4685. {
  4686.     CHECK_MEDIAFRAMEWORK();
  4687.     m_pFramework->m_mediaFramework->put_AudioCaptureDevice(newVal);
  4688.     return S_OK;
  4689. }
  4690.  
  4691. STDMETHODIMP CSessionControl::get_AudioPlaybackDevice(int *pVal)
  4692. {
  4693.     CHECK_MEDIAFRAMEWORK();
  4694.     CHECK_POINTER(pVal);
  4695.  
  4696.     m_pFramework->m_mediaFramework->get_AudioPlaybackDevice(pVal);
  4697.     return S_OK;
  4698. }
  4699.  
  4700. STDMETHODIMP CSessionControl::put_AudioPlaybackDevice(int newVal)
  4701. {
  4702.     CHECK_MEDIAFRAMEWORK();
  4703.     m_pFramework->m_mediaFramework->put_AudioPlaybackDevice(newVal);
  4704.     return S_OK;
  4705. }
  4706.  
  4707. STDMETHODIMP CSessionControl::get_MicrophoneVolume(int *pVal)
  4708. {
  4709.     CHECK_MEDIAFRAMEWORK();
  4710.     CHECK_POINTER(pVal);
  4711.  
  4712.     m_pFramework->m_mediaFramework->get_MicrophoneVolume(pVal);
  4713.     return S_OK;
  4714. }
  4715.  
  4716. STDMETHODIMP CSessionControl::put_MicrophoneVolume(int newVal)
  4717. {
  4718.     CHECK_MEDIAFRAMEWORK();
  4719.     m_pFramework->m_mediaFramework->put_MicrophoneVolume(newVal);
  4720.     return S_OK;
  4721. }
  4722.  
  4723. STDMETHODIMP CSessionControl::get_WaveVolume(int *pVal)
  4724. {
  4725.     CHECK_MEDIAFRAMEWORK();
  4726.     CHECK_POINTER(pVal);
  4727.  
  4728.     string sTargetID = m_pCallLine->GetTargetID();
  4729.     m_pFramework->m_mediaFramework->get_WaveVolume(ToMFExportString(sTargetID), pVal);
  4730.     return S_OK;
  4731. }
  4732.  
  4733. STDMETHODIMP CSessionControl::put_WaveVolume(int newVal)
  4734. {
  4735.     CHECK_MEDIAFRAMEWORK();
  4736.     string sTargetID = m_pCallLine->GetTargetID();
  4737.     m_pFramework->m_mediaFramework->put_WaveVolume(ToMFExportString(sTargetID), newVal);
  4738.     m_pCallLine->SaveWaveVolume(newVal);
  4739.     return S_OK;
  4740. }
  4741.  
  4742.  
  4743. STDMETHODIMP CSessionControl::get_LineVolume(int *pVal)
  4744. {
  4745.     CHECK_MEDIAFRAMEWORK();
  4746.     CHECK_POINTER(pVal);
  4747.  
  4748.     string sTargetID = m_pCallLine->GetTargetID();
  4749.  
  4750.     m_pFramework->m_mediaFramework->get_LineVolume(ToMFExportString(sTargetID), pVal);
  4751.     return S_OK;
  4752. }
  4753.  
  4754. STDMETHODIMP CSessionControl::put_LineVolume(int newVal)
  4755. {
  4756.     CHECK_MEDIAFRAMEWORK();
  4757.     string sTargetID = m_pCallLine->GetTargetID();
  4758.  
  4759.     m_pFramework->m_mediaFramework->put_LineVolume(ToMFExportString(sTargetID), newVal);
  4760.     return S_OK;
  4761. }
  4762.  
  4763. #ifdef USE_VARIANT_IN_EVENT
  4764. STDMETHODIMP CSessionControl::GetVideoSenderStat(SAFEARRAY **pVal)
  4765. #else
  4766. STDMETHODIMP CSessionControl::GetVideoSenderStat(std::vector<std::string> *pVal)
  4767. #endif
  4768. {
  4769.     CHECK_MEDIAFRAMEWORK();
  4770.     CHECK_POINTER(pVal);
  4771.     string sTargetID = m_pCallLine->GetTargetID();
  4772.     if (sTargetID.empty())
  4773.         return ThrowError("ERROR: Not in session.");
  4774.  
  4775.     return m_pFramework->m_mediaFramework->GetVideoSenderStat(pVal);
  4776. }
  4777.  
  4778. #ifdef USE_VARIANT_IN_EVENT
  4779. STDMETHODIMP CSessionControl::GetVideoReceiverStat(SAFEARRAY **pVal)
  4780. #else
  4781. STDMETHODIMP CSessionControl::GetVideoReceiverStat(std::vector<std::string> *pVal)
  4782. #endif
  4783. {
  4784.     CHECK_MEDIAFRAMEWORK();
  4785.     CHECK_POINTER(pVal);
  4786.     string sTargetID = m_pCallLine->GetTargetID();
  4787.     if (sTargetID.empty())
  4788.         return ThrowError("ERROR: Not in session.");
  4789.  
  4790.     return m_pFramework->m_mediaFramework->GetVideoReceiverStat(ToMFExportString(sTargetID), pVal);
  4791. }
  4792.  
  4793. #ifdef USE_VARIANT_IN_EVENT
  4794. STDMETHODIMP CSessionControl::GetAudioSenderStat(SAFEARRAY **pVal)
  4795. #else
  4796. STDMETHODIMP CSessionControl::GetAudioSenderStat(std::vector<std::string> *pVal)
  4797. #endif
  4798. {
  4799.     CHECK_MEDIAFRAMEWORK();
  4800.     CHECK_POINTER(pVal);
  4801.  
  4802.     string sTargetID = m_pCallLine->GetTargetID();
  4803.     if (sTargetID.empty())
  4804.         return ThrowError("ERROR: Not in session.");
  4805.  
  4806.     return m_pFramework->m_mediaFramework->GetAudioSenderStat(ToMFExportString(sTargetID), pVal);
  4807. }
  4808.  
  4809. #ifdef USE_VARIANT_IN_EVENT
  4810. STDMETHODIMP CSessionControl::GetAudioReceiverStat(SAFEARRAY **pVal)
  4811. #else
  4812. STDMETHODIMP CSessionControl::GetAudioReceiverStat(std::vector<std::string> *pVal)
  4813. #endif
  4814. {
  4815.     CHECK_MEDIAFRAMEWORK();
  4816.     CHECK_POINTER(pVal);
  4817.     string sTargetID = m_pCallLine->GetTargetID();
  4818.     if (sTargetID.empty())
  4819.         return ThrowError("ERROR: Not in session.");
  4820.  
  4821.     return m_pFramework->m_mediaFramework->GetAudioReceiverStat(ToMFExportString(sTargetID), pVal);
  4822. }
  4823.  
  4824. STDMETHODIMP CSessionControl::get_PauseSender(VARIANT_BOOL *pVal)
  4825. {
  4826.     CHECK_MEDIAFRAMEWORK();
  4827.     CHECK_POINTER(pVal);
  4828.  
  4829.     m_pFramework->m_mediaFramework->get_Pause(pVal);
  4830.     return S_OK;
  4831. }
  4832.  
  4833. STDMETHODIMP CSessionControl::put_PauseSender(VARIANT_BOOL newVal)
  4834. {
  4835.     CHECK_MEDIAFRAMEWORK();
  4836.     m_pFramework->m_mediaFramework->put_Pause(newVal);
  4837.     return S_OK;
  4838. }
  4839.  
  4840. STDMETHODIMP CSessionControl::get_PauseReceiver(VARIANT_BOOL *pVal)
  4841. {
  4842.     CHECK_MEDIAFRAMEWORK();
  4843.     CHECK_POINTER(pVal);
  4844.  
  4845.     string sTargetID = m_pCallLine->GetTargetID();
  4846.     if (sTargetID.empty())
  4847.         return S_OK;
  4848.     *pVal = ToVB(m_pCallLine->IsLinePaused());
  4849.     return S_OK;
  4850. }
  4851.  
  4852. STDMETHODIMP CSessionControl::put_PauseReceiver(VARIANT_BOOL newVal)
  4853. {
  4854.     string sTargetID = m_pCallLine->GetTargetID();
  4855.     if (sTargetID.empty())
  4856.         return S_OK;
  4857.  
  4858.     m_pCallLine->PauseLine(Tobool(newVal));
  4859.     return S_OK;
  4860. }
  4861.  
  4862. STDMETHODIMP CSessionControl::get_MuteReceiver(VARIANT_BOOL *pVal)
  4863. {
  4864.     CHECK_MEDIAFRAMEWORK();
  4865.     CHECK_POINTER(pVal);
  4866.     string sTargetID = m_pCallLine->GetTargetID();
  4867.     if (sTargetID.empty())
  4868.         return S_OK;
  4869.     m_pFramework->m_mediaFramework->get_MuteClient(ToMFExportString(sTargetID), pVal);
  4870.  
  4871.     return S_OK;
  4872. }
  4873.  
  4874. STDMETHODIMP CSessionControl::put_MuteReceiver(VARIANT_BOOL newVal)
  4875. {
  4876.     CHECK_MEDIAFRAMEWORK();
  4877.     string sTargetID = m_pCallLine->GetTargetID();
  4878.     if (sTargetID.empty())
  4879.         return S_OK;
  4880.  
  4881.     return m_pFramework->m_mediaFramework->put_MuteClient(ToMFExportString(sTargetID), ToBOOL(newVal));
  4882. }
  4883.  
  4884. STDMETHODIMP CSessionControl::ResetVideoSenderStat()
  4885. {
  4886.     CHECK_MEDIAFRAMEWORK();
  4887.     m_pFramework->m_mediaFramework->ResetVideoSenderStat();
  4888.     return S_OK;
  4889. }
  4890.  
  4891. STDMETHODIMP CSessionControl::ResetAudioSenderStat()
  4892. {
  4893.     CHECK_MEDIAFRAMEWORK();
  4894.     m_pFramework->m_mediaFramework->ResetAudioSenderStat();
  4895.     return S_OK;
  4896. }
  4897.  
  4898. STDMETHODIMP CSessionControl::ResetVideoReceiverStat()
  4899. {
  4900.     CHECK_MEDIAFRAMEWORK();
  4901.     string sTargetID = m_pCallLine->GetTargetID();
  4902.     if (sTargetID.empty())
  4903.         return ThrowError("ERROR: Not in session.");
  4904.     m_pFramework->m_mediaFramework->ResetVideoReceiverStat(ToMFExportString(sTargetID));
  4905.     return S_OK;
  4906. }
  4907.  
  4908. STDMETHODIMP CSessionControl::ResetAudioReceiverStat()
  4909. {
  4910.     CHECK_MEDIAFRAMEWORK();
  4911.     string sTargetID = m_pCallLine->GetTargetID();
  4912.     if (sTargetID.empty())
  4913.         return ThrowError("ERROR: Not in session.");
  4914.     m_pFramework->m_mediaFramework->ResetAudioReceiverStat(ToMFExportString(sTargetID));
  4915.     return S_OK;
  4916. }
  4917.  
  4918. STDMETHODIMP CSessionControl::get_VideoCodecs(BSTR *pVal)
  4919. {
  4920.     CHECK_POINTER(pVal);
  4921.     BstrFromString(pVal, m_pCodecConfig->GetVideoCodecs());
  4922.     return S_OK;
  4923. }
  4924.  
  4925. STDMETHODIMP CSessionControl::put_VideoCodecs(BSTR newVal)
  4926. {  
  4927. #ifdef USE_MJPEG
  4928.     return S_OK;
  4929. #endif
  4930.     string sOldCodecs = m_pCodecConfig->GetVideoCodecs();
  4931.     string sNewCodecs = ToStringA(newVal);
  4932.     if (_stricmp(sOldCodecs.c_str(), sNewCodecs.c_str()) == 0) {
  4933.          return S_OK;
  4934.     }
  4935.  
  4936.     m_pFramework->Log("Set Video Codec = " + (sNewCodecs.empty() ? "\"\"" : sNewCodecs));
  4937.  
  4938.     m_pCodecConfig->SetVideoCodecs(sNewCodecs);
  4939.     if (!m_pCallLine->IsAllLineIdle())
  4940.     {
  4941.         m_pFramework->Log("Changing video codec in call");
  4942.  
  4943.         CallDialog* p = m_pCallLine->GetSelectedDialog();
  4944.         if (!p)
  4945.         {
  4946.             return ThrowError("ERROR: put_VideoCodecs::Invalid Line");
  4947.         }
  4948.  
  4949.         SipAccount* sipAccnt = GetSipAccount(p->m_iAcct);
  4950.  
  4951.         RET_ERROR_STR(sipAccnt);
  4952.         if (!sipAccnt->m_pAgent->ChangeMedia(false))
  4953.             return E_FAIL; //S_OK;
  4954.     }
  4955.  
  4956.     return S_OK;
  4957. }
  4958.  
  4959. STDMETHODIMP CSessionControl::get_AudioCodecs(BSTR *pVal)
  4960. {
  4961.     CHECK_POINTER(pVal);
  4962.     BstrFromString(pVal, m_pCodecConfig->GetAudioCodecs());
  4963.     return S_OK;
  4964. }
  4965.  
  4966. STDMETHODIMP CSessionControl::put_AudioCodecs(BSTR newVal)
  4967. {
  4968.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4969.  
  4970.     RET_ERROR_STR(sipAccnt);
  4971.     string sOldCodecs = m_pCodecConfig->GetAudioCodecs();
  4972.     string sNewCodecs = ToStringA(newVal);
  4973.     if (_stricmp(sOldCodecs.c_str(), sNewCodecs.c_str()) == 0) {
  4974.          return S_OK;
  4975.     }
  4976.  
  4977.     m_pFramework->Log("Set Audio Codec = " + (sNewCodecs.empty() ? "\"\"" : sNewCodecs));
  4978.  
  4979.     m_pCodecConfig->SetAudioCodecs(sNewCodecs);
  4980.     if (!m_pCallLine->IsAllLineIdle())
  4981.     {
  4982.         m_pFramework->Log("Changing audio codec in call");
  4983.         if (!sipAccnt->m_pAgent->ChangeMedia(true))
  4984.             return E_FAIL;  //ThrowError("ERROR: Invalid call state.");
  4985.     }
  4986.     return S_OK;
  4987. }
  4988.  
  4989. STDMETHODIMP CSessionControl::get_RegistrationExpire(int *pVal)
  4990. {
  4991.     SipAccount* sipAccnt = GetSelectedSipAccount();
  4992.  
  4993.     RET_ERROR_STR(sipAccnt);
  4994.  
  4995.     CHECK_POINTER(pVal);
  4996.     *pVal = sipAccnt->m_pAgent->GetRegistrationExpire();
  4997.     return S_OK;
  4998. }
  4999.  
  5000. STDMETHODIMP CSessionControl::put_RegistrationExpire(int newVal)
  5001. {
  5002.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5003.  
  5004.     RET_ERROR_STR(sipAccnt);
  5005.  
  5006.     if (newVal <= 10)
  5007.         return ThrowError("ERROR: Invalid expiration value.");
  5008.     sipAccnt->m_pAgent->SetRegistrationExpire(newVal);
  5009.  
  5010.     if (sipAccnt->m_iRegistrationRefreshTimer)
  5011.     {
  5012.         SetRegistrationRefreshTimer(m_iSelectedAccount);
  5013.     }
  5014.  
  5015.     return S_OK;
  5016. }
  5017.  
  5018. STDMETHODIMP CSessionControl::get_SignalPort(int *pVal)
  5019. {
  5020.     return ThrowError("ERROR: not supported by AFE");
  5021. }
  5022.  
  5023. STDMETHODIMP CSessionControl::put_SignalPort(int newVal)
  5024. {
  5025.     return ThrowError("ERROR: not supported by AFE");
  5026. }
  5027.  
  5028. STDMETHODIMP CSessionControl::get_AudioRtpPort(int *pVal)
  5029. {
  5030.     CHECK_POINTER(pVal);
  5031.     // get the port from selected dialog. We need AFE support.
  5032.     *pVal = 0;
  5033.     return S_OK;
  5034. }
  5035.  
  5036. STDMETHODIMP CSessionControl::put_AudioRtpPort(int newVal)
  5037. {
  5038.     // put the port to selected dialog. We need AFE support.
  5039.     return S_OK;
  5040. }
  5041.  
  5042. STDMETHODIMP CSessionControl::get_AudioRtcpPort(int *pVal)
  5043. {
  5044.     CHECK_POINTER(pVal);
  5045.     // get the port from selected dialog. We need AFE support.
  5046.     *pVal = 0;
  5047.     return S_OK;
  5048. }
  5049.  
  5050. STDMETHODIMP CSessionControl::put_AudioRtcpPort(int newVal)
  5051. {
  5052.     // put the port to selected dialog. We need AFE support.
  5053.     return S_OK;
  5054. }
  5055.  
  5056. STDMETHODIMP CSessionControl::get_VideoRtpPort(int *pVal)
  5057. {
  5058.     CHECK_POINTER(pVal);
  5059.     // get the port from selected dialog. We need AFE support.
  5060.     *pVal = 0;
  5061.     return S_OK;
  5062. }
  5063.  
  5064. STDMETHODIMP CSessionControl::put_VideoRtpPort(int newVal)
  5065. {
  5066.     // put the port to selected dialog. We need AFE support.
  5067.     return S_OK;
  5068. }
  5069.  
  5070. STDMETHODIMP CSessionControl::get_VideoRtcpPort(int *pVal)
  5071. {
  5072.     CHECK_POINTER(pVal);
  5073.     // get the port from selected dialog. We need AFE support.
  5074.     *pVal = 0;
  5075.     return S_OK;
  5076. }
  5077.  
  5078. STDMETHODIMP CSessionControl::put_VideoRtcpPort(int newVal)
  5079. {  
  5080.     // put the port to selected dialog. We need AFE support.
  5081.     return S_OK;
  5082. }
  5083.  
  5084. STDMETHODIMP CSessionControl::get_RegistrationPeriod(int *pVal)
  5085. {
  5086.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5087.  
  5088.     RET_ERROR_STR(sipAccnt);
  5089.  
  5090.     CHECK_POINTER(pVal);
  5091.     *pVal = sipAccnt->m_pAgent->GetRegistrationPeriod();
  5092.     return S_OK;
  5093. }
  5094.  
  5095. STDMETHODIMP CSessionControl::put_RegistrationPeriod(int newVal)
  5096. {
  5097.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5098.  
  5099.     RET_ERROR_STR(sipAccnt);
  5100.  
  5101.     if (newVal <= 0 || newVal >= sipAccnt->m_pAgent->GetRegistrationExpire())
  5102.         return ThrowError("ERROR: Invalid registration period.");
  5103.  
  5104.     sipAccnt->m_pAgent->SetRegistrationPeriod(newVal);
  5105.     if (sipAccnt->m_iRegistrationRefreshTimer)
  5106.     {
  5107.         SetRegistrationRefreshTimer(m_iSelectedAccount);
  5108.     }
  5109.     return S_OK;
  5110. }
  5111.  
  5112. STDMETHODIMP CSessionControl::get_KeepAlivePeriod(int *pVal)
  5113. {
  5114.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5115.  
  5116.     RET_ERROR_STR(sipAccnt);
  5117.  
  5118.     CHECK_POINTER(pVal);
  5119.     *pVal = sipAccnt->m_iSignalChannelKeepAlivePeriod;
  5120.     return S_OK;
  5121. }
  5122.  
  5123. STDMETHODIMP CSessionControl::put_KeepAlivePeriod(int newVal)
  5124. {
  5125.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5126.  
  5127.     RET_ERROR_STR(sipAccnt);
  5128.  
  5129.     if (newVal < 0)
  5130.         return ThrowError("ERROR: Invalid keep alive period.");
  5131.  
  5132.     m_pFramework->Log("Setting keep alive period to " + tostring(newVal));
  5133.  
  5134.     sipAccnt->m_iSignalChannelKeepAlivePeriod = newVal;
  5135.     if (!sipAccnt->m_pAgent->IsAllProxyIdle())
  5136.         SetSignalChannelKeepAliveTimer(m_iSelectedAccount);
  5137.     return S_OK;
  5138. }
  5139.  
  5140. void CSessionControl::SetUpdateConferenceListTimer()
  5141. {
  5142.     KILL_TIMER(m_iUpdateConferenceListTimer);
  5143.    
  5144.     m_iUpdateConferenceListTimer = SetTimer(UPDATE_CONF_LIST_TIMER_ID, 10000);
  5145.     m_pFramework->Log("SetUpdateConferenceListTimer.");    
  5146. }
  5147.  
  5148. //UPDATE_CONF_LIST_TIMER_ID
  5149.  
  5150. void CSessionControl::SetSignalChannelKeepAliveTimer(int iAccnt)
  5151. {
  5152.     SipAccount* sipAccnt = GetSipAccount(iAccnt);
  5153.  
  5154.     RET_IF_NULL(sipAccnt);
  5155.  
  5156.     KILL_TIMER(sipAccnt->m_iSignalChannelKeepAliveTimer);
  5157.    
  5158.     if(sipAccnt->m_iSignalChannelKeepAlivePeriod)
  5159.     {
  5160.         sipAccnt->m_iSignalChannelKeepAliveTimer = SetTimer(
  5161.             SIGNAL_CHANNEL_KEEP_ALIVE_TIMER_ID + GetAccountID(sipAccnt),
  5162.             sipAccnt->m_iSignalChannelKeepAlivePeriod * 1000);
  5163.         MSA_LOG("SipAccnt->SetSignalChannelKeepAliveTimer() = " + itoa(sipAccnt->m_iSignalChannelKeepAliveTimer));
  5164.     }
  5165.     else
  5166.     {
  5167.         MSA_LOG("sipAccnt->m_iSignalChannelKeepAlivePeriod = invalid.............");
  5168.     }
  5169. }
  5170.  
  5171. void CSessionControl::SetRegistrationRefreshTimer(int iAccnt)
  5172. {
  5173.     MSA_LOG("Setting Registration refresh timer for: " + itoa(iAccnt));
  5174.     SipAccount* sipAccnt = GetSipAccount(iAccnt);
  5175.  
  5176.     RET_IF_NULL(sipAccnt);
  5177.  
  5178.     KILL_TIMER(sipAccnt->m_iRegistrationRefreshTimer);
  5179.  
  5180.     sipAccnt->m_iRegistrationRefreshTimer = SetTimer(
  5181.         REGISTRATION_RFRESH_TIMER_ID + GetAccountID(sipAccnt),
  5182.         sipAccnt->m_pAgent->GetRegistrationPeriod() * 1000);
  5183.  
  5184.     MSA_LOG("timer id: " + itoa(REGISTRATION_RFRESH_TIMER_ID));
  5185.     MSA_LOG(" accnt timerid: " + itoa(sipAccnt->m_iRegistrationRefreshTimer));
  5186. }
  5187.  
  5188. #ifdef _SUPPORT_EVENT_PACKAGE
  5189. void CSessionControl::SetMWIRefreshTimer(int iAccnt)
  5190. {
  5191.     SipAccount* sipAccnt = GetSipAccount(iAccnt);
  5192.  
  5193.     RET_IF_NULL(sipAccnt);
  5194.  
  5195.     KILL_TIMER(sipAccnt->m_iMWIRefreshTimer);
  5196.     int iExpire = sipAccnt->m_pAgent->GetMWIExpire() - 10;//this param may be changed later.
  5197.     if(iExpire <10 )
  5198.         iExpire  = 10;
  5199.    
  5200.     PAL_DB2("In SetMWIRefreshTImer: iExpire is set to : ", iExpire);
  5201.  
  5202.     sipAccnt->m_iMWIRefreshTimer = SetTimer(
  5203.         MWI_RFRESH_TIMER_ID + GetAccountID(sipAccnt),
  5204.         iExpire *  1000);
  5205. }
  5206.  
  5207.  
  5208. #endif
  5209. ////////////////////// INTERNAL /////////////////////
  5210. void CSessionControl::SetRegistrationResponseTimer(int iAccnt)
  5211. {
  5212.     SipAccount* sipAccnt = GetSipAccount(iAccnt);
  5213.     RET_IF_NULL(sipAccnt);
  5214.     KILL_TIMER(sipAccnt->m_iRegistrationResponseTimer);
  5215.  
  5216. #ifdef _CUSTOM_TIMER_
  5217.     sipAccnt->m_iRegistrationResponseTimer = SetTimer(
  5218.         REGISTRATION_RESPONSE_TIMER_ID + GetAccountID(sipAccnt),
  5219.         CUSTOM_REGISTRATION_RESPONSE_TIMEOUT*1000);
  5220. #else
  5221.     sipAccnt->m_iRegistrationResponseTimer = SetTimer(
  5222.         REGISTRATION_RESPONSE_TIMER_ID + GetAccountID(sipAccnt),
  5223.         REGISTRATION_RESPONSE_TIMEOUT*1000);
  5224. #endif
  5225. }
  5226.  
  5227. STDMETHODIMP CSessionControl::RespondReinvite(int iLine)
  5228. {
  5229.     CallDialog* p = m_pCallLine->GetDialog(iLine);
  5230.     if (!p) {
  5231.         return ThrowError("ERROR: RespondReinvite::Invalid Line");
  5232.     }
  5233.  
  5234.     SipAccount* sipAccnt = GetSipAccount(p->m_iAcct);
  5235.  
  5236.     RET_ERROR_STR(sipAccnt);
  5237.  
  5238.     sipAccnt->m_pAgent->RespondReinvite(iLine);
  5239.     return S_OK;
  5240. }
  5241.  
  5242. STDMETHODIMP CSessionControl::IsRegistered(VARIANT_BOOL *pVal)
  5243. {
  5244.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5245.  
  5246.     RET_ERROR_STR(sipAccnt);
  5247.  
  5248.     CHECK_POINTER(pVal);
  5249.     *pVal = ToVB(sipAccnt->m_pAgent->IsRegistered());
  5250.     return S_OK;
  5251. }
  5252.  
  5253. STDMETHODIMP CSessionControl::get_EnableEchoCancellation(VARIANT_BOOL *pVal)
  5254. {
  5255.     CHECK_MEDIAFRAMEWORK();
  5256.     CHECK_POINTER(pVal);
  5257.    
  5258.     m_pFramework->m_mediaFramework->get_EnableEchoCancellation(pVal);
  5259.     return S_OK;
  5260. }
  5261.  
  5262. STDMETHODIMP CSessionControl::put_EnableEchoCancellation(VARIANT_BOOL newVal)
  5263. {
  5264.     CHECK_MEDIAFRAMEWORK();
  5265.     return m_pFramework->m_mediaFramework->put_EnableEchoCancellation(newVal);
  5266. }
  5267.  
  5268. STDMETHODIMP CSessionControl::get_QualityProfile(int *pVal)
  5269. {
  5270.     CHECK_MEDIAFRAMEWORK();
  5271.     CHECK_POINTER(pVal);
  5272.     m_pFramework->m_mediaFramework->get_QualityProfile(pVal);
  5273.     return S_OK;
  5274. }
  5275.  
  5276. STDMETHODIMP CSessionControl::put_QualityProfile(int newVal)
  5277. {
  5278.     CHECK_MEDIAFRAMEWORK();
  5279.     return m_pFramework->m_mediaFramework->put_QualityProfile(newVal);
  5280. }
  5281.  
  5282. STDMETHODIMP CSessionControl::get_EnableKeepAliveFailover(VARIANT_BOOL *pVal)
  5283. {
  5284.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5285.  
  5286.     RET_ERROR_STR(sipAccnt);
  5287.  
  5288.  
  5289.     CHECK_POINTER(pVal);
  5290.     *pVal  = ToVB(sipAccnt->m_bEnableBindingResponseFailover);
  5291.     return S_OK;
  5292. }
  5293.  
  5294. STDMETHODIMP CSessionControl::put_EnableKeepAliveFailover(VARIANT_BOOL newVal)
  5295. {
  5296.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5297.  
  5298.     RET_ERROR_STR(sipAccnt);
  5299.  
  5300.     m_pFramework->Log("Keep alive failover = " + tostring(Tobool(newVal)));
  5301.  
  5302.     sipAccnt->m_bEnableBindingResponseFailover = Tobool(newVal);
  5303.     if (!sipAccnt->m_bEnableBindingResponseFailover)
  5304.     {
  5305.         sipAccnt->m_iSentKeepAliveCount = 0;
  5306.     }
  5307.     return S_OK;
  5308. }
  5309.  
  5310. STDMETHODIMP CSessionControl::TakeSnapshot(BSTR bstrFileName)
  5311. {
  5312. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5313.     CHECK_MEDIAFRAMEWORK();
  5314.     return m_pFramework->m_mediaFramework->TakeSnapshot(bstrFileName);
  5315. #else
  5316.     return S_OK;
  5317. #endif
  5318. }
  5319.  
  5320. STDMETHODIMP CSessionControl::TakeIncomingVideoSnapshot(BSTR bstrFileName, int nIndex)
  5321. {
  5322. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5323.     CHECK_MEDIAFRAMEWORK();
  5324.     string sTargetID = m_pCallLine->GetTargetID();
  5325.     if (sTargetID.empty())
  5326.         return ThrowError("ERROR: Not in session.");
  5327.    
  5328.     return m_pFramework->m_mediaFramework->TakeSnapshot2(ToBstr(sTargetID),
  5329.                                                          bstrFileName,
  5330.                                                          nIndex);
  5331. #else
  5332.     return S_OK;
  5333. #endif
  5334. }
  5335.  
  5336.  
  5337. STDMETHODIMP CSessionControl::get_PlayCapturedAudio(VARIANT_BOOL* pVal)
  5338. {
  5339. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5340.     CHECK_POINTER(pVal);
  5341.     CHECK_MEDIAFRAMEWORK();
  5342.     m_pFramework->m_mediaFramework->get_PlayCapturedAudio(pVal);
  5343. #endif
  5344.     return S_OK;
  5345. }
  5346.  
  5347. STDMETHODIMP CSessionControl::put_PlayCapturedAudio(VARIANT_BOOL newVal)
  5348. {  
  5349. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5350.     CHECK_MEDIAFRAMEWORK();
  5351.     m_pFramework->m_mediaFramework->put_PlayCapturedAudio(newVal);
  5352. #endif
  5353.     return S_OK;
  5354. }
  5355.  
  5356.  
  5357. STDMETHODIMP CSessionControl::get_AudioPlaybackBufferSize(int* pVal)
  5358. {
  5359. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5360.     CHECK_POINTER(pVal);
  5361.     CHECK_MEDIAFRAMEWORK();
  5362.     m_pFramework->m_mediaFramework->get_AudioPlaybackBufferSize(pVal);
  5363. #endif
  5364.     return S_OK;
  5365. }
  5366.  
  5367. STDMETHODIMP CSessionControl::put_AudioPlaybackBufferSize(int newVal)
  5368. {
  5369. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5370.     CHECK_MEDIAFRAMEWORK();
  5371.     m_pFramework->m_mediaFramework->put_AudioPlaybackBufferSize(newVal);
  5372. #endif
  5373.     return S_OK;
  5374. }
  5375.  
  5376. //Packet Loss Concealment
  5377. STDMETHODIMP CSessionControl::get_EnablePacketLossConcealment(VARIANT_BOOL* pVal)
  5378. {
  5379. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5380.     CHECK_POINTER(pVal);
  5381.     CHECK_MEDIAFRAMEWORK();
  5382.     m_pFramework->m_mediaFramework->get_EnablePacketLossConcealment(pVal);
  5383. #endif
  5384.     return S_OK;
  5385. }
  5386.  
  5387. STDMETHODIMP CSessionControl::put_EnablePacketLossConcealment(VARIANT_BOOL newVal)
  5388. {
  5389. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5390.     CHECK_MEDIAFRAMEWORK();
  5391.     m_pFramework->m_mediaFramework->put_EnablePacketLossConcealment(newVal);
  5392. #endif
  5393.     return S_OK;
  5394. }
  5395. //Voice Activity Detection
  5396. STDMETHODIMP CSessionControl::get_EnableVoiceActivityDetection(VARIANT_BOOL* pVal)
  5397. {
  5398. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5399.     CHECK_POINTER(pVal);
  5400.     CHECK_MEDIAFRAMEWORK();
  5401.     m_pFramework->m_mediaFramework->get_EnableVoiceActivityDetection(pVal);
  5402. #endif
  5403.     return S_OK;
  5404. }
  5405.  
  5406. STDMETHODIMP CSessionControl::put_EnableVoiceActivityDetection(VARIANT_BOOL newVal)
  5407. {
  5408. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5409.     CHECK_MEDIAFRAMEWORK();
  5410.     m_pFramework->m_mediaFramework->put_EnableVoiceActivityDetection(newVal);
  5411. #endif
  5412.     return S_OK;
  5413. }
  5414.  
  5415. //20-7
  5416. //Auto Gain Control
  5417. STDMETHODIMP CSessionControl::get_EnableAGC(VARIANT_BOOL* pVal)
  5418. {
  5419.     CHECK_POINTER(pVal);
  5420.     CHECK_MEDIAFRAMEWORK();
  5421.     m_pFramework->m_mediaFramework->get_EnableAGC(pVal);
  5422.     return S_OK;
  5423. }
  5424.  
  5425. STDMETHODIMP CSessionControl::put_EnableAGC(VARIANT_BOOL newVal)
  5426. {
  5427.     CHECK_MEDIAFRAMEWORK();
  5428.     m_pFramework->m_mediaFramework->put_EnableAGC(newVal);
  5429.     return S_OK;
  5430. }
  5431.  
  5432. //return whether or not srtp is enabled
  5433. STDMETHODIMP CSessionControl::get_EnableSrtp(VARIANT_BOOL* pVal)
  5434. {
  5435.     CHECK_POINTER(pVal);
  5436.     CHECK_MEDIAFRAMEWORK();
  5437.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5438.  
  5439.     RET_ERROR_STR(sipAccnt);
  5440.     *pVal = ToVB(sipAccnt->m_pAgent->GetSrtpCall());
  5441.     return S_OK;
  5442. }
  5443.  
  5444. //enable Srtp
  5445. STDMETHODIMP CSessionControl::put_EnableSrtp(VARIANT_BOOL newVal)
  5446. {
  5447.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5448.  
  5449.     RET_ERROR_STR(sipAccnt);
  5450.     CHECK_MEDIAFRAMEWORK();
  5451.     m_pFramework->Log("Enable SRTP = " + itoa((int)ToBOOL(newVal)));
  5452.  
  5453.     sipAccnt->m_pAgent->SetSrtpCall(Tobool(newVal));
  5454.     return S_OK;
  5455. }
  5456.  
  5457. //Denoise
  5458. STDMETHODIMP CSessionControl::get_EnableDenoise(VARIANT_BOOL* pVal)
  5459. {
  5460.     CHECK_POINTER(pVal);
  5461.     CHECK_MEDIAFRAMEWORK();
  5462.     m_pFramework->m_mediaFramework->get_EnableDenoise(pVal);
  5463.     return S_OK;
  5464. }
  5465.  
  5466. STDMETHODIMP CSessionControl::put_EnableDenoise(VARIANT_BOOL newVal)
  5467. {
  5468.     CHECK_MEDIAFRAMEWORK();
  5469.     m_pFramework->m_mediaFramework->put_EnableDenoise(newVal);
  5470.     return S_OK;
  5471. }
  5472.  
  5473.  
  5474. STDMETHODIMP CSessionControl::get_HashedPassword(int iIndex, BSTR* pVal)
  5475. {
  5476.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5477.  
  5478.     RET_ERROR_STR(sipAccnt);
  5479.  
  5480.     CHECK_POINTER(pVal);
  5481.     BstrFromString(pVal, sipAccnt->m_pAgent->GetHashedPassword(iIndex));
  5482.     return S_OK;
  5483. }
  5484.  
  5485. STDMETHODIMP CSessionControl::put_HashedPassword(int iIndex, BSTR newVal)
  5486. {
  5487.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5488.  
  5489.     RET_ERROR_STR(sipAccnt);
  5490.  
  5491.     sipAccnt->m_pAgent->SetHashedPassword(iIndex, ToStringA(newVal));
  5492.     return S_OK;
  5493. }
  5494.  
  5495. #ifdef USE_VARIANT_IN_EVENT
  5496. STDMETHODIMP CSessionControl::ConferenceMemberList(VARIANT_BOOL bVideoOnly, SAFEARRAY **pVal)
  5497. #else
  5498. STDMETHODIMP CSessionControl::ConferenceMemberList(VARIANT_BOOL bVideoOnly, std::vector<std::string> *pVal)
  5499. #endif
  5500. {
  5501.     CHECK_POINTER(pVal);
  5502.  
  5503.     list<string> ls;
  5504.  
  5505.     m_pCallLine->GetConferenceMemberList(ls, Tobool(bVideoOnly));
  5506.  
  5507. #ifdef USE_VARIANT_IN_EVENT
  5508.     BstrArray a(ls.size());
  5509.     list<string>::iterator iter = ls.begin();
  5510.     for (int i = 0; iter != ls.end(); iter++, i++)
  5511.     {
  5512.         a.PutString(i, *iter);
  5513.     }
  5514.  
  5515.     a.Detach(pVal);
  5516. #else
  5517.     pVal->clear();
  5518.     for(list<string>::iterator iter = ls.begin(); iter != ls.end(); iter++)
  5519.     {
  5520.         pVal->push_back(*iter);
  5521.     }
  5522. #endif
  5523.     return S_OK;
  5524. }
  5525.  
  5526. STDMETHODIMP CSessionControl::SubscribeConferenceMemberList()
  5527. {
  5528.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5529.  
  5530.     RET_ERROR_STR(sipAccnt);
  5531.  
  5532.     sipAccnt->m_pAgent->SubscribeConferenceMemberList();
  5533.  
  5534.     return S_OK;
  5535. }
  5536.  
  5537. STDMETHODIMP CSessionControl::GetVideoWindowCount(int iLine, int* pVal)
  5538. {
  5539.     CallDialog* p = m_pCallLine->GetDialog(iLine);
  5540.     if (!p)
  5541.     {
  5542.         return ThrowError("ERROR: GetVideoWindowCount::Invalid Line");
  5543.     }
  5544.  
  5545.     SipAccount* sipAccnt = GetSipAccount(p->m_iAcct);
  5546.  
  5547.     RET_ERROR_STR(sipAccnt);
  5548.  
  5549.     //SipAccount* sipAccnt = GetSelectedSipAccount();
  5550.  
  5551.     RET_ERROR_STR(sipAccnt);
  5552.  
  5553.     CHECK_POINTER(pVal);
  5554.  
  5555.     *pVal = sipAccnt->m_pAgent->GetVideoWindowCount(iLine);
  5556.  
  5557.     return S_OK;
  5558. }
  5559.  
  5560. #ifdef WCE_PLATFORM_STANDARDSDK_500
  5561. //////////////////////////////////////////////////////////////////////
  5562. // network thread and message handler
  5563. //////////////////////////////////////////////////////////////////////
  5564. void* CSessionControl::WindowsMessageThread(void *arg)
  5565. {
  5566.     SET_CURRENT_THREAD_NAME;
  5567.     CSessionControl *pThis = (CSessionControl *)(arg);
  5568.  
  5569.     CoInit coInit;
  5570.  
  5571.     const long iNumEvents = 2;
  5572.  
  5573.     HANDLE EventArray[iNumEvents];
  5574.     EventArray[0] = pThis->m_hQuitWindowsMessageThread;
  5575.     EventArray[1] = pThis->m_hNewWindowsMessage;
  5576.  
  5577.     for (;;)
  5578.     {
  5579.         // Wait for an event (or a queued callback function) to wake
  5580.         // us up.  This is an alertable wait state (fAlertable == TRUE).
  5581.         u_int32_t WaitStatus = WaitForMultipleObjects(iNumEvents,
  5582.                                                   EventArray,
  5583.                                                   FALSE,
  5584.                                                   5000);
  5585.  
  5586.         switch (WaitStatus)
  5587.         {
  5588.         case WAIT_FAILED:
  5589.             PAL_DB_ASSERT(0 && "WaitForMultipleObjects() failed");
  5590.             break;
  5591.  
  5592.         case WAIT_OBJECT_0:
  5593.             return NULL;
  5594.  
  5595.         case WAIT_OBJECT_0 + 1:
  5596.             pThis->ProcessNextWindowsMessage();
  5597.             break; 
  5598.  
  5599.         default:
  5600.             break;
  5601.         }
  5602.     }
  5603.    
  5604.     return NULL;
  5605. }
  5606.  
  5607. void CSessionControl::ProcessNextWindowsMessage()
  5608. {
  5609.     UINT uMsg = m_qWindowsMessageMsgTypeQueue.front();
  5610.     WPARAM wParam = m_qWindowsMessageWparamQueue.front();
  5611.     LPARAM lParam = m_qWindowsMessageLparamQueue.front();
  5612.  
  5613.     {
  5614.         PAL::Time_Critical_Section cs(*m_pWindowsMessageQueueMutex.get());
  5615.         m_qWindowsMessageMsgTypeQueue.pop();
  5616.         m_qWindowsMessageWparamQueue.pop();
  5617.         m_qWindowsMessageLparamQueue.pop();
  5618.  
  5619.         if (!m_qWindowsMessageMsgTypeQueue.empty())
  5620.             SetEvent(m_hNewWindowsMessage);
  5621.     }
  5622.  
  5623.     LRESULT lResult;
  5624.     ProcessWindowMessage(NULL, uMsg, wParam, lParam, lResult);
  5625. }
  5626.  
  5627. void CSessionControl::SendWindowsMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  5628. {
  5629.     {
  5630.         PAL::Time_Critical_Section cs(*m_pWindowsMessageQueueMutex.get());
  5631.         m_qWindowsMessageMsgTypeQueue.push(uMsg);
  5632.         m_qWindowsMessageWparamQueue.push(wParam);
  5633.         m_qWindowsMessageLparamQueue.push(lParam);
  5634.         SetEvent(m_hNewWindowsMessage);
  5635.     }
  5636. }
  5637.  
  5638. #endif
  5639.  
  5640. STDMETHODIMP CSessionControl::get_MyPhoneNumber(BSTR *pVal)
  5641. {
  5642.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5643.  
  5644.     RET_ERROR_STR(sipAccnt);
  5645.  
  5646.     CHECK_POINTER(pVal);
  5647.     BstrFromString(pVal, sipAccnt->m_pAgent->GetFromPhoneNumber());
  5648.     return S_OK;
  5649. }
  5650.  
  5651. STDMETHODIMP CSessionControl::put_MyPhoneNumber(BSTR newVal)
  5652. {
  5653.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5654.  
  5655.     RET_ERROR_STR(sipAccnt);
  5656.  
  5657.     sipAccnt->m_pAgent->SetFromPhoneNumber(ToStringA(newVal));
  5658.     return S_OK;
  5659. }
  5660.  
  5661. STDMETHODIMP CSessionControl::WriteFirewallInfo(void)
  5662. {
  5663.     return ThrowError("ERROR: WriteFirewallInfo not supported by Any-Firewall Engine");
  5664. }
  5665.  
  5666. STDMETHODIMP CSessionControl::get_ArchiveSentStreams(VARIANT_BOOL *pVal)
  5667. {
  5668. #ifndef __unix__
  5669.     CHECK_POINTER(pVal);
  5670.     CHECK_MEDIAFRAMEWORK();
  5671.     m_pFramework->m_mediaFramework->get_ArchiveSentStreams(pVal);
  5672. #endif
  5673.     return S_OK;
  5674. }
  5675.  
  5676. STDMETHODIMP CSessionControl::put_ArchiveSentStreams(VARIANT_BOOL newVal)
  5677. {
  5678. #ifndef __unix__
  5679.     CHECK_MEDIAFRAMEWORK();
  5680.     return m_pFramework->m_mediaFramework->put_ArchiveSentStreams(newVal);
  5681. #else
  5682.     return S_OK;
  5683. #endif
  5684. }
  5685.  
  5686. STDMETHODIMP CSessionControl::get_ArchiveFileName(BSTR *pVal)
  5687. {
  5688. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5689.     CHECK_POINTER(pVal);
  5690.     CHECK_MEDIAFRAMEWORK();
  5691.     m_pFramework->m_mediaFramework->get_ArchiveFileName(pVal);
  5692. #endif
  5693.     return S_OK;
  5694. }
  5695.  
  5696. STDMETHODIMP CSessionControl::put_ArchiveFileName(BSTR newVal)
  5697. {
  5698. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5699.     CHECK_MEDIAFRAMEWORK();
  5700.     return m_pFramework->m_mediaFramework->put_ArchiveFileName(newVal);
  5701. #else
  5702.     return S_OK;
  5703. #endif
  5704. }
  5705.  
  5706. STDMETHODIMP CSessionControl::get_DTMFMode(int *pVal)
  5707. {
  5708.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5709.  
  5710.     RET_ERROR_STR(sipAccnt);
  5711.  
  5712.     CHECK_POINTER(pVal);
  5713.     // 0 = DTMF using RTP Payload
  5714.     // 1 = DTMF using SIP INFO method
  5715.     // 2 = DTMF using inband audio signal
  5716.  
  5717.     *pVal = sipAccnt->m_iSipInfoDtmf;
  5718.     return S_OK;
  5719. }
  5720.  
  5721. STDMETHODIMP CSessionControl::put_DTMFMode(int newVal)
  5722. {
  5723.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5724.  
  5725.     RET_ERROR_STR(sipAccnt);
  5726.  
  5727.     // 0 = DTMF using RTP Payload, RFC 2833
  5728.     // 1 = DTMF using SIP INFO method
  5729.     // 2 = DTMF using inband audio signal
  5730.  
  5731.     if (newVal < 0 || newVal > 2)
  5732.         return ThrowError("ERROR: DTMFMode is out of range. Valid range is 0-2");
  5733.  
  5734.     sipAccnt->m_iSipInfoDtmf = newVal;
  5735.     return S_OK;
  5736. }
  5737.  
  5738. #ifdef _WIN32_WCE
  5739. void* CSessionControl::SuspendMonitorThread(void* arg)
  5740. {
  5741.     SET_CURRENT_THREAD_NAME;
  5742.     CSessionControl *pThis = (CSessionControl *)(arg);
  5743.  
  5744.     CoInit coInit;
  5745.  
  5746.     const long iNumEvents = 2;
  5747.  
  5748.     HANDLE EventArray[iNumEvents];
  5749.     EventArray[0] = pThis->m_hQuitSuspendMonitorThread;
  5750.     EventArray[1] = pThis->m_hPowerMsgQueue;
  5751.  
  5752.     for (;;)
  5753.     {
  5754.         // Wait for an event (or a queued callback function) to wake
  5755.         // us up.  This is an alertable wait state (fAlertable == TRUE).
  5756.         u_int32_t WaitStatus = WaitForMultipleObjects(iNumEvents,
  5757.                                                   EventArray,
  5758.                                                   FALSE,
  5759.                                                   INFINITE);
  5760.  
  5761.         switch (WaitStatus)
  5762.         {
  5763.         case WAIT_FAILED:
  5764.             PAL_DB_ASSERT(0 && "WaitForMultipleObjects() failed");
  5765.             break;
  5766.  
  5767.         case WAIT_OBJECT_0:
  5768.             return NULL;
  5769.  
  5770.         case WAIT_OBJECT_0 + 1:
  5771.             BYTE messageBuffer[30];
  5772.             LPDWORD numBytesRead;
  5773.             //u_int32_t dwFlags;
  5774.             LPDWORD dwFlags;
  5775.  
  5776.             ReadMsgQueue(pThis->m_hPowerMsgQueue, messageBuffer, sizeof(messageBuffer),
  5777.                          numBytesRead, 0, dwFlags);
  5778.            
  5779.             pThis->HandleSuspendResume();
  5780.             break; 
  5781.  
  5782.         default:
  5783.             break;
  5784.         }
  5785.     }
  5786.    
  5787.     return NULL;
  5788. }
  5789.  
  5790. void CSessionControl::HandleSuspendResume()
  5791. {
  5792.     // transport error fired from transaction layer
  5793.     // recv error
  5794.     // invite response times out
  5795.     // register response times out
  5796.     // register renew times out
  5797.     // stun keep alive times out
  5798.  
  5799.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5800.  
  5801.     RET_IF_NULL(sipAccnt)
  5802.  
  5803.     KILL_TIMER(sipAccnt->m_iRegistrationResponseTimer);
  5804.     KILL_TIMER(sipAccnt->m_iInviteResponseTimer);
  5805.     KILL_TIMER(sipAccnt->m_iRegistrationRefreshTimer);
  5806.     KILL_TIMER(sipAccnt->m_iSignalChannelKeepAliveTimer);
  5807. #ifdef _SUPPORT_EVENT_PACKAGE
  5808.     KILL_TIMER(sipAccnt->m_iMWIRefreshTimer);
  5809. #endif
  5810.  
  5811.     if (!sipAccnt->m_sCallUri.empty())
  5812.     {
  5813.         sipAccnt->m_pAgent->HandleCallTimeoutOrError();
  5814.     }
  5815.  
  5816.     // close framework and call line
  5817.     // reset registration state to idle
  5818.     // register to a new server if available
  5819.     // start response timer
  5820.     // start refresh-response timer?
  5821.  
  5822.     // reinvite  if invite failed
  5823.     // fire no response during the first registration
  5824.     // fir connection lost during the rest registration
  5825.     if (sipAccnt->m_pAgent->HandleTimeoutOrError())
  5826.     {
  5827.         PAL_DB("timeout or error is handled.");
  5828.     }
  5829.  
  5830.     sipAccnt->m_pAgent->RestoreSessionNetwork();
  5831.     if (sipAccnt->m_bRegistered)
  5832.     {
  5833.         sipAccnt->m_bRegistered = false;
  5834.         sipAccnt->m_sCallUri = "";
  5835.        
  5836.         Fire_OnConnectionLost(m_iSelectedAccount);     
  5837.     }
  5838. }
  5839. #endif
  5840.  
  5841. STDMETHODIMP CSessionControl::put_EnableStunSupport(VARIANT_BOOL newVal)
  5842. {
  5843.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5844.  
  5845.     RET_ERROR_STR(sipAccnt);
  5846.  
  5847.     int iAfOption = (Tobool(newVal) ? AF_OPTION_TRUE : AF_OPTION_FALSE);
  5848. #if (AF_DLL_VERSION >= 10011629)
  5849.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableStun, &iAfOption);
  5850. #else
  5851.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableStun, iAfOption);
  5852. #endif
  5853.  
  5854.     m_pFramework->Log((string)"STUN Support: " + (newVal ? "on" : "off"));
  5855.  
  5856.     return S_OK;
  5857. }
  5858.  
  5859. STDMETHODIMP CSessionControl::get_EnableStunSupport(VARIANT_BOOL *pVal)
  5860. {
  5861.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5862.  
  5863.     RET_ERROR_STR(sipAccnt);
  5864.  
  5865.     bool bret = m_pAFEngine->GetChannelOption(0, EAfOptionEnableStun) == AF_OPTION_TRUE;
  5866.  
  5867.     CHECK_POINTER(pVal);
  5868.    
  5869.     *pVal = ToVB(bret);
  5870.  
  5871.     return S_OK;
  5872. }
  5873.  
  5874. STDMETHODIMP CSessionControl::put_EnableRelaySupport(VARIANT_BOOL newVal)
  5875. {
  5876.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5877.  
  5878.     RET_ERROR_STR(sipAccnt);
  5879.  
  5880.     int iAfOption = (Tobool(newVal) ? AF_OPTION_TRUE : AF_OPTION_FALSE);
  5881. #if (AF_DLL_VERSION >= 10011629)
  5882.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableTurn, &iAfOption);
  5883. #else
  5884.     m_pAFEngine->SetChannelOption(0, EAfOptionEnableTurn, iAfOption);
  5885. #endif
  5886.  
  5887.     m_pFramework->Log((string)"Relay Support: " + (newVal ? "on" : "off"));
  5888.  
  5889.     return S_OK;
  5890. }
  5891.  
  5892. STDMETHODIMP CSessionControl::get_EnableRelaySupport(VARIANT_BOOL *pVal)
  5893. {
  5894.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5895.  
  5896.     RET_ERROR_STR(sipAccnt);
  5897.  
  5898.     bool bret = m_pAFEngine->GetChannelOption(0, EAfOptionEnableTurn) == AF_OPTION_TRUE;
  5899.  
  5900.     CHECK_POINTER(pVal);
  5901.    
  5902.     *pVal = ToVB(bret);
  5903.  
  5904.     return S_OK;
  5905. }
  5906.  
  5907. STDMETHODIMP CSessionControl::put_EnableIceSupport(VARIANT_BOOL newVal)
  5908. {
  5909.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5910.  
  5911.     RET_ERROR_STR(sipAccnt);
  5912.  
  5913.     sipAccnt->m_pAgent->SetEnableIceSupport(Tobool(newVal));
  5914.     m_pFramework->Log((string)"ICE Support: " + (newVal ? "on" : "off"));
  5915.  
  5916.     return S_OK;
  5917. }
  5918.  
  5919. STDMETHODIMP CSessionControl::get_DialupDetected(VARIANT_BOOL *pVal)
  5920. {
  5921.     CHECK_POINTER(pVal);
  5922. #if !defined(__unix__) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
  5923.     DWORD dwFlags = 0;
  5924.     ::InternetGetConnectedState(&dwFlags, 0);
  5925.     bool bLan = ((dwFlags & INTERNET_CONNECTION_LAN) != 0);
  5926.     bool bModem = ((dwFlags & INTERNET_CONNECTION_MODEM) != 0);
  5927.     *pVal = ToVB(bModem);
  5928. #endif
  5929.     return S_OK;
  5930. }
  5931.  
  5932. STDMETHODIMP CSessionControl::get_EnableIceSupport(VARIANT_BOOL *pVal)
  5933. {
  5934.     SipAccount* sipAccnt = GetSelectedSipAccount();
  5935.  
  5936.     RET_ERROR_STR(sipAccnt);
  5937.  
  5938.     CHECK_POINTER(pVal);
  5939.    
  5940.     *pVal = ToVB(sipAccnt->m_pAgent->GetEnableIceSupport());
  5941.  
  5942.     return S_OK;
  5943. }
  5944.  
  5945. #ifdef _WIN32_WCE
  5946. STDMETHODIMP CSessionControl::SetVoSIPServer(BSTR address, int port)
  5947. {
  5948. #ifdef AEGIS
  5949.     CHECK_MEDIAFRAMEWORK();
  5950.    
  5951.     string sAddress = TruncateSpace(ToStringA(address));
  5952.  
  5953.     if (sAddress.length() > 0) {
  5954.         if (!AreURICharactersValid(sAddress)) {
  5955.             CComBSTR dummyAddress(L"LocalHost");
  5956.             m_pFramework->m_mediaFramework->VoSIPSetServer(dummyAddress, port);
  5957.             return ThrowError("ERROR: Invalid characters in VoSIP Server address.");
  5958.         }
  5959.     }
  5960.  
  5961.     m_pFramework->m_mediaFramework->VoSIPSetServer(ToBstr(sAddress), port);
  5962.     return S_OK;
  5963. #else
  5964.     return E_FAIL;
  5965. #endif //AEGIS
  5966. }
  5967.  
  5968. STDMETHODIMP CSessionControl::get_VideoCaptureACFrequency(int* pVal)
  5969. {
  5970.     CHECK_MEDIAFRAMEWORK();
  5971. #ifndef _WIN32_WCE 
  5972.     return m_pFramework->m_mediaFramework->get_VideoCaptureACFrequency(pVal);
  5973. #else
  5974.     return S_OK;
  5975. #endif
  5976. }
  5977.  
  5978. STDMETHODIMP CSessionControl::put_VideoCaptureACFrequency(int newVal)
  5979. {
  5980.     CHECK_MEDIAFRAMEWORK();
  5981.    
  5982. #ifndef _WIN32_WCE
  5983.     //not implemented for WinCE in VideoSender
  5984.     return m_pFramework->m_mediaFramework->put_VideoCaptureACFrequency(newVal);
  5985. #else
  5986.     return S_OK;
  5987. #endif
  5988. }
  5989.  
  5990. STDMETHODIMP CSessionControl::get_VideoCaptureUpsideDown(VARIANT_BOOL* pVal)
  5991. {
  5992.     CHECK_MEDIAFRAMEWORK();
  5993. #ifndef _WIN32_WCE
  5994.     return m_pFramework->m_mediaFramework->get_VideoCaptureUpsideDown(pVal);
  5995. #else
  5996.     return S_OK;
  5997. #endif
  5998. }
  5999.  
  6000. STDMETHODIMP CSessionControl::put_VideoCaptureUpsideDown(VARIANT_BOOL newVal)
  6001. {
  6002.     CHECK_MEDIAFRAMEWORK();
  6003.    
  6004. #ifndef _WIN32_WCE
  6005.     return m_pFramework->m_mediaFramework->put_VideoCaptureUpsideDown(newVal);
  6006. #else
  6007.     return S_OK;
  6008. #endif
  6009. }
  6010.  
  6011. STDMETHODIMP CSessionControl::get_VideoCaptureIndoorMode(VARIANT_BOOL* pVal)
  6012. {
  6013.     CHECK_MEDIAFRAMEWORK();
  6014. #ifndef _WIN32_WCE
  6015.     return m_pFramework->m_mediaFramework->get_VideoCaptureIndoorMode(pVal);
  6016. #else
  6017.     return S_OK;
  6018. #endif
  6019. }
  6020.  
  6021. STDMETHODIMP CSessionControl::put_VideoCaptureIndoorMode(VARIANT_BOOL newVal)
  6022. {
  6023.     CHECK_MEDIAFRAMEWORK();
  6024. #ifndef _WIN32_WCE 
  6025.     return m_pFramework->m_mediaFramework->put_VideoCaptureIndoorMode(newVal);
  6026. #else
  6027.     return S_OK;
  6028. #endif
  6029. }
  6030.  
  6031. STDMETHODIMP CSessionControl::get_AudioPTime60MsInVideoCalls(VARIANT_BOOL* pVal)
  6032. {
  6033.     *pVal = g_AudioPTime60MsInVideoCalls;
  6034.     return S_OK;
  6035. }
  6036.  
  6037. STDMETHODIMP CSessionControl::put_AudioPTime60MsInVideoCalls(VARIANT_BOOL newVal)
  6038. {
  6039.     g_AudioPTime60MsInVideoCalls = Tobool(newVal);
  6040.     return S_OK;
  6041. }
  6042.  
  6043. #endif //_WIN32_WCE
  6044.  
  6045. void CSessionControl::Shutdown()
  6046. {
  6047.     if (NULL != m_pFramework)
  6048.     {
  6049.         // final log message from this control
  6050.         m_pFramework->Log("Session Control shutting down...");
  6051.     }
  6052.     SipAccount* sipAccnt = GetSelectedSipAccount();
  6053.  
  6054.     RET_IF_NULL(sipAccnt);
  6055.     MSA_LOG("Sip Account is valid");
  6056.     sipAccnt->m_pAgent->Shutdown(); /*Remove this to final release.
  6057.     //                              * It will nullify MFramework.*/
  6058.     MSA_LOG("Killing Xact timer...");
  6059.     KILL_TIMER(sipAccnt->m_iTransactionTimer); //otherwise, it'll keep firing on a dead object.
  6060.     MSA_LOG("Killed Xact timer...");
  6061.     //ReleaseAccount(sipAccnt); //You can't refer to them later.
  6062.     m_iSelectedAccount = -1;
  6063. }
  6064.  
  6065. void CSessionControl::StartProfileTimer(const string& /*s*/)
  6066. {
  6067. #if 0
  6068.     if (NULL == m_pFramework)
  6069.         return;
  6070.     m_dwProfileStartTime = (u_int32_t)PAL::getCurrentTimeInMilliSeconds();
  6071. #endif
  6072. }
  6073.  
  6074. void CSessionControl::StopProfileTimer(const string& /*s*/)
  6075. {
  6076. #if 0
  6077.     if (NULL == m_pFramework)
  6078.         return;
  6079.  
  6080.     u_int32_t dwEndTime = (u_int32_t)PAL::getCurrentTimeInMilliSeconds();
  6081.     u_int32_t dwElapsed = dwEndTime - m_dwProfileStartTime;
  6082. #endif
  6083. }
  6084.  
  6085. /////////////////////////////////////////////////////
  6086. // NEW METHODS for MSA (Multiple Sip Account) feature.
  6087. //////////////////////////////////////////////////////
  6088.  
  6089. /**
  6090. * Get a pointer to the SipAccount with ID iAccnt.
  6091. */
  6092.  
  6093. SipAccount* CSessionControl::GetSipAccount(int id)
  6094. {
  6095.     SipAccountMap::iterator iter = m_sipAccountMap.find(id);
  6096.     if (iter == m_sipAccountMap.end())
  6097.     {
  6098.         return NULL;
  6099.     }
  6100.     return iter->second;
  6101. }
  6102.  
  6103. /**
  6104. * Get a pointer to the selected SipAccount.
  6105. */
  6106. SipAccount* CSessionControl::GetSelectedSipAccount()
  6107. {
  6108.  
  6109.     if (m_iSelectedAccount == -1)
  6110.         return NULL;
  6111.  
  6112.     return GetSipAccount(m_iSelectedAccount);
  6113. }
  6114.  
  6115. /* remove SIP Account. */
  6116. STDMETHODIMP CSessionControl::RemoveSipAccount(int iAccnt)
  6117. {  
  6118.     if(m_sipAccountMap.empty())
  6119.         return ThrowError("ERROR: No accounts to remove.");
  6120.    
  6121.     SipAccountMap::iterator iter = m_sipAccountMap.find(iAccnt);
  6122.     if (iter == m_sipAccountMap.end())
  6123.         return ThrowError("ERROR: Invalid SIP account ID.");
  6124.    
  6125.     SipAccount* sipAccnt = iter->second;
  6126.     sipAccnt->m_bAccountRemoved = true;
  6127.    
  6128.     Logout();
  6129.     return S_OK;
  6130. }
  6131. ///////////////////////////////////////////////////////////
  6132.  
  6133. STDMETHODIMP CSessionControl::SetApplicationActiveMode(int iApplicationActiveMode)
  6134. {
  6135. #ifdef USE_NSSTREAM_FOR_SIP
  6136.     printf("Application entered %d mode", iApplicationActiveMode);
  6137.     if(m_pFramework)
  6138.         m_pFramework->Log("Application entered " + itoa(iApplicationActiveMode) + " mode");
  6139.  
  6140.     PAL::Critical_Section cs(*m_pApplicationModeMutex);
  6141.  
  6142.     EApplicationActiveMode eApplicationActiveMode = (EApplicationActiveMode)iApplicationActiveMode;
  6143.     if (eApplicationActiveMode == eApplicationActiveModeEnteringBackground || eApplicationActiveMode == eApplicationActiveModeEnteredBackground)
  6144.     {
  6145.         //OpenGLPause(true);
  6146.         for (SipAccountMap::iterator accntIter = m_sipAccountMap.begin(); accntIter != m_sipAccountMap.end(); ++accntIter)
  6147.         {
  6148.             SipAccount* pAccnt = (SipAccount*)accntIter->second;
  6149.             if(pAccnt)
  6150.                 pAccnt->m_pAgent->StopThread(false);
  6151.         }
  6152.         UnloadAFEngine();
  6153.     }
  6154.     else
  6155.     {
  6156.         //OpenGLPause(false);
  6157.         if(!m_bAFEngineInit)
  6158.         {
  6159.             LoadAFEngine();
  6160.             m_pFramework->SetAFEngine(m_pAFEngine, m_iAFEServerStoreID);
  6161.             for (SipAccountMap::iterator accntIter = m_sipAccountMap.begin(); accntIter != m_sipAccountMap.end(); ++accntIter)
  6162.             {
  6163.                 SipAccount* pAccnt = (SipAccount*)accntIter->second;
  6164.                 if(pAccnt)
  6165.                     pAccnt->m_pAgent->SetAFEngine(m_pAFEngine, m_iAFEServerStoreID);
  6166.             }
  6167.             SetTURNUsernamePassword();
  6168.             SetNATTraversalServer(0, ToInternalBstr(""), 0, true);
  6169.         }
  6170.     }
  6171.     if(m_pFramework)
  6172.         m_pFramework->Log("Application mode change done");
  6173. #endif
  6174.  
  6175.     return S_OK;
  6176. }
  6177.  
  6178. STDMETHODIMP CSessionControl::ApplicationKeepAliveHandler()
  6179. {
  6180.     for (SipAccountMap::iterator accntIter = m_sipAccountMap.begin(); accntIter != m_sipAccountMap.end(); ++accntIter)
  6181.     {
  6182.         SipAccount* pAccnt = (SipAccount*)accntIter->second;
  6183.         if(pAccnt)
  6184.             pAccnt->m_pAgent->KeepSignalSocketAlive();
  6185.     }
  6186.  
  6187.     return S_OK;
  6188. }
  6189. STDMETHODIMP CSessionControl::get_SelectedSipAccount(int *pVal)
  6190. {
  6191.     CHECK_POINTER(pVal);
  6192.     *pVal = m_iSelectedAccount;
  6193.  
  6194.     return (*pVal == -1) ? ThrowError("ERROR: No Account is currently selected.") : S_OK;
  6195. }
  6196. /**
  6197. * Takes account id; selects the account whose map_index = newVal.
  6198. * If account does not exist, create it.
  6199. */
  6200. STDMETHODIMP CSessionControl::put_SelectedSipAccount(int newVal)
  6201. {  
  6202.     if(newVal >= m_iMaximumAccount)
  6203.         return ThrowError("ERROR: Account ID must not exceed maximum accounts");
  6204.  
  6205.     if (m_sipAccountMap.find(newVal) == m_sipAccountMap.end())
  6206.     {
  6207.             MSA_LOG("Account does not exist. Creating account...");
  6208.  
  6209.             if(-1 == CreateSipAccount(newVal))
  6210.                 return ThrowError("ERROR: Maximum number of accounts exceeded.");
  6211.        
  6212.     }
  6213.  
  6214.     m_iSelectedAccount = newVal;
  6215.  
  6216.     /*Sets the Framework to point to this account*/
  6217.     m_pFramework->Init(m_iSelectedAccount);
  6218.     m_pCallHistory->Init(m_iSelectedAccount);
  6219.     m_pCallLine->Init(m_iSelectedAccount);
  6220. #ifndef NO_DATA_TRAVELER
  6221.     m_pDataTraveler->SetSipAccountId(m_iSelectedAccount);
  6222. #endif
  6223.     MSA_LOG("Account: " + itoa(m_iSelectedAccount) + " is now selected");
  6224.     return S_OK;
  6225. }
  6226.  
  6227. /**
  6228. * Creates account with the specified ID.
  6229. * returns -1 if max accounts is exceeded.
  6230. */
  6231. int CSessionControl::CreateSipAccount(int iAccnt)
  6232. {
  6233.     if(m_sipAccountMap.size() >= m_iMaximumAccount)
  6234.         return -1;
  6235.  
  6236.     SipAccount* sipAccount = new SipAccount(this);
  6237.     PAL_DB_ASSERT(sipAccount);
  6238.  
  6239.     m_iSelectedAccount = iAccnt; /*Automatically set selectedAccount to the
  6240.                                   *Just-created account*/
  6241.  
  6242.     AddAccount(m_iSelectedAccount, sipAccount);
  6243.  
  6244.     sipAccount->Init(m_iSelectedAccount);  
  6245.  
  6246.     /*Sets the Framework to point to this account*/
  6247.     m_pFramework->Init(m_iSelectedAccount);
  6248.     m_pCallHistory->Init(m_iSelectedAccount);
  6249.     m_pCallLine->Init(m_iSelectedAccount);
  6250. #ifndef NO_DATA_TRAVELER
  6251.     m_pDataTraveler->SetSipAccountId(m_iSelectedAccount);
  6252. #endif
  6253. #ifdef USE_NSSTREAM_FOR_SIP
  6254.     // This must be set before setting AFEngine since setting AFEngine starts thread which uses the NSsocket
  6255.     sipAccount->m_pAgent->SetNSsocket(m_pNSsocket);
  6256. #endif
  6257.     sipAccount->m_pAgent->SetAFEngine(m_pAFEngine, m_iAFEServerStoreID);
  6258.     sipAccount->m_pAgent->SetAppWindow(m_hWndControl);
  6259.  
  6260.     sipAccount->m_iTransactionTimer = SetTimer(TRANSACTION_TIMER_ID + GetAccountID(sipAccount), TRANSACTION_TIMER_INTERVAL);
  6261.    
  6262.     sipAccount->m_iDataChannelKeepAliveTimer = SetTimer(
  6263.         DATA_CHANNEL_KEEP_ALIVE_TIMER_ID + GetAccountID(sipAccount),
  6264.         DATA_CHANNEL_KEEP_ALIVE_PERIOD * 1000);
  6265.  
  6266.     MSA_LOG("Created account: " + itoa(iAccnt));
  6267.     return iAccnt;
  6268. }
  6269.  
  6270. ////////////////////////////////////////////////////////////
  6271.  
  6272. /*release memory resources associated with a SipAccount object.*/
  6273. void CSessionControl::ReleaseAccount(SipAccount* sipAccnt)
  6274. {
  6275.     SAFE_DELETE(sipAccnt->m_pAgent);
  6276. }
  6277.  
  6278. void CSessionControl::AddAccount(int id, SipAccount* accnt)
  6279. {
  6280.     if (m_sipAccountMap.find(id) != m_sipAccountMap.end())
  6281.     {
  6282.         PAL_DB_ASSERT(0);
  6283.     }
  6284.     m_sipAccountMap.insert(SipAccountMap::value_type(id, accnt));
  6285. }
  6286.  
  6287. int CSessionControl::GetAccountID(SipAccount* sipAccnt)
  6288. {
  6289.     SipAccountMap::iterator iter = m_sipAccountMap.begin();
  6290.     for(; iter != m_sipAccountMap.end(); iter++)
  6291.     {
  6292.         if(sipAccnt == iter->second)
  6293.             return iter->first;
  6294.     }
  6295.     return -1;
  6296. }
  6297.  
  6298. void CSessionControl::WriteMSALog(const string &str)
  6299. {
  6300. #ifdef __unix__
  6301.     OnWriteLog(CSessionControl::LOG_MSA, str);
  6302. #endif
  6303.  
  6304.     if(m_fp == NULL)
  6305.         return;
  6306.  
  6307. #ifndef __unix__
  6308.     SYSTEMTIME st;
  6309.     GetLocalTime(&st);
  6310.     char buff[100] = {};
  6311.     sprintf(buff,"%d-%d-%d  %d:%d:%d::%d ",st.wYear,st.wMonth,st.wDay,
  6312.             st.wHour,st.wMinute,st.wSecond,st.wMilliseconds);
  6313.     fwrite(buff,1,strlen(buff),m_fp);
  6314. #endif
  6315.  
  6316.     fwrite(str.c_str(),1,str.length(),m_fp);
  6317.     fwrite("\n",1,1,m_fp);
  6318.     fflush(m_fp);
  6319.  
  6320. }
Advertisement
Add Comment
Please, Sign In to add comment