From d908076a8ec4e3f56db03ba3cd3b79c74e95b29d Mon Sep 17 00:00:00 2001 From: pescuma Date: Fri, 1 Jan 2010 14:24:20 +0000 Subject: sip: status messages git-svn-id: http://pescuma.googlecode.com/svn/trunk/Miranda@201 c086bb3d-8645-0410-b8da-73a8550f86e7 --- Protocols/SIP/SIPProto.cpp | 150 +++++++++++++++++++++++++++++++++++++-------- Protocols/SIP/SIPProto.h | 14 ++++- Protocols/SIP/commons.h | 2 +- 3 files changed, 135 insertions(+), 31 deletions(-) (limited to 'Protocols/SIP') 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 // Miranda headers -#define MIRANDA_VER 0x0900 +#define MIRANDA_VER 0x0800 #include #include #include -- cgit v1.2.3