summaryrefslogtreecommitdiff
path: root/Protocols/SIP
diff options
context:
space:
mode:
Diffstat (limited to 'Protocols/SIP')
-rw-r--r--Protocols/SIP/SIPProto.cpp387
-rw-r--r--Protocols/SIP/SIPProto.h27
-rw-r--r--Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.libbin10311026 -> 10311042 bytes
-rw-r--r--Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.libbin3598192 -> 3598196 bytes
-rw-r--r--Protocols/SIP/resource.h7
-rw-r--r--Protocols/SIP/resource.rc48
6 files changed, 315 insertions, 154 deletions
diff --git a/Protocols/SIP/SIPProto.cpp b/Protocols/SIP/SIPProto.cpp
index 85e8515..3659cbb 100644
--- a/Protocols/SIP/SIPProto.cpp
+++ b/Protocols/SIP/SIPProto.cpp
@@ -118,7 +118,7 @@ static char * mir_pjstrdup(const pj_str_t *from)
}
-static int FistGtZero(int n1, int n2)
+static int FirstGtZero(int n1, int n2)
{
if (n1 > 0)
return n1;
@@ -157,58 +157,57 @@ SIPProto::SIPProto(const char *aProtoName, const TCHAR *aUserName)
hNetlibUser = 0;
hCallStateEvent = 0;
m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE;
+ messageID = 0;
m_tszUserName = mir_tstrdup(aUserName);
m_szProtoName = mir_strdup(aProtoName);
m_szModuleName = mir_strdup(aProtoName);
static OptPageControl amCtrls[] = {
- { NULL, CONTROL_TEXT, IDC_HOST, "Host", NULL, 0, 0, 256 },
- { NULL, CONTROL_INT, IDC_PORT, "RegPort", 5060, 0, 1 },
- { NULL, CONTROL_TEXT, IDC_USERNAME, "Username", NULL, 0, 0, 16 },
+ { NULL, CONTROL_TEXT, IDC_REG_HOST, "RegHost", NULL, 0, 0, 256 },
+ { NULL, CONTROL_INT, IDC_REG_PORT, "RegPort", 5060, 0, 0 },
{ NULL, CONTROL_PASSWORD, IDC_PASSWORD, "Password", NULL, IDC_SAVEPASSWORD, 0, 16 },
{ NULL, CONTROL_CHECKBOX, IDC_SAVEPASSWORD, "SavePassword", (BYTE) TRUE },
};
memmove(accountManagerCtrls, amCtrls, sizeof(accountManagerCtrls));
- accountManagerCtrls[0].var = &opts.host;
- accountManagerCtrls[1].var = &opts.reg.port;
- accountManagerCtrls[2].var = &opts.username;
- accountManagerCtrls[3].var = &opts.password;
- accountManagerCtrls[4].var = &opts.savePassword;
+ accountManagerCtrls[0].var = &opts.registrar.host;
+ accountManagerCtrls[1].var = &opts.registrar.port;
+ accountManagerCtrls[2].var = &opts.password;
+ accountManagerCtrls[3].var = &opts.savePassword;
static OptPageControl oCtrls[] = {
- { NULL, CONTROL_TEXT, IDC_HOST, "Host", NULL, 0, 0, 256 },
{ NULL, CONTROL_TEXT, IDC_USERNAME, "Username", NULL, 0, 0, 16 },
+ { NULL, CONTROL_TEXT, IDC_DOMAIN, "Domain", NULL, 0, 0, 256 },
{ NULL, CONTROL_PASSWORD, IDC_PASSWORD, "Password", NULL, IDC_SAVEPASSWORD, 0, 16 },
{ NULL, CONTROL_CHECKBOX, IDC_SAVEPASSWORD, "SavePassword", (BYTE) TRUE },
{ NULL, CONTROL_TEXT, IDC_REG_HOST, "RegHost", NULL, 0, 0, 256 },
{ NULL, CONTROL_INT, IDC_REG_PORT, "RegPort", 5060, 0, 0 },
- { NULL, CONTROL_TEXT, IDC_REALM, "Realm", NULL, 0, 0, 256 },
+ { NULL, CONTROL_TEXT, IDC_PROXY_HOST, "ProxyHost", NULL, 0, 0, 256 },
+ { NULL, CONTROL_INT, IDC_PROXY_PORT, "ProxyPort", 5060, 0, 0 },
{ NULL, CONTROL_TEXT, IDC_DNS_HOST, "DNSHost", NULL, 0, 0, 256 },
{ NULL, CONTROL_INT, IDC_DNS_PORT, "DNSPort", 53, 0, 0 },
{ NULL, CONTROL_TEXT, IDC_STUN_HOST, "STUNHost", (DWORD) _T("stun01.sipphone.com"), 0, 0, 256 },
{ NULL, CONTROL_INT, IDC_STUN_PORT, "STUNPort", PJ_STUN_PORT, 0, 0 },
- { NULL, CONTROL_TEXT, IDC_PROXY_HOST, "ProxyHost", NULL, 0, 0, 256 },
- { NULL, CONTROL_INT, IDC_PROXY_PORT, "ProxyPort", 5060, 0, 0 },
{ NULL, CONTROL_CHECKBOX, IDC_PUBLISH, "Publish", (BYTE) FALSE },
+ { NULL, CONTROL_CHECKBOX, IDC_KEEPALIVE, "SendKeepAlive", (BYTE) TRUE },
};
memmove(optionsCtrls, oCtrls, sizeof(optionsCtrls));
- optionsCtrls[0].var = &opts.host;
- optionsCtrls[1].var = &opts.username;
+ optionsCtrls[0].var = &opts.username;
+ optionsCtrls[1].var = &opts.domain;
optionsCtrls[2].var = &opts.password;
optionsCtrls[3].var = &opts.savePassword;
- optionsCtrls[4].var = &opts.reg.host;
- optionsCtrls[5].var = &opts.reg.port;
- optionsCtrls[6].var = &opts.realm;
- optionsCtrls[7].var = &opts.dns.host;
- optionsCtrls[8].var = &opts.dns.port;
- optionsCtrls[9].var = &opts.stun.host;
- optionsCtrls[10].var = &opts.stun.port;
- optionsCtrls[11].var = &opts.proxy.host;
- optionsCtrls[12].var = &opts.proxy.port;
- optionsCtrls[13].var = &opts.publish;
+ optionsCtrls[4].var = &opts.registrar.host;
+ optionsCtrls[5].var = &opts.registrar.port;
+ optionsCtrls[6].var = &opts.proxy.host;
+ optionsCtrls[7].var = &opts.proxy.port;
+ optionsCtrls[8].var = &opts.dns.host;
+ optionsCtrls[9].var = &opts.dns.port;
+ optionsCtrls[10].var = &opts.stun.host;
+ optionsCtrls[11].var = &opts.stun.port;
+ optionsCtrls[12].var = &opts.publish;
+ optionsCtrls[13].var = &opts.sendKeepAlive;
LoadOpts(optionsCtrls, MAX_REGS(optionsCtrls), m_szModuleName);
@@ -341,6 +340,10 @@ static void CALLBACK ProcessEvents(void *param)
case SIPEvent::pager:
proto->on_pager(ev.from, ev.text, ev.mime);
break;
+ case SIPEvent::pager_status:
+ proto->on_pager_status(ev.messageData->hContact, ev.messageData->messageID,
+ ev.messageData->status, ev.text);
+ break;
case SIPEvent::typing:
proto->on_typing(ev.from, ev.isTyping);
break;
@@ -348,6 +351,7 @@ static void CALLBACK ProcessEvents(void *param)
mir_free(ev.from);
mir_free(ev.text);
mir_free(ev.mime);
+ delete ev.messageData;
}
}
}
@@ -516,24 +520,6 @@ static void static_on_buddy_state(pjsua_buddy_id buddy_id)
}
-static SIPProto * FindProto(const TCHAR *uri)
-{
- for(int i = 0; i < instances.getCount(); ++i)
- {
- SIPProto *proto = &instances[i];
-
- TCHAR tmp[1024];
- mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s@%s"),
- CleanupSip(proto->opts.username), proto->opts.host);
-
- if (lstrcmpi(uri, tmp) == 0)
- return proto;
- }
-
- return NULL;
-}
-
-
// Incoming IM message (i.e. MESSAGE request)!
static void static_on_pager(pjsua_call_id call_id, const pj_str_t *from,
const pj_str_t *to, const pj_str_t *contact,
@@ -559,6 +545,29 @@ static void static_on_pager(pjsua_call_id call_id, const pj_str_t *from,
}
+void static_on_pager_status(pjsua_call_id call_id, const pj_str_t *to, const pj_str_t *body,
+ void *user_data, pjsip_status_code status, const pj_str_t *reason,
+ pjsip_tx_data *tdata, pjsip_rx_data *rdata, pjsua_acc_id acc_id)
+{
+ SIPProto *proto = (SIPProto *) pjsua_acc_get_user_data(acc_id);
+ if (proto == NULL)
+ return;
+
+ SIPEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = SIPEvent::pager_status;
+ ev.messageData = (MessageData *) user_data;
+ ev.messageData->status = status;
+ ev.text = mir_pjstrdup(reason);
+
+ EnterCriticalSection(&proto->cs);
+ proto->events.push_back(ev);
+ LeaveCriticalSection(&proto->cs);
+
+ CallFunctionAsync(&ProcessEvents, NULL);
+}
+
+
// Received typing indication
static void static_on_typing(pjsua_call_id call_id, const pj_str_t *from,
const pj_str_t *to, const pj_str_t *contact,
@@ -620,6 +629,7 @@ int SIPProto::Connect()
cfg.cb.on_incoming_subscribe = &static_on_incoming_subscribe;
cfg.cb.on_buddy_state = &static_on_buddy_state;
cfg.cb.on_pager2 = &static_on_pager;
+ cfg.cb.on_pager_status2 = &static_on_pager_status;
cfg.cb.on_typing2 = &static_on_typing;
@@ -628,7 +638,7 @@ int SIPProto::Connect()
TCHAR tmp[1024];
mir_sntprintf(tmp, MAX_REGS(tmp), _T("%s:%d"),
CleanupSip(opts.stun.host),
- FistGtZero(opts.stun.port, PJ_STUN_PORT));
+ FirstGtZero(opts.stun.port, PJ_STUN_PORT));
stun = TcharToUtf8(tmp).detach();
cfg.stun_srv_cnt = 1;
@@ -640,7 +650,7 @@ int SIPProto::Connect()
TCHAR tmp[1024];
mir_sntprintf(tmp, MAX_REGS(tmp), _T("%s:%d"),
CleanupSip(opts.dns.host),
- FistGtZero(opts.dns.port, 53));
+ FirstGtZero(opts.dns.port, 53));
dns = TcharToUtf8(tmp).detach();
cfg.nameserver_count = 1;
@@ -683,29 +693,34 @@ int SIPProto::Connect()
}
{
+ scoped_mir_free<char> registrar;
scoped_mir_free<char> proxy;
TCHAR tmp[1024];
pjsua_acc_config cfg;
pjsua_acc_config_default(&cfg);
cfg.user_data = this;
- //cfg.transport_id = transport_id;
+ cfg.transport_id = transport_id;
- mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s@%s"), CleanupSip(opts.username), opts.host);
+ BuildURI(tmp, MAX_REGS(tmp), opts.username, opts.domain);
TcharToUtf8 id(tmp);
cfg.id = pj_str(id);
- mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s:%d"),
- CleanupSip(FirstNotEmpty(opts.reg.host, opts.host)),
- FistGtZero(opts.reg.port, 5060));
- TcharToUtf8 reg_uri(tmp);
- cfg.reg_uri = pj_str(reg_uri);
+ if (!IsEmpty(opts.registrar.host))
+ {
+ BuildURI(tmp, MAX_REGS(tmp), NULL,
+ CleanupSip(opts.registrar.host),
+ FirstGtZero(opts.registrar.port, 5060));
+ registrar = TcharToUtf8(tmp).detach();
+
+ cfg.reg_uri = pj_str(registrar);
+ }
if (!IsEmpty(opts.proxy.host))
{
- mir_sntprintf(tmp, MAX_REGS(tmp), _T("sip:%s:%d"),
- CleanupSip(opts.proxy.host),
- FistGtZero(opts.proxy.port, 5060));
+ BuildURI(tmp, MAX_REGS(tmp), NULL,
+ CleanupSip(opts.proxy.host),
+ FirstGtZero(opts.proxy.port, 5060));
proxy = TcharToUtf8(tmp).detach();
cfg.proxy_cnt = 1;
@@ -714,10 +729,13 @@ int SIPProto::Connect()
cfg.publish_enabled = (opts.publish ? PJ_TRUE : PJ_FALSE);
+ if (!opts.sendKeepAlive)
+ cfg.ka_interval = 0;
+
cfg.cred_count = 1;
- TcharToUtf8 host(CleanupSip(FirstNotEmpty(opts.realm, opts.host)));
- cfg.cred_info[0].realm = pj_str(host);
+ TcharToUtf8 realm(CleanupSip(opts.domain));
+ cfg.cred_info[0].realm = pj_str(realm);
cfg.cred_info[0].scheme = pj_str("digest");
TcharToUtf8 username(opts.username);
cfg.cred_info[0].username = pj_str(username);
@@ -733,7 +751,12 @@ int SIPProto::Connect()
}
}
- // Add contacts to buddy list
+ return 0;
+}
+
+
+void SIPProto::AddContactsToBuddyList()
+{
for(HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
hContact != NULL;
hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0))
@@ -769,8 +792,6 @@ int SIPProto::Connect()
pjsua_buddy_subscribe_pres(buddy_id, PJ_TRUE);
}
-
- return 0;
}
@@ -1136,9 +1157,16 @@ void SIPProto::on_reg_state()
if (info.status == PJSIP_SC_OK)
{
+ int oldStatus = m_iStatus;
+
int status = (m_iDesiredStatus > ID_STATUS_OFFLINE ? m_iDesiredStatus : ID_STATUS_ONLINE);
SendPresence(status);
BroadcastStatus(status);
+
+ if (oldStatus <= ID_STATUS_OFFLINE)
+ {
+ AddContactsToBuddyList();
+ }
}
else
{
@@ -1168,33 +1196,32 @@ void SIPProto::on_incoming_call(pjsua_call_id call_id)
return;
}
- TCHAR number[1024];
- lstrcpyn(number, SipToTchar(info.remote_contact), MAX_REGS(number));
- RemoveLtGt(number);
-
- TCHAR name[256];
- name[0] = 0;
- SipToTchar remote_info(info.remote_info);
- if (remote_info[0] == _T('"'))
+ pjsua_buddy_id buddy_id = pjsua_buddy_find(&info.remote_info);
+ if (buddy_id != PJSUA_INVALID_ID)
{
- TCHAR *other = _tcsstr(&remote_info[1], _T("\" <"));
- if (other != NULL)
- {
- lstrcpyn(name, &remote_info[1], min(MAX_REGS(name), other - remote_info));
- if (IsEmpty(number))
- {
- lstrcpyn(number, other+2, MAX_REGS(number));
- RemoveLtGt(number);
- }
- }
+ HANDLE hContact = GetContact(buddy_id);
+
+ NotifyCall(call_id, VOICE_STATE_RINGING, hContact);
}
-
- if (IsEmpty(name) && IsEmpty(number))
- lstrcpyn(number, remote_info, MAX_REGS(number));
else
- CleanupURI(number, MAX_REGS(number), number);
+ {
+ SipToTchar remote_info(info.remote_info);
+
+ TCHAR number[1024];
+ number[0] = 0;
+ CleanupURI(number, MAX_REGS(number), remote_info);
- NotifyCall(call_id, VOICE_STATE_RINGING, NULL, name, number);
+ TCHAR name[256];
+ name[0] = 0;
+ if (remote_info[0] == _T('"'))
+ {
+ TCHAR *other = _tcsstr(&remote_info[1], _T("\" <"));
+ if (other != NULL)
+ lstrcpyn(name, &remote_info[1], min(MAX_REGS(name), other - remote_info));
+ }
+
+ NotifyCall(call_id, VOICE_STATE_RINGING, NULL, name, number);
+ }
}
@@ -1316,7 +1343,7 @@ void SIPProto::ConfigureDevices()
int __cdecl SIPProto::VoiceCaps(WPARAM wParam,LPARAM lParam)
{
- return VOICE_CAPS_VOICE | VOICE_CAPS_CALL_STRING;
+ return VOICE_CAPS_VOICE | VOICE_CAPS_CALL_CONTACT | VOICE_CAPS_CALL_STRING;
}
@@ -1339,49 +1366,79 @@ static void CleanupNumber(TCHAR *out, int outSize, const TCHAR *number)
void SIPProto::CleanupURI(TCHAR *out, int outSize, const TCHAR *url)
{
- lstrcpyn(out, CleanupSip(url), outSize);
+ if (url[0] == _T('"'))
+ {
+ const TCHAR *other = _tcsstr(&url[1], _T("\" <"));
+ if (other != NULL)
+ url = other + 2;
+ }
+
+ lstrcpyn(out, url, outSize);
TCHAR *phone = _tcsstr(out, _T(";user=phone"));
if (phone != NULL)
*phone = 0;
+ RemoveLtGt(out);
+
+ phone = _tcsstr(out, _T(";user=phone"));
+ if (phone != NULL)
+ *phone = 0;
+
+ if (_tcsnicmp(_T("sip:"), out, 4) == 0)
+ lstrcpyn(out, &out[4], outSize);
+
TCHAR *host = _tcschr(out, _T('@'));
- if (host != NULL && _tcsicmp(opts.host, host+1) == 0)
+ if (host != NULL && _tcsicmp(opts.domain, host+1) == 0)
*host = 0;
}
-void SIPProto::BuildURI(TCHAR *out, int outSize, const TCHAR *number, bool isTel)
+void SIPProto::BuildTelURI(TCHAR *out, int outSize, const TCHAR *number)
{
- bool hasSip = (_tcsnicmp(_T("sip:"), number, 4) == 0);
- bool hasHost = (_tcschr(number, _T('@')) != NULL);
+ BuildURI(out, outSize, number, NULL, 0, true);
+}
- if (isTel)
+
+void SIPProto::BuildURI(TCHAR *out, int outSize, const TCHAR *user, const TCHAR *aHost, int port, bool isTel)
+{
+ if (user == NULL)
{
- bool hasPhone = (_tcsstr(number, _T(";user=phone")) != NULL);
+ TCHAR *host = FirstNotEmpty((TCHAR *) aHost, opts.domain);
- if (!hasSip && !hasHost)
- {
- TCHAR tmp[1024];
- CleanupNumber(tmp, MAX_REGS(tmp), number);
- mir_sntprintf(out, outSize, _T("sip:%s@%s"), tmp, opts.host);
- }
+ if (port > 0)
+ mir_sntprintf(out, outSize, _T("<sip:%s:%d>"), host, port);
else
- mir_sntprintf(out, outSize, _T("sip:%s"), CleanupSip(number));
+ mir_sntprintf(out, outSize, _T("<sip:%s>"), host);
- if (!hasPhone)
- {
- int len = lstrlen(out);
- lstrcpyn(&out[len], _T(";user=phone"), outSize - len);
- }
+ return;
}
- else
+
+ TCHAR tmp[1024];
+ CleanupURI(tmp, MAX_REGS(tmp), user);
+
+ TCHAR *host = _tcschr(tmp, _T('@'));
+ if (host != NULL)
{
- if (!hasSip && !hasHost)
- mir_sntprintf(out, outSize, _T("sip:%s@%s"), number, opts.host);
- else
- mir_sntprintf(out, outSize, _T("sip:%s"), CleanupSip(number));
+ *host = 0;
+ host++;
}
+
+ if (host != NULL && aHost != NULL && lstrcmp(host, aHost) != 0)
+ Error(_T("Two conflicting hosts: %s / %s , ignoring one in argument"), host, aHost);
+
+ host = FirstNotEmpty(host, (TCHAR *) aHost, opts.domain);
+
+ if (port > 0)
+ mir_sntprintf(out, outSize, _T("<sip:%s@%s:%d>"), tmp, host, port);
+ else
+ mir_sntprintf(out, outSize, _T("<sip:%s@%s>"), tmp, host);
+
+ if (isTel)
+ {
+ int len = lstrlen(out);
+ lstrcpyn(&out[len], _T(";user=phone"), outSize - len);
+ }
}
@@ -1392,17 +1449,23 @@ int __cdecl SIPProto::VoiceCall(WPARAM wParam, LPARAM lParam)
TCHAR uri[1024];
- if (number != NULL)
+ if (!IsEmpty(number))
{
if (!VoiceCallStringValid((WPARAM) number, 0))
return 1;
- BuildURI(uri, MAX_REGS(uri), number, true);
+ BuildTelURI(uri, MAX_REGS(uri), number);
}
else
{
- // TODO
- return 2;
+ DBTString buddy(hContact, m_szModuleName, "URI");
+ if (buddy == NULL)
+ {
+ Error(_T("Contact %d has no URI!"), hContact);
+ return -1;
+ }
+
+ lstrcpyn(uri, buddy, MAX_REGS(uri));
}
pjsua_call_id call_id;
@@ -1559,7 +1622,7 @@ int __cdecl SIPProto::VoiceCallStringValid(WPARAM wParam, LPARAM lParam)
return 0;
TCHAR tmp[1024];
- BuildURI(tmp, MAX_REGS(tmp), number, true);
+ BuildTelURI(tmp, MAX_REGS(tmp), number);
return pjsua_verify_sip_url(TcharToUtf8(tmp)) == PJ_SUCCESS;
}
@@ -1573,7 +1636,7 @@ HANDLE __cdecl SIPProto::SearchBasic(const char *id)
return 0;
TCHAR tmp[1024];
- BuildURI(tmp, MAX_REGS(tmp), CharToTchar(id), false);
+ BuildURI(tmp, MAX_REGS(tmp), CharToTchar(id));
TCHAR *uri = mir_tstrdup(tmp);
ForkThread(&SIPProto::SearchUserThread, uri);
@@ -1629,7 +1692,7 @@ HANDLE __cdecl SIPProto::AddToList(int flags, PROTOSEARCHRESULT *psr)
return NULL;
TCHAR uri[1024];
- BuildURI(uri, MAX_REGS(uri), CharToTchar(psr->nick), false);
+ BuildURI(uri, MAX_REGS(uri), CharToTchar(psr->nick));
TcharToUtf8 sip_uri(uri);
HANDLE hContact;
@@ -1794,6 +1857,13 @@ void SIPProto::on_pager(char *from, char *text, char *mime_type)
}
+int __cdecl SIPProto::RecvMsg(HANDLE hContact, PROTORECVEVENT *pre)
+{
+ CCSDATA ccs = { hContact, PSR_MESSAGE, 0, (LPARAM) pre };
+ return CallService(MS_PROTO_RECVMSG, 0, (LPARAM) &ccs);
+}
+
+
int __cdecl SIPProto::SendMsg(HANDLE hContact, int flags, const char *msg)
{
if (m_iStatus <= ID_STATUS_OFFLINE)
@@ -1832,14 +1902,37 @@ int __cdecl SIPProto::SendMsg(HANDLE hContact, int flags, const char *msg)
// TODO Send to call
- status = pjsua_im_send(acc_id, &info.uri, NULL, &pj_str(text), NULL, NULL);
+ MessageData *md = new MessageData();
+ md->messageID = InterlockedIncrement(&messageID);
+ md->hContact = hContact;
+
+ status = pjsua_im_send(acc_id, &info.uri, NULL, &pj_str(text), NULL, md);
if (status != PJ_SUCCESS)
{
Error(status, _T("Error sending message"));
- return 0;
+ ForkThread(&SIPProto::FakeMsgAck, md);
}
- return 0;
+ return md->messageID;
+}
+
+
+void __cdecl SIPProto::FakeMsgAck(void *param)
+{
+ MessageData *md = (MessageData *) param;
+
+ Sleep(150);
+ on_pager_status(md->hContact, md->messageID, PJSIP_SC_BAD_REQUEST, Translate("Error sending message"));
+
+ delete md;
+}
+
+
+void SIPProto::on_pager_status(HANDLE hContact, LONG messageID, pjsip_status_code status, char *text)
+{
+ SendBroadcast(hContact, ACKTYPE_MESSAGE,
+ status != PJSIP_SC_OK ? ACKRESULT_FAILED : ACKRESULT_SUCCESS,
+ (HANDLE) messageID, (LPARAM) text);
}
@@ -1952,6 +2045,64 @@ static INT_PTR CALLBACK DlgProcAccMgrUI(HWND hwnd, UINT msg, WPARAM wParam, LPAR
{
SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
proto = (SIPProto *) lParam;
+
+ INT_PTR ret = SaveOptsDlgProc(proto->accountManagerCtrls, MAX_REGS(proto->accountManagerCtrls),
+ proto->m_szModuleName, hwnd, msg, wParam, lParam);
+
+ TCHAR username[1024];
+ if (lstrcmp(proto->opts.domain, proto->opts.registrar.host) == 0)
+ lstrcpyn(username, proto->opts.username, MAX_REGS(username));
+ else
+ mir_sntprintf(username, MAX_REGS(username), _T("%s@%s"),
+ proto->opts.username, proto->opts.domain);
+
+ SetDlgItemText(hwnd, IDC_USERNAME, username);
+ SendDlgItemMessage(hwnd, IDC_USERNAME, EM_LIMITTEXT, 1024, 0);
+
+ return ret;
+ }
+ case WM_COMMAND:
+ {
+ if (LOWORD(wParam) == IDC_USERNAME)
+ {
+ if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())
+ return 0;
+
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+
+ return 0;
+ }
+
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ LPNMHDR lpnmhdr = (LPNMHDR)lParam;
+
+ if (lpnmhdr->idFrom == 0 && lpnmhdr->code == PSN_APPLY)
+ {
+ INT_PTR ret = SaveOptsDlgProc(proto->accountManagerCtrls, MAX_REGS(proto->accountManagerCtrls),
+ proto->m_szModuleName, hwnd, msg, wParam, lParam);
+
+ TCHAR username[1024];
+ GetDlgItemText(hwnd, IDC_USERNAME, username, MAX_REGS(username));
+ TCHAR *host = _tcschr(username, _T('@'));
+ if (host != NULL)
+ {
+ *host = 0;
+ host++;
+ }
+
+ lstrcpyn(proto->opts.username, username, MAX_REGS(proto->opts.username));
+ DBWriteContactSettingTString(NULL, proto->m_szModuleName, "Username", proto->opts.username);
+
+ lstrcpyn(proto->opts.domain, FirstNotEmpty(host, proto->opts.registrar.host),
+ MAX_REGS(proto->opts.domain));
+ DBWriteContactSettingTString(NULL, proto->m_szModuleName, "Domain", proto->opts.domain);
+
+ return ret;
+ }
+
break;
}
}
diff --git a/Protocols/SIP/SIPProto.h b/Protocols/SIP/SIPProto.h
index 23e0cf9..be3864c 100644
--- a/Protocols/SIP/SIPProto.h
+++ b/Protocols/SIP/SIPProto.h
@@ -27,6 +27,13 @@ typedef INT_PTR (__cdecl SIPProto::*SIPServiceFunc)(WPARAM, LPARAM);
typedef INT_PTR (__cdecl SIPProto::*SIPServiceFuncParam)(WPARAM, LPARAM, LPARAM);
typedef int (__cdecl SIPProto::*SIPEventFunc)(WPARAM, LPARAM);
+struct MessageData
+{
+ HANDLE hContact;
+ LONG messageID;
+ pjsip_status_code status;
+};
+
struct SIPEvent
{
enum {
@@ -37,6 +44,7 @@ struct SIPEvent
incoming_subscribe,
buddy_state,
pager,
+ pager_status,
typing
} type;
@@ -48,6 +56,7 @@ struct SIPEvent
char *text;
char *mime;
bool isTyping;
+ MessageData *messageData;
};
class SIPProto : public PROTO_INTERFACE
@@ -58,18 +67,18 @@ private:
bool hasToDestroy;
pjsua_transport_id transport_id;
pjsua_acc_id acc_id;
+ LONG messageID;
public:
struct {
- TCHAR host[256];
- TCHAR realm[256];
TCHAR username[16];
+ TCHAR domain[256];
char password[16];
BYTE savePassword;
struct {
TCHAR host[256];
int port;
- } reg;
+ } registrar;
struct {
TCHAR host[256];
int port;
@@ -88,8 +97,8 @@ public:
CRITICAL_SECTION cs;
std::vector<SIPEvent> events;
- OptPageControl accountManagerCtrls[5];
- OptPageControl optionsCtrls[15];
+ OptPageControl accountManagerCtrls[4];
+ OptPageControl optionsCtrls[14];
SIPProto(const char *aProtoName, const TCHAR *aUserName);
virtual ~SIPProto();
@@ -122,7 +131,7 @@ public:
virtual int __cdecl RecvContacts( HANDLE hContact, PROTORECVEVENT* ) { return 1; }
virtual int __cdecl RecvFile( HANDLE hContact, PROTOFILEEVENT* ) { return 1; }
- virtual int __cdecl RecvMsg( HANDLE hContact, PROTORECVEVENT* ) { return 1; }
+ virtual int __cdecl RecvMsg( HANDLE hContact, PROTORECVEVENT* );
virtual int __cdecl RecvUrl( HANDLE hContact, PROTORECVEVENT* ) { return 1; }
virtual int __cdecl SendContacts( HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList ) { return 1; }
@@ -155,6 +164,7 @@ public:
void on_incoming_subscribe(char *from, char *text);
void on_buddy_state(pjsua_buddy_id buddy_id);
void on_pager(char *from, char *text, char *mime_type);
+ void on_pager_status(HANDLE hContact, LONG messageID, pjsip_status_code status, char *text);
void on_typing(char *from, bool isTyping);
bool IsMyContact(HANDLE hContact);
@@ -185,7 +195,8 @@ private:
INT_PTR __cdecl CreateAccMgrUI(WPARAM wParam, LPARAM lParam);
void ConfigureDevices();
- void BuildURI(TCHAR *out, int outSize, const TCHAR *number, bool isTel);
+ void BuildTelURI(TCHAR *out, int outSize, const TCHAR *number);
+ void BuildURI(TCHAR *out, int outSize, const TCHAR *user, const TCHAR *host = NULL, int port = 0, bool isTel = false);
void CleanupURI(TCHAR *out, int outSize, const TCHAR *url);
// Voice services
@@ -199,10 +210,12 @@ private:
int __cdecl VoiceCallStringValid(WPARAM wParam, LPARAM lParam);
// Buddy
+ void AddContactsToBuddyList();
void __cdecl SearchUserThread(void *param);
pjsua_buddy_id GetBuddy(HANDLE hContact);
HANDLE GetContact(pjsua_buddy_id buddy_id);
void Attach(HANDLE hContact, pjsua_buddy_id buddy_id);
+ void __cdecl FakeMsgAck(void *param);
// Static callbacks
static void CALLBACK DisconnectProto(void *param);
diff --git a/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.lib b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.lib
index e768fbc..49a691a 100644
--- a/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.lib
+++ b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Debug-Dynamic.lib
Binary files differ
diff --git a/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.lib b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.lib
index f67178c..5d9f093 100644
--- a/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.lib
+++ b/Protocols/SIP/lib/pjsip/lib/libpjproject-i386-Win32-vc8-Release-Static.lib
Binary files differ
diff --git a/Protocols/SIP/resource.h b/Protocols/SIP/resource.h
index daa7fb8..2cd12ae 100644
--- a/Protocols/SIP/resource.h
+++ b/Protocols/SIP/resource.h
@@ -2,21 +2,19 @@
// Microsoft Visual C++ generated include file.
// Used by resource.rc
//
-#define IDD_OPTIONS 119
#define IDD_OPTIONS_OLD 120
#define IDD_EMOTICON_SELECTION 126
#define IDD_ACCMGRUI 227
+#define IDD_OPTIONS 229
#define IDC_USERNAME 1000
#define IDC_PASSWORD 1001
#define IDC_NAME 1002
-#define IDC_REALM 1002
#define IDC_NUMBER 1003
#define IDC_PORT 1004
#define IDC_REG_PORT 1005
#define IDC_DNS_PORT 1006
#define IDC_STUN_PORT 1007
#define IDC_PROXY_PORT 1008
-#define IDC_HOST 1043
#define IDC_REG_HOST 1044
#define IDC_DNS_HOST 1045
#define IDC_STUN_HOST 1046
@@ -36,6 +34,7 @@
#define IDC_VIDEO 1088
#define IDC_PUBLISH2 1088
#define IDC_KEEPALIVE 1088
+#define IDC_DOMAIN 1091
#define IDC_STATIC -1
// Next default values for new objects
@@ -46,7 +45,7 @@
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 128
#define _APS_NEXT_COMMAND_VALUE 40005
-#define _APS_NEXT_CONTROL_VALUE 1088
+#define _APS_NEXT_CONTROL_VALUE 1092
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/Protocols/SIP/resource.rc b/Protocols/SIP/resource.rc
index 17ca10e..570661a 100644
--- a/Protocols/SIP/resource.rc
+++ b/Protocols/SIP/resource.rc
@@ -33,9 +33,9 @@ EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
LTEXT "Server:",IDC_STATIC,0,0,53,12,SS_CENTERIMAGE
- EDITTEXT IDC_HOST,54,0,92,12,ES_AUTOHSCROLL
+ EDITTEXT IDC_REG_HOST,54,0,92,12,ES_AUTOHSCROLL
CTEXT ":",IDC_STATIC,147,0,8,12,SS_CENTERIMAGE
- EDITTEXT IDC_PORT,155,0,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ EDITTEXT IDC_REG_PORT,155,0,30,12,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "Username:",IDC_STATIC,0,16,53,12,SS_CENTERIMAGE
EDITTEXT IDC_USERNAME,54,16,131,12,ES_AUTOHSCROLL
LTEXT "Password:",IDC_STATIC,0,31,53,12,SS_CENTERIMAGE
@@ -43,40 +43,38 @@ BEGIN
CONTROL "Save password",IDC_SAVEPASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,48,131,10
END
-IDD_OPTIONS DIALOGEX 0, 0, 216, 217
+IDD_OPTIONS DIALOGEX 0, 0, 216, 205
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
- GROUPBOX "SIP",IDC_STATIC,3,4,209,76
- LTEXT "Server:",IDC_STATIC,14,17,53,12,SS_CENTERIMAGE
- EDITTEXT IDC_HOST,68,17,131,12,ES_AUTOHSCROLL
- LTEXT "Username:",IDC_STATIC,14,33,53,12,SS_CENTERIMAGE
- EDITTEXT IDC_USERNAME,68,33,131,12,ES_AUTOHSCROLL
- LTEXT "Password:",IDC_STATIC,14,48,53,12,SS_CENTERIMAGE
+ GROUPBOX "SIP",-1,3,4,209,76
+ LTEXT "Username:",-1,14,17,53,12,SS_CENTERIMAGE
+ EDITTEXT IDC_USERNAME,68,17,131,12,ES_AUTOHSCROLL
+ LTEXT "Domain:",-1,14,33,53,12,SS_CENTERIMAGE
+ EDITTEXT IDC_DOMAIN,68,33,131,12,ES_AUTOHSCROLL
+ LTEXT "Password:",-1,14,48,53,12,SS_CENTERIMAGE
EDITTEXT IDC_PASSWORD,68,49,131,12,ES_PASSWORD | ES_AUTOHSCROLL
CONTROL "Save password",IDC_SAVEPASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,68,65,131,10
- GROUPBOX "Advanced",IDC_STATIC,3,84,209,126
- LTEXT "Registrar:",IDC_STATIC,14,99,53,12,SS_CENTERIMAGE
+ GROUPBOX "Advanced",-1,3,84,209,115
+ LTEXT "Registrar:",-1,14,99,53,12,SS_CENTERIMAGE
EDITTEXT IDC_REG_HOST,68,99,92,12,ES_AUTOHSCROLL
- CTEXT ":",IDC_STATIC,161,99,8,12,SS_CENTERIMAGE
+ CTEXT ":",-1,161,99,8,12,SS_CENTERIMAGE
EDITTEXT IDC_REG_PORT,169,99,30,12,ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "Auth Realm:",IDC_STATIC,14,115,53,12,SS_CENTERIMAGE
- EDITTEXT IDC_REALM,68,115,131,12,ES_AUTOHSCROLL
- LTEXT "DNS SRV:",IDC_STATIC,14,131,53,12,SS_CENTERIMAGE
+ LTEXT "Proxy Server:",-1,14,115,53,12,SS_CENTERIMAGE
+ EDITTEXT IDC_PROXY_HOST,68,115,92,12,ES_AUTOHSCROLL
+ CTEXT ":",-1,161,115,8,12,SS_CENTERIMAGE
+ EDITTEXT IDC_PROXY_PORT,169,115,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "DNS SRV:",-1,14,131,53,12,SS_CENTERIMAGE
EDITTEXT IDC_DNS_HOST,68,131,92,12,ES_AUTOHSCROLL
- CTEXT ":",IDC_STATIC,161,131,8,12,SS_CENTERIMAGE
+ CTEXT ":",-1,161,131,8,12,SS_CENTERIMAGE
EDITTEXT IDC_DNS_PORT,169,131,30,12,ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "STUN Server:",IDC_STATIC,14,147,53,12,SS_CENTERIMAGE
+ LTEXT "STUN Server:",-1,14,147,53,12,SS_CENTERIMAGE
EDITTEXT IDC_STUN_HOST,68,147,92,12,ES_AUTOHSCROLL
- CTEXT ":",IDC_STATIC,161,147,8,12,SS_CENTERIMAGE
+ CTEXT ":",-1,161,147,8,12,SS_CENTERIMAGE
EDITTEXT IDC_STUN_PORT,169,147,30,12,ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "Proxy Server:",IDC_STATIC,14,163,53,12,SS_CENTERIMAGE
- EDITTEXT IDC_PROXY_HOST,68,163,92,12,ES_AUTOHSCROLL
- CTEXT ":",IDC_STATIC,161,163,8,12,SS_CENTERIMAGE
- EDITTEXT IDC_PROXY_PORT,169,163,30,12,ES_AUTOHSCROLL | ES_NUMBER
- CONTROL "Publish status",IDC_PUBLISH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,181,185,10
- CTEXT "Leave empty to use default values",IDC_STATIC,14,197,185,12
+ CONTROL "Publish status",IDC_PUBLISH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,166,185,10
+ CONTROL "Send keep-alives",IDC_KEEPALIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,182,185,10
END
@@ -90,7 +88,7 @@ GUIDELINES DESIGNINFO
BEGIN
IDD_OPTIONS, DIALOG
BEGIN
- BOTTOMMARGIN, 216
+ BOTTOMMARGIN, 204
END
END
#endif // APSTUDIO_INVOKED