Kaidul

Certi

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