summaryrefslogtreecommitdiff
path: root/Protocols/SIP
diff options
context:
space:
mode:
authorpescuma <pescuma@c086bb3d-8645-0410-b8da-73a8550f86e7>2010-01-01 14:24:20 +0000
committerpescuma <pescuma@c086bb3d-8645-0410-b8da-73a8550f86e7>2010-01-01 14:24:20 +0000
commitd908076a8ec4e3f56db03ba3cd3b79c74e95b29d (patch)
treef2ce01a2108f53ac70a3f3f009f1b18de8ce0659 /Protocols/SIP
parent1f309b3e73e5c8ee1194cb36c13f7c741cb17cd6 (diff)
sip: status messages
git-svn-id: http://pescuma.googlecode.com/svn/trunk/Miranda@201 c086bb3d-8645-0410-b8da-73a8550f86e7
Diffstat (limited to 'Protocols/SIP')
-rw-r--r--Protocols/SIP/SIPProto.cpp150
-rw-r--r--Protocols/SIP/SIPProto.h14
-rw-r--r--Protocols/SIP/commons.h2
3 files changed, 135 insertions, 31 deletions
diff --git a/Protocols/SIP/SIPProto.cpp b/Protocols/SIP/SIPProto.cpp
index 57aef07..c114e2c 100644
--- a/Protocols/SIP/SIPProto.cpp
+++ b/Protocols/SIP/SIPProto.cpp
@@ -162,6 +162,9 @@ SIPProto::SIPProto(const char *aProtoName, const TCHAR *aUserName)
hCallStateEvent = 0;
m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE;
messageID = 0;
+ awayMessageID = 0;
+
+ memset(awayMessages, 0, sizeof(awayMessages));
m_tszUserName = mir_tstrdup(aUserName);
m_szProtoName = mir_strdup(aProtoName);
@@ -224,6 +227,7 @@ SIPProto::SIPProto(const char *aProtoName, const TCHAR *aUserName)
DBDeleteContactSetting(hContact, m_szModuleName, "Status");
DBDeleteContactSetting(hContact, m_szModuleName, "ID");
+ DBDeleteContactSetting(hContact, "CList", "StatusMsg");
}
char setting[256];
@@ -244,6 +248,8 @@ SIPProto::SIPProto(const char *aProtoName, const TCHAR *aUserName)
CreateProtoService(PS_VOICE_SEND_DTMF, &SIPProto::VoiceSendDTMF);
CreateProtoService(PS_VOICE_CALL_STRING_VALID, &SIPProto::VoiceCallStringValid);
+ CreateProtoService(PS_GETMYAWAYMSG, &SIPProto::GetMyAwayMsg);
+
hCallStateEvent = CreateProtoEvent(PE_VOICE_CALL_STATE);
HookProtoEvent(ME_OPT_INITIALISE, &SIPProto::OnOptionsInit);
@@ -806,15 +812,34 @@ void SIPProto::AddContactsToBuddyList()
}
-int __cdecl SIPProto::SetStatus( int iNewStatus )
+int SIPProto::ConvertStatus(int status)
+{
+ switch(status)
+ {
+ case ID_STATUS_ONLINE: return ID_STATUS_ONLINE;
+ case ID_STATUS_AWAY: return ID_STATUS_AWAY;
+ case ID_STATUS_DND: return ID_STATUS_OCCUPIED;
+ case ID_STATUS_NA: return ID_STATUS_AWAY;
+ case ID_STATUS_OCCUPIED: return ID_STATUS_OCCUPIED;
+ case ID_STATUS_FREECHAT: return ID_STATUS_ONLINE;
+ case ID_STATUS_INVISIBLE: return ID_STATUS_INVISIBLE;
+ case ID_STATUS_ONTHEPHONE: return ID_STATUS_AWAY;
+ case ID_STATUS_OUTTOLUNCH: return ID_STATUS_AWAY;
+ default: return ID_STATUS_OFFLINE;
+ }
+}
+
+
+int __cdecl SIPProto::SetStatus(int iNewStatus)
{
- if (m_iStatus == iNewStatus)
+ if (m_iDesiredStatus == iNewStatus)
return 0;
m_iDesiredStatus = iNewStatus;
if (m_iDesiredStatus == ID_STATUS_OFFLINE)
{
- Disconnect();
+ if (m_iStatus != ID_STATUS_OFFLINE)
+ Disconnect();
}
else if (m_iStatus == ID_STATUS_OFFLINE)
{
@@ -822,8 +847,8 @@ int __cdecl SIPProto::SetStatus( int iNewStatus )
}
else if (m_iStatus > ID_STATUS_OFFLINE)
{
- SendPresence(m_iDesiredStatus);
- BroadcastStatus(m_iDesiredStatus);
+ BroadcastStatus(ConvertStatus(m_iDesiredStatus));
+ SendPresence();
}
return 0;
@@ -1102,13 +1127,13 @@ void SIPProto::NotifyCall(pjsua_call_id call_id, int state, HANDLE hContact, TCH
}
-bool SIPProto::SendPresence(int proto_status)
+bool SIPProto::SendPresence(int aStatus)
{
pjsua_acc_info info;
- pj_status_t status = pjsua_acc_get_info(acc_id, &info);
- if (status != PJ_SUCCESS)
+ pj_status_t st = pjsua_acc_get_info(acc_id, &info);
+ if (st != PJ_SUCCESS)
{
- Error(status, _T("Error obtaining call info"));
+ Error(st, _T("Error obtaining call info"));
return false;
}
@@ -1119,7 +1144,9 @@ bool SIPProto::SendPresence(int proto_status)
pj_bzero(&elem, sizeof(elem));
elem.type = PJRPID_ELEMENT_TYPE_PERSON;
- switch(proto_status)
+ int status = FirstGtZero(aStatus, m_iStatus);
+
+ switch(status)
{
case ID_STATUS_AWAY:
elem.activity = PJRPID_ACTIVITY_AWAY;
@@ -1132,9 +1159,10 @@ bool SIPProto::SendPresence(int proto_status)
break;
}
- elem.note = pj_str(""); // TODO
+ TcharToSip sip_msg(GetAwayMsg(FirstGtZero(aStatus, m_iDesiredStatus)));
+ elem.note = pj_str(sip_msg);
- pj_bool_t online = (proto_status == ID_STATUS_INVISIBLE ? PJ_FALSE : PJ_TRUE);
+ pj_bool_t online = (status == ID_STATUS_INVISIBLE ? PJ_FALSE : PJ_TRUE);
if (online == info.online_status && pj_strcmp(&info.online_status_text, &elem.note) == 0)
return false;
@@ -1162,9 +1190,8 @@ void SIPProto::on_reg_state()
{
int oldStatus = m_iStatus;
- int status = (m_iDesiredStatus > ID_STATUS_OFFLINE ? m_iDesiredStatus : ID_STATUS_ONLINE);
- SendPresence(status);
- BroadcastStatus(status);
+ BroadcastStatus(ConvertStatus(m_iDesiredStatus));
+ SendPresence();
if (oldStatus <= ID_STATUS_OFFLINE)
{
@@ -1801,8 +1828,6 @@ void SIPProto::on_buddy_state(pjsua_buddy_id buddy_id)
return;
}
- // TODO info.rpid
-
switch(info.status)
{
case PJSUA_BUDDY_STATUS_ONLINE:
@@ -1865,23 +1890,17 @@ void SIPProto::on_pager(char *from, char *text, char *mime_type)
if (strlen(text) < 1)
return;
- pjsua_buddy_id buddy_id = pjsua_buddy_find(&pj_str(from));
- if (buddy_id == PJSUA_INVALID_ID)
+ if (strcmp("text/plain", mime_type) != 0)
{
- // TODO
+ Error(_T("Unknown mime type in message from %s: %s"),
+ SipToTchar(pj_str(from)).get(), SipToTchar(pj_str(mime_type)).get());
return;
}
- HANDLE hContact = GetContact(buddy_id);
+ HANDLE hContact = GetContact(SipToTchar(pj_str(from)), true, true);
if (hContact == NULL)
return;
- if (strcmp("text/plain", mime_type) != 0)
- {
- Error(_T("Unknown mime type: %s"), Utf8ToTchar(mime_type));
- return;
- }
-
CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, 0);
PROTORECVEVENT pre;
@@ -2292,6 +2311,83 @@ int __cdecl SIPProto::OnContactDeleted(WPARAM wParam, LPARAM lParam)
}
+// Away message /////////////////////////////////////////////////////////////////////////
+
+struct AwayMsgInfo
+{
+ LONG id;
+ HANDLE hContact;
+};
+
+void __cdecl SIPProto::GetAwayMsgThread(void* arg)
+{
+ Sleep(150);
+
+ AwayMsgInfo *inf = (AwayMsgInfo *) arg;
+
+ DBTString msg(inf->hContact, "CList", "StatusMsg");
+ if (msg != NULL)
+ SendBroadcast(inf->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)inf->id, (LPARAM) TcharToChar(msg).get());
+ else
+ SendBroadcast(inf->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)inf->id, (LPARAM) "");
+
+ mir_free(inf);
+}
+
+HANDLE __cdecl SIPProto::GetAwayMsg(HANDLE hContact)
+{
+ AwayMsgInfo *inf = (AwayMsgInfo*) mir_alloc(sizeof(AwayMsgInfo));
+ inf->hContact = hContact;
+ inf->id = InterlockedIncrement(&awayMessageID);
+
+ ForkThread(&SIPProto::GetAwayMsgThread, inf);
+ return (HANDLE) inf->id;
+}
+
+
+int __cdecl SIPProto::SetAwayMsg(int status, const char *msga)
+{
+ int pos = status - ID_STATUS_ONLINE;
+ if (pos < 0 || pos >= MAX_REGS(awayMessages))
+ return 1;
+
+ CharToTchar msg(msga);
+ if (lstrcmp(FirstNotEmpty((TCHAR *)msg.get(), _T("")), FirstNotEmpty(awayMessages[pos], _T(""))) == 0)
+ return 0;
+
+ mir_free(awayMessages[pos]);
+ awayMessages[pos] = msg.detach();
+
+ if (ConvertStatus(status) == m_iStatus)
+ SendPresence();
+
+ return 0;
+}
+
+
+INT_PTR __cdecl SIPProto::GetMyAwayMsg(WPARAM wParam, LPARAM lParam)
+{
+ TCHAR *msg = GetAwayMsg(wParam ? wParam : m_iStatus);
+ return (lParam & SGMA_UNICODE) ? (INT_PTR) mir_t2u(msg)
+ : (INT_PTR) mir_t2a(msg);
+}
+
+
+TCHAR *SIPProto::GetAwayMsg(int status)
+{
+ if (status == ID_STATUS_INVISIBLE)
+ return _T("");
+
+ int pos = status - ID_STATUS_ONLINE;
+ if (pos < 0 || pos >= MAX_REGS(awayMessages))
+ return _T("");
+ else if (awayMessages[pos] == NULL)
+ return _T("");
+ else
+ return awayMessages[pos];
+}
+
+
// Dialog procs /////////////////////////////////////////////////////////////////////////
diff --git a/Protocols/SIP/SIPProto.h b/Protocols/SIP/SIPProto.h
index ff50de7..5c449de 100644
--- a/Protocols/SIP/SIPProto.h
+++ b/Protocols/SIP/SIPProto.h
@@ -69,6 +69,8 @@ private:
pjsua_transport_id transport_id;
pjsua_acc_id acc_id;
LONG messageID;
+ LONG awayMessageID;
+ TCHAR *awayMessages[ID_STATUS_OUTTOLUNCH - ID_STATUS_ONLINE + 1];
public:
struct {
@@ -144,10 +146,10 @@ public:
virtual int __cdecl SetStatus( int iNewStatus );
- virtual HANDLE __cdecl GetAwayMsg( HANDLE hContact ) { return 0; }
+ virtual HANDLE __cdecl GetAwayMsg( HANDLE hContact );
virtual int __cdecl RecvAwayMsg( HANDLE hContact, int mode, PROTORECVEVENT* evt ) { return 1; }
virtual int __cdecl SendAwayMsg( HANDLE hContact, HANDLE hProcess, const char* msg ) { return 1; }
- virtual int __cdecl SetAwayMsg( int iStatus, const char* msg ) { return 1; }
+ virtual int __cdecl SetAwayMsg( int iStatus, const char* msg );
virtual int __cdecl UserIsTyping( HANDLE hContact, int type );
@@ -171,6 +173,7 @@ public:
bool IsMyContact(HANDLE hContact);
private:
+ int ConvertStatus(int status);
void BroadcastStatus(int newStatus);
void CreateProtoService(const char *szService, SIPServiceFunc serviceProc);
void CreateProtoService(const char *szService, SIPServiceFuncParam serviceProc, LPARAM lParam);
@@ -190,7 +193,7 @@ private:
void Error(pj_status_t status, TCHAR *fmt, ...);
void ShowMessage(int type, TCHAR *fmt, va_list args);
- bool SendPresence(int status);
+ bool SendPresence(int status = 0);
int Connect();
void Disconnect();
INT_PTR __cdecl CreateAccMgrUI(WPARAM wParam, LPARAM lParam);
@@ -221,6 +224,11 @@ private:
void Attach(HANDLE hContact, pjsua_buddy_id buddy_id);
void __cdecl FakeMsgAck(void *param);
+ // Away messages
+ void __cdecl GetAwayMsgThread(void* arg);
+ TCHAR *GetAwayMsg(int status);
+ INT_PTR __cdecl GetMyAwayMsg(WPARAM wParam, LPARAM lParam);
+
// Static callbacks
static void CALLBACK DisconnectProto(void *param);
};
diff --git a/Protocols/SIP/commons.h b/Protocols/SIP/commons.h
index e881107..4112a0b 100644
--- a/Protocols/SIP/commons.h
+++ b/Protocols/SIP/commons.h
@@ -34,7 +34,7 @@ Boston, MA 02111-1307, USA.
#include <list>
// Miranda headers
-#define MIRANDA_VER 0x0900
+#define MIRANDA_VER 0x0800
#include <win2k.h>
#include <newpluginapi.h>
#include <m_system.h>