source: qutecom-2.2/libs/sipwrapper/src/phapi/PhApiCallbacks.cpp @ 447:e8e3b471e274

Last change on this file since 447:e8e3b471e274 was 447:e8e3b471e274, checked in by laurent@…, 3 years ago

Show error codes in a more fashion way

File size: 28.5 KB
Line 
1/*
2 * WengoPhone, a voice over Internet phone
3 * Copyright (C) 2004-2007  Wengo
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20#include "PhApiCallbacks.h"
21
22#include "PhApiWrapper.h"
23#include "PhApiIMChat.h"
24
25#include <sipwrapper/WebcamVideoFrame.h>
26
27#include <sipwrapper/SipWrapper.h>
28#include <imwrapper/IMPresence.h>
29#include <imwrapper/EnumPresenceState.h>
30#include <imwrapper/IMChatSession.h>
31
32#include <util/StringList.h>
33#include <util/Logger.h>
34
35#ifdef ENABLE_VIDEO
36        #include <pixertool/pixertool.h>
37#endif
38
39#include <tinyxml.h>
40
41using namespace std;
42
43extern "C" {
44
45        static int phApiEventsHandler(OWPL_EVENT_CATEGORY category, void* pInfo, void* pUserData) {
46                switch(category) {
47                        case EVENT_CATEGORY_CALLSTATE :
48                                PhApiCallbacks::getInstance().callProgress((OWPL_CALLSTATE_INFO *)pInfo);
49                                break;
50
51                        case EVENT_CATEGORY_LINESTATE :
52                                PhApiCallbacks::getInstance().registerProgress((OWPL_LINESTATE_INFO *)pInfo);
53                                break;
54
55                        case EVENT_CATEGORY_MESSAGE :
56                                PhApiCallbacks::getInstance().messageProgress((OWPL_MESSAGE_INFO *)pInfo);
57                                break;
58
59                        case EVENT_CATEGORY_SUB_STATUS :
60                                PhApiCallbacks::getInstance().subscriptionProgress((OWPL_SUBSTATUS_INFO *)pInfo);
61                                break;
62
63                        case EVENT_CATEGORY_NOTIFY :
64                                PhApiCallbacks::getInstance().onNotify((OWPL_NOTIFICATION_INFO *)pInfo);
65                                break;
66
67                        case EVENT_CATEGORY_ERROR :
68                                PhApiCallbacks::getInstance().errorNotify((OWPL_ERROR_INFO *)pInfo);
69                                break;
70
71                        default :
72                                break;
73                }
74
75                return 0;
76        }
77
78}
79
80PhApiCallbacks::PhApiCallbacks() {}
81
82PhApiCallbacks::~PhApiCallbacks() {}
83
84void PhApiCallbacks::startListeningPhApiEvents() {
85        owplEventListenerAdd(phApiEventsHandler, NULL);
86}
87
88void PhApiCallbacks::callProgress(OWPL_CALLSTATE_INFO * info) {
89        if(info != NULL) {
90                PhApiWrapper * p = PhApiWrapper::PhApiWrapperHack;
91                std::string from;
92                phVideoFrameReceivedEvent_t * video_data = NULL;
93                switch(info->event) {
94                        case CALLSTATE_UNKNOWN :
95                                break;
96
97                        case CALLSTATE_NEWCALL :
98                                switch(info->cause) {
99                                        case CALLSTATE_NEW_CALL_NORMAL :
100                                                break;
101
102                                        case CALLSTATE_NEW_CALL_TRANSFERRED :
103                                                break;
104
105                                        case CALLSTATE_NEW_CALL_TRANSFER :
106                                                break;
107
108                                        default :
109                                                break;
110                                }
111                                break;
112
113                        case CALLSTATE_REMOTE_OFFERING :
114                                switch(info->cause) {
115                                        case CALLSTATE_REMOTE_OFFERING_NORMAL :
116                                                if (!info->szRemoteIdentity) {
117                                                        from = "unknown@unknown.unknown";
118                                                }
119                                                else {
120                                                        from = info->szRemoteIdentity;
121                                                }
122
123                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateDialing, from);
124                                                break;
125
126                                        default :
127                                                break;
128                                }
129                                break;
130
131                        case CALLSTATE_REMOTE_ALERTING :
132                                switch(info->cause) {
133                                        case CALLSTATE_REMOTE_ALERTING_NORMAL :
134                                                if (!info->szRemoteIdentity) {
135                                                        from = "unknown@unknown.unknown";
136                                                }
137                                                else {
138                                                        from = info->szRemoteIdentity;
139                                                }
140                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateRinging, from);
141                                                break;
142
143                                        case CALLSTATE_REMOTE_ALERTING_MEDIA_START :
144                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateRingingStart, from);
145                                                break;
146
147                                        case CALLSTATE_REMOTE_ALERTING_MEDIA_STOP :
148                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateRingingStop, from);
149                                                break;
150
151                                        default :
152                                                break;
153                                }
154                                break;
155
156                        case CALLSTATE_CONNECTED :
157                                switch(info->cause) {
158                                        case CALLSTATE_CONNECTED_ACTIVE :
159                                                if (!info->szRemoteIdentity) {
160                                                        from = "unknown@unknown.unknown";
161                                                }
162                                                else {
163                                                        from = info->szRemoteIdentity;
164                                                }
165
166                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateTalking, from);
167                                                break;
168
169                                        case CALLSTATE_CONNECTED_ACTIVE_HELD :
170                                                break;
171
172                                        case CALLSTATE_CONNECTED_INACTIVE :
173                                                break;
174
175                                        default :
176                                                break;
177                                }
178                                break;
179
180                        case CALLSTATE_DISCONNECTED :
181                                switch(info->cause) {
182                                        case CALLSTATE_DISCONNECTED_BADADDRESS :
183                                                break;
184
185                                        case CALLSTATE_DISCONNECTED_BUSY :
186                                                if (!info->szRemoteIdentity) {
187                                                        from = "unknown@unknown.unknown";
188                                                }
189                                                else {
190                                                        from = info->szRemoteIdentity;
191                                                }
192                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateBusy, from);
193                                                break;
194
195                                        case CALLSTATE_DISCONNECTED_REJECTED :
196                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateRejected, from);
197                                                break;
198
199                                        case CALLSTATE_DISCONNECTED_USER_NOT_FOUND :
200                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateUserNotFound, from);
201                                                break;
202
203                                        case CALLSTATE_DISCONNECTED_USER_NOT_AVAILABLE :
204                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateUserNotAvailable, from);
205                                                break;
206
207                                        case CALLSTATE_DISCONNECTED_NORMAL :
208                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateClosed, from);
209                                                break;
210
211                                        case CALLSTATE_DISCONNECTED_RESOURCES :
212                                                break;
213
214                                        case CALLSTATE_DISCONNECTED_NETWORK :
215                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateError, from);
216                                                break;
217
218                                        case CALLSTATE_DISCONNECTED_REDIRECTED :
219                                                break;
220
221                                        case CALLSTATE_DISCONNECTED_NO_RESPONSE :
222                                                from = info->szRemoteIdentity;
223                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateClosed, from);
224                                                break;
225
226                                        case CALLSTATE_DISCONNECTED_AUTH :
227                                                break;
228
229                                        case CALLSTATE_DISCONNECTED_UNKNOWN :
230                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateError, from);
231                                                break;
232
233                                        default :
234                                                break;
235                                }
236                                break;
237
238                        case CALLSTATE_OFFERING :
239                                switch(info->cause) {
240                                        case CALLSTATE_OFFERING_ACTIVE :
241                                                if (!info->szRemoteIdentity) {
242                                                        from = "unknown@unknown.unknown";
243                                                }
244                                                else {
245                                                        from = info->szRemoteIdentity;
246                                                }
247                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateIncoming, from);
248                                                break;
249
250                                        default :
251                                                break;
252                                }
253                                break;
254
255                        case CALLSTATE_ALERTING :
256                                switch(info->cause) {
257                                        case CALLSTATE_ALERTING_NORMAL :
258                                                break;
259
260                                        default :
261                                                break;
262                                }
263                                break;
264
265                        case CALLSTATE_DESTROYED :
266                                switch(info->cause) {
267                                        case CALLSTATE_DESTROYED_NORMAL :
268                                                break;
269
270                                        default :
271                                                break;
272                                }
273                                break;
274
275                        case CALLSTATE_AUDIO_EVENT :
276                                switch(info->cause) {
277                                        case CALLSTATE_AUDIO_START :
278                                                break;
279
280                                        case CALLSTATE_AUDIO_STOP :
281                                                break;
282
283                                        case CALLSTATE_AUDIO_DTMF :
284                                                break;
285
286                                        default :
287                                                break;
288                                }
289                                break;
290
291                        case CALLSTATE_VIDEO_EVENT :
292                                switch(info->cause) {
293                                        case CALLSTATE_VIDEO_START :
294                                                break;
295
296                                        case CALLSTATE_VIDEO_STOP :
297                                                break;
298
299                                        case CALLSTATE_VIDEO_FRAME_RCV :
300                                                if(info->pData != NULL) {
301                                                        video_data = (phVideoFrameReceivedEvent_t *) info->pData;
302#ifdef ENABLE_VIDEO
303                                                        if(video_data != NULL) {
304                                                                p->videoFrameReceivedEvent(*p, info->hCall, video_data->frame_remote, video_data->frame_local);
305                                                        }
306#endif
307                                                }
308                                                break;
309
310                                        default :
311                                                break;
312                                }
313                                break;
314
315                        case CALLSTATE_TRANSFER :
316                                switch(info->cause) {
317                                        case CALLSTATE_TRANSFER_INITIATED :
318                                                break;
319
320                                        case CALLSTATE_TRANSFER_ACCEPTED :
321                                                break;
322
323                                        case CALLSTATE_TRANSFER_TRYING :
324                                                break;
325
326                                        case CALLSTATE_TRANSFER_RINGING :
327                                                break;
328
329                                        case CALLSTATE_TRANSFER_SUCCESS :
330                                                break;
331
332                                        case CALLSTATE_TRANSFER_FAILURE :
333                                                break;
334
335                                        default :
336                                                break;
337                                }
338                                break;
339
340                        case CALLSTATE_REDIRECTED :
341                                switch(info->cause) {
342                                        case CALLSTATE_REDIRECTED_NORMAL :
343                                                from = info->szRemoteIdentity;
344                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateRedirected, from);
345                                                break;
346
347                                        default :
348                                                break;
349                                }
350                                break;
351
352                        case CALLSTATE_HOLD :
353                                switch(info->cause) {
354                                        case CALLSTATE_HOLD_STARTED :
355                                                from = info->szRemoteIdentity;
356                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateHold, from);
357                                                break;
358
359                                        case CALLSTATE_HOLD_RESUMED :
360                                                from = info->szRemoteIdentity;
361                                                p->phoneCallStateChangedEvent(*p, info->hCall, EnumPhoneCallState::PhoneCallStateResumed, from);
362                                                break;
363
364                                        default :
365                                                break;
366                                }
367                                break;
368
369                        case CALLSTATE_SECURITY_EVENT :
370                                switch(info->cause) {
371                                        case CALLSTATE_SECURITY_SELF_SIGNED_CERT :
372                                                break;
373
374                                        case CALLSTATE_SECURITY_SESSION_NOT_SECURED :
375                                                break;
376
377                                        case CALLSTATE_SECURITY_REMOTE_SMIME_UNSUPPORTED :
378                                                break;
379
380                                        default :
381                                                break;
382                                }
383                                break;
384
385                        case CALLSTATE_IDENTITY_CHANGE :
386                                switch(info->cause) {
387                                        case CALLSTATE_IDENTITY_CHANGE_UNKNOWN :
388                                                break;
389
390                                        default :
391                                                break;
392                                }
393                                break;
394
395                        default :
396                                break;
397                }
398        }
399}
400
401void PhApiCallbacks::registerProgress(OWPL_LINESTATE_INFO * info) {
402        PhApiWrapper * p = PhApiWrapper::PhApiWrapperHack;
403        switch(info->event) {
404                case LINESTATE_UNKNOWN :
405                        p->setRegistered(false);
406                        p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateUnknown);
407                        break;
408
409                case LINESTATE_REGISTERING :
410                        switch(info->cause) {
411                                case LINESTATE_CAUSE_NORMAL :
412                                        break;
413
414                                default :
415                                        break;
416                        }
417                        break;
418
419                case LINESTATE_REGISTERED :
420                        switch(info->cause) {
421                                case LINESTATE_CAUSE_NORMAL :
422                                if(!p->isRegistered()) {
423                                        p->setRegistered(true);
424                                        p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateOk);
425                                        p->connectedEvent(*p);
426                                        for (std::set<std::string>::const_iterator it = p->getSubscribedContacts().begin();
427                                                it != p->getSubscribedContacts().end();
428                                                ++it) {
429                                                        p->subscribeToPresenceOf(*it);
430                                        }
431                                }
432                                break;
433
434                                default :
435                                break;
436                        }
437                        break;
438
439                case LINESTATE_UNREGISTERING :
440                        switch(info->cause) {
441                                case LINESTATE_CAUSE_NORMAL :
442                                        break;
443
444                                default :
445                                        break;
446                        }
447                        break;
448
449                case LINESTATE_UNREGISTERED :
450                        switch(info->cause) {
451                                case LINESTATE_CAUSE_NORMAL :
452                                        p->setRegistered(false);
453                                        p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateClosed);
454                                        break;
455
456                                default :
457                                        break;
458                        }
459                        break;
460
461                case LINESTATE_REGISTER_FAILED :
462                        switch(info->cause) {
463                                case LINESTATE_CAUSE_COULD_NOT_CONNECT :
464                                        if (p->isRegistered()) {
465                                                p->setRegistered(false);
466                                                p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateTimeout);
467                                                p->disconnectedEvent(*p, true, "No response from server");
468                                        }
469                                        break;
470
471                                case LINESTATE_CAUSE_NOT_AUTHORIZED :
472                                        p->setRegistered(false);
473                                        p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateAuthenticationError);
474                                        p->disconnectedEvent(*p, true, "Bad login or password");
475                                        break;
476
477                                case LINESTATE_CAUSE_TIMEOUT :
478                                        p->setRegistered(false);
479                                        p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateTimeout);
480                                        p->disconnectedEvent(*p, true, "No response from server");
481                                        break;
482
483                                case LINESTATE_CAUSE_NOT_FOUND :
484                                        p->setRegistered(false);
485                                        p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateAuthenticationError);
486                                        p->disconnectedEvent(*p, true, "Bad login or password");
487                                        break;
488
489                                default :
490                                        p->setRegistered(false);
491                                        LOG_ERROR("unknown phApi event");
492                                        p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateServerError);
493                                        p->disconnectedEvent(*p, true, "No response from server");
494                                        break;
495                        }
496                        for (std::set<std::string>::const_iterator it = p->getSubscribedContacts().begin();
497                                it != p->getSubscribedContacts().end(); ++it) {
498                                p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateUnknown, "", *it);
499                        }
500                        break;
501
502                case LINESTATE_UNREGISTER_FAILED :
503                        p->setRegistered(false);
504                        switch(info->cause) {
505                                /*
506                                case LINESTATE_CAUSE_COULD_NOT_CONNECT:
507                                        break;
508
509                                case LINESTATE_CAUSE_NOT_AUTHORIZED:
510                                        break;
511                                */
512                                case LINESTATE_CAUSE_TIMEOUT:
513                                        //p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateTimeout);
514                                        break;
515                                /*
516                                case LINESTATE_CAUSE_NOT_FOUND:
517                                        break;
518                                */
519                                default :
520                                        p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateClosed);
521                                        break;
522                        }
523                        break;
524
525                case LINESTATE_PROVISIONED :
526                        switch(info->cause) {
527                                case LINESTATE_CAUSE_NORMAL :
528                                        break;
529
530                                default :
531                                        break;
532                        }
533                        break;
534
535                default :
536                        p->setRegistered(false);
537                        LOG_ERROR("unknown phApi event");
538                        p->phoneLineStateChangedEvent(*p, info->hLine, EnumPhoneLineState::PhoneLineStateServerError);
539                        break;
540        }
541}
542
543void PhApiCallbacks::messageProgress(OWPL_MESSAGE_INFO * info) {
544        PhApiWrapper * p = PhApiWrapper::PhApiWrapperHack;
545
546        if ((info->event == MESSAGE_SUCCESS && info->cause == MESSAGE_SUCCESS_NORMAL) ||
547                (info->event == MESSAGE_FAILURE && info->cause == MESSAGE_FAILURE_UNKNOWN)){
548                //We drop status message
549                return;
550        }
551
552        std::string content;
553        if(info->szContent) {
554                content = info->szContent;
555        }
556
557        // Wengo case: somebody <sip:somebody@voip.wengo.fr>;tag=b6e249633711def8c2dbe3c2d4f39996-e1d6
558        // Standard case: "Mister somebody" <sip:somebody@sipprovider.com>;tag=b6e249633711def1d6
559        String from = p->parseFromHeader(std::string(info->szRemoteIdentity));
560        String alias = p->getDisplayNameFromHeader(std::string(info->szRemoteIdentity));
561
562        std::string ctype;
563        if (info->szContentType) {
564                ctype = info->szContentType;
565        }
566
567        std::string subtype;
568        if (info->szSubContentType) {
569                subtype = info->szSubContentType;
570        }
571
572        //Getting buddy icon
573        if ((info->event == MESSAGE_NEW) && (ctype == "buddyicon")) {
574                if (!subtype.empty()) {
575                        p->contactIconChangedEvent(*p, from, subtype);
576                }
577                return;
578        }
579
580        // Is there already an IMChatSession with this contact?
581        IMChatSession *imChatSession = p->getIMChatSession(from);
582
583        //Drop typingstate packet if there is no chat session created
584        if (!imChatSession && (ctype == "typingstate" || (ctype == "application" && subtype == "im-iscomposing+xml"))) {
585                return;
586        } else if (!imChatSession) {
587                LOG_DEBUG("creating new IMChatSession");
588                imChatSession = new IMChatSession(*PhApiIMChat::PhApiIMChatHack);
589                p->addContact(*imChatSession, from,alias);
590                p->newIMChatSessionCreatedEvent(*p, *imChatSession);
591                p->sendMyIcon(from, p->_iconFilename);
592        }
593
594        switch(info->event) {
595        case MESSAGE_NEW : {
596
597                if (ctype == "typingstate") {
598                        IMChat::TypingState state;
599
600                        if (subtype == "typing") {
601                                state = IMChat::TypingStateTyping;
602                        } else if (subtype == "stoptyping") {
603                                state = IMChat::TypingStateStopTyping;
604                        } else {
605                                state = IMChat::TypingStateNotTyping;
606                        }
607
608                        p->typingStateChangedEvent(*p, *imChatSession, from, state);
609                } else if (ctype == "application" && subtype == "im-iscomposing+xml") {
610                        IMChat::TypingState state;
611
612                        TiXmlDocument doc;
613                        doc.Parse(content.c_str());
614                        TiXmlHandle docHandle(&doc);
615                        TiXmlText * basicText = docHandle.FirstChild("isComposing").FirstChild("state").FirstChild().Text();
616                        if (basicText) {
617                                std::string basic = basicText->Value();
618                                if (String(basic).toLowerCase() == "active") {
619                                        state = IMChat::TypingStateTyping;
620                                } else if (String(basic).toLowerCase() == "idle") {
621                                        state = IMChat::TypingStateStopTyping;
622                                } else {
623                                        state = IMChat::TypingStateNotTyping;
624                                }
625                        } else {
626                                state = IMChat::TypingStateNotTyping;
627                        }
628                        p->typingStateChangedEvent(*p, *imChatSession, from, state);
629                } else {
630                        // once a message is received, typing is inferred off
631                        p->typingStateChangedEvent(*p, *imChatSession, from, IMChat::TypingStateNotTyping);
632                        p->messageReceivedEvent(*p, *imChatSession, from, content);
633                }
634
635                break;
636        case MESSAGE_FAILURE :
637                LOG_DEBUG("message could not be sent");
638                p->statusMessageReceivedEvent(*p, *imChatSession, PhApiIMChat::StatusMessageError, content);
639                break;
640        }
641
642        default:
643                LOG_WARN("unknown message event=" + String::fromNumber(info->event));
644        }
645}
646
647/*
648TODO for future use ?
649void PhApiCallbacks::messageProgress(OWPL_MESSAGE_INFO * info) {
650        PhApiWrapper * p = PhApiWrapper::PhApiWrapperHack;
651        IMChatSession * imChatSession;
652        string from;
653        int atPos = 0;
654        std::string buddyIcon;
655        std::map<const std::string, IMChatSession *>::const_iterator sessionIt;
656        switch(info->event) {
657                case MESSAGE_UNKNOWN :
658                        break;
659
660                case MESSAGE_NEW :
661                        switch(info->cause) {
662                                case MESSAGE_NEW_NORMAL :
663                                        LOG_DEBUG("message received from=" + std::string(info->szRemoteIdentity) + " content=" + std::string(info->szContent));
664                                        from = String(info->szRemoteIdentity).split(" ")[0];
665                                        sessionIt = contactChatMap.find(from);
666                                        if (sessionIt != contactChatMap.end()) {
667                                                imChatSession = (*sessionIt).second;
668                                        } else {
669                                                LOG_DEBUG("creating new IMChatSession");
670                                                imChatSession = new IMChatSession(*PhApiIMChat::PhApiIMChatHack);
671                                                contactChatMap[from] = imChatSession;
672                                                p->addContact(*imChatSession, from);
673                                                p->newIMChatSessionCreatedEvent(*p, *imChatSession);
674                                                p->sendMyIcon(from, p->_iconFilename);
675                                        }
676                                        p->messageReceivedEvent(*p, *imChatSession, from, std::string(info->szContent));
677                                        break;
678
679                                case MESSAGE_NEW_BUDDY_ICON :
680                                        LOG_DEBUG("message received from=" + std::string(info->szRemoteIdentity) + " content=" + std::string(info->szContent));
681                                        from = String(info->szRemoteIdentity).split(" ")[0];
682                                        buddyIcon = info->szSubContentType;
683                                        if(!buddyIcon.empty()) {
684                                                p->contactIconChangedEvent(*p, from, buddyIcon);
685                                        }
686                                        break;
687
688                                case MESSAGE_NEW_TYPING :
689                                        LOG_DEBUG("message received from=" + std::string(info->szRemoteIdentity) + " content=" + std::string(info->szContent));
690                                        from = String(info->szRemoteIdentity).split(" ")[0];
691                                        sessionIt = contactChatMap.find(from);
692                                        if (sessionIt != contactChatMap.end()) {
693                                                imChatSession = (*sessionIt).second;
694                                                p->typingStateChangedEvent(*p, *imChatSession, from, IMChat::TypingStateTyping);
695                                        }
696                                        break;
697
698                                case MESSAGE_NEW_STOP_TYPING :
699                                        LOG_DEBUG("message received from=" + std::string(info->szRemoteIdentity) + " content=" + std::string(info->szContent));
700                                        from = String(info->szRemoteIdentity).split(" ")[0];
701                                        sessionIt = contactChatMap.find(from);
702                                        if (sessionIt != contactChatMap.end()) {
703                                                imChatSession = (*sessionIt).second;
704                                                p->typingStateChangedEvent(*p, *imChatSession, from, IMChat::TypingStateStopTyping);
705                                        }
706                                        break;
707
708                                case MESSAGE_NEW_NOT_TYPING :
709                                        LOG_DEBUG("message received from=" + std::string(info->szRemoteIdentity) + " content=" + std::string(info->szContent));
710                                        from = String(info->szRemoteIdentity).split(" ")[0];
711                                        sessionIt = contactChatMap.find(from);
712                                        if (sessionIt != contactChatMap.end()) {
713                                                imChatSession = (*sessionIt).second;
714                                                p->typingStateChangedEvent(*p, *imChatSession, from, IMChat::TypingStateNotTyping);
715                                        }
716                                        break;
717
718                                default :
719                                        break;
720                        }
721                        break;
722
723                case MESSAGE_SUCCESS :
724                        switch(info->cause) {
725                                case MESSAGE_SUCCESS_NORMAL :
726                                        // do nothing : drop the status message
727                                        break;
728
729                                default :
730                                        break;
731                        }
732                        break;
733
734                case MESSAGE_FAILURE :
735                        switch(info->cause) {
736                                case MESSAGE_FAILURE_UNKNOWN :
737                                        LOG_DEBUG("message received from=" + std::string(info->szRemoteIdentity) + " content=" + std::string(info->szContent));
738                                        atPos = String(info->szLocalIdentity).find("@");
739                                        from = String(info->szLocalIdentity).substr(5, atPos - 5);
740                                        sessionIt = contactChatMap.find(from);
741                                        if (sessionIt != contactChatMap.end()) {
742                                                imChatSession = (*sessionIt).second;
743                                        } else {
744                                                LOG_DEBUG("creating new IMChatSession");
745                                                imChatSession = new IMChatSession(*PhApiIMChat::PhApiIMChatHack);
746                                                contactChatMap[from] = imChatSession;
747                                                p->addContact(*imChatSession, from);
748                                                p->newIMChatSessionCreatedEvent(*p, *imChatSession);
749                                                p->sendMyIcon(from, p->_iconFilename);
750                                        }
751                                        LOG_DEBUG("message could not be sent");
752                                        p->statusMessageReceivedEvent(*p, *imChatSession, PhApiIMChat::StatusMessageError, std::string(info->szContent));
753                                        break;
754
755                                case MESSAGE_FAILURE_COULD_NOT_SEND :
756                                        LOG_DEBUG("message received from=" + std::string(info->szRemoteIdentity) + " content=" + std::string(info->szContent));
757                                        atPos = String(info->szLocalIdentity).find("@");
758                                        from = String(info->szLocalIdentity).substr(5, atPos - 5);
759                                        sessionIt = contactChatMap.find(from);
760                                        if (sessionIt != contactChatMap.end()) {
761                                                imChatSession = (*sessionIt).second;
762                                        } else {
763                                                LOG_DEBUG("creating new IMChatSession");
764                                                imChatSession = new IMChatSession(*PhApiIMChat::PhApiIMChatHack);
765                                                contactChatMap[from] = imChatSession;
766                                                p->addContact(*imChatSession, from);
767                                                p->newIMChatSessionCreatedEvent(*p, *imChatSession);
768                                                p->sendMyIcon(from, p->_iconFilename);
769                                        }
770                                        LOG_DEBUG("message could not be sent");
771                                        p->statusMessageReceivedEvent(*p, *imChatSession, PhApiIMChat::StatusMessageError, std::string(info->szContent));
772                                        break;
773
774                                default :
775                                        LOG_DEBUG("message received from=" + std::string(info->szRemoteIdentity) + " content=" + std::string(info->szContent));
776                                        LOG_DEBUG("message could not be sent : unknown failure cause=" + String::fromNumber(info->cause));
777                                        break;
778                        }
779                        break;
780
781                default :
782                        LOG_DEBUG("message received from=" + std::string(info->szRemoteIdentity) + " content=" + std::string(info->szContent));
783                        LOG_FATAL("unknown message event=" + String::fromNumber(info->event));
784                        break;
785        }
786}
787*/
788
789void PhApiCallbacks::subscriptionProgress(OWPL_SUBSTATUS_INFO * info) {
790        PhApiWrapper * p = PhApiWrapper::PhApiWrapperHack;
791        std::string from(info->szRemoteIdentity);
792
793        switch (info->state) {
794
795                case OWPL_SUBSCRIPTION_PENDING :
796                        switch (info->cause) {
797                                case SUBSCRIPTION_CAUSE_NORMAL :
798                                        break;
799
800                                default:
801                                        break;
802                        }
803                        break;
804
805                case OWPL_SUBSCRIPTION_ACTIVE :
806                        switch (info->cause) {
807                                case SUBSCRIPTION_CAUSE_NORMAL :
808                                        p->subscribeStatusEvent(*p, from, IMPresence::SubscribeStatusOk);
809                                        break;
810
811                                default:
812                                        break;
813                        }
814                        break;
815
816                case OWPL_SUBSCRIPTION_FAILED :
817                        switch (info->cause) {
818                                case SUBSCRIPTION_CAUSE_UNKNOWN :
819                                        p->subscribeStatusEvent(*p, from, IMPresence::SubscribeStatusError);
820                                        break;
821
822                                default:
823                                        break;
824                        }
825                        break;
826
827                case OWPL_SUBSCRIPTION_EXPIRED :
828                        switch (info->cause) {
829                                case SUBSCRIPTION_CAUSE_UNKNOWN :
830                                        break;
831
832                                case SUBSCRIPTION_CAUSE_NORMAL :
833                                        break;
834
835                                default:
836                                        break;
837                        }
838                        break;
839
840                case OWPL_SUBSCRIPTION_CLOSED :
841                        switch (info->cause) {
842
843                                case SUBSCRIPTION_CAUSE_UNKNOWN :
844                                        break;
845
846                                case SUBSCRIPTION_CAUSE_NORMAL :
847                                        {
848                                                std::string buddy = computeContactId(info->szRemoteIdentity);
849                                                if (buddy.empty()) {
850                                                        return;
851                                                }
852                                               
853                                                p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateUnknown, "", buddy);
854                                        }
855                                        break;
856
857                                default:
858                                        break;
859                        }
860                        break;
861
862                 case OWPL_INSUBSCRIPTION_NEW: 
863                   p->handleIncomingSubscribe(info->hSub, info->szRemoteIdentity, info->szEvtType);
864                   break;
865
866                 case OWPL_INSUBSCRIPTION_CLOSE:
867                   p->terminateIncomingSubscribe(info->hSub);
868                   break;
869
870                default :
871                        break;
872        }
873}
874
875void PhApiCallbacks::onNotify(OWPL_NOTIFICATION_INFO * info) {
876        PhApiWrapper * p = PhApiWrapper::PhApiWrapperHack;
877        TiXmlDocument doc;
878        doc.Parse(info->szXmlContent);
879        TiXmlHandle docHandle(&doc);
880        TiXmlElement * watcherinfoElement = NULL;
881        TiXmlElement * watcherElement = NULL;
882        std::string note;
883        std::string buddy;
884
885        switch(info->event) {
886                //A buddy presence
887                case NOTIFICATION_PRESENCE :
888                        buddy = computeContactId(info->Data.StatusInfo->szRemoteIdentity);
889
890                        if (buddy.empty()) {
891                                return;
892                        }
893
894                        switch(info->cause) {
895                                case NOTIFICATION_PRESENCE_ONLINE :
896                                        note = std::string(info->Data.StatusInfo->szStatusNote);
897                                        if (note == PhApiWrapper::PresenceStateOnline) {
898                                                p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateOnline, note, buddy);
899                                        } else if (note == PhApiWrapper::PresenceStateAway) {
900                                                p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateAway, note, buddy);
901                                        } else if (note == PhApiWrapper::PresenceStateDoNotDisturb
902                                                || note == PhApiWrapper::PresenceStateBusy) {
903                                                p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateDoNotDisturb, note, buddy);
904                                        } else {
905                                                p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateUserDefined, note, buddy);
906                                        }
907                                        break;
908
909                                case NOTIFICATION_PRESENCE_OFFLINE :
910                                        note = std::string(info->Data.StatusInfo->szStatusNote);
911                                        if (note == PhApiWrapper::PresenceStateBusy)
912                                        {
913                                                p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateDoNotDisturb, note, buddy);
914                                        }
915                                        else
916                                        {
917                                                p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateOffline, String::null, buddy);
918                                        }
919                                        break;
920
921                                case NOTIFICATION_PRESENCE_WATCHER :
922                                        LOG_DEBUG("buddy=" + buddy + " notification=presence.winfo content=" + std::string(info->szXmlContent));
923                                        watcherinfoElement = doc.FirstChildElement("watcherinfo");
924                                        if (watcherinfoElement) {
925
926                                                watcherElement = watcherinfoElement->FirstChildElement("watcher");
927                                                while (watcherElement) {
928
929                                                        std::string watcher(watcherElement->Value());
930                                                        p->allowWatcher(watcher);
931
932                                                        watcherElement = watcherinfoElement->NextSiblingElement("watcher");
933                                                }
934                                        }
935                                        break;
936
937                                default :
938                                        break;
939                        }
940
941                        //basicText = docHandle.FirstChild("presence").FirstChild("tuple").FirstChild("status").FirstChild("basic").FirstChild().Text();
942                        //if (basicText) {
943                        //      std::string basic = basicText->Value();
944
945                        //      //buddy is offline
946                        //      if (String(basic).toLowerCase() == "closed") {
947                        //              p->presenceStateChangedEvent(*p,  EnumPresenceState::PresenceStateOffline, String::null, buddy);
948                        //      }
949
950                        //      //buddy is online
951                        //      else if (String(basic).toLowerCase() == "open") {
952                        //              noteText = docHandle.FirstChild("presence").FirstChild("tuple").FirstChild("status").FirstChild("note").FirstChild().Text();
953                        //              if (!noteText) {
954                        //                      noteText = docHandle.FirstChild("presence").FirstChild("tuple").FirstChild("status").FirstChild("value").FirstChild().Text();
955                        //              }
956                        //              if (noteText) {
957                        //                      std::string note = noteText->Value();
958                        //                      if (note == PhApiWrapper::PresenceStateOnline) {
959                        //                              p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateOnline, note, buddy);
960                        //                      } else if (note == PhApiWrapper::PresenceStateAway) {
961                        //                              p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateAway, note, buddy);
962                        //                      } else if (note == PhApiWrapper::PresenceStateDoNotDisturb) {
963                        //                              p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateDoNotDisturb, note, buddy);
964                        //                      } else {
965                        //                              p->presenceStateChangedEvent(*p, EnumPresenceState::PresenceStateUserDefined, note, buddy);
966                        //                      }
967                        //              }
968                        //      }
969                        //}
970                        break;
971
972                //watcher list
973                /*case NOTIFICATION_WATCHER :
974                        LOG_DEBUG("buddy=" + buddy + " notification=presence.winfo content=" + std::string(info->szXmlContent));
975                        watcherinfoElement = doc.FirstChildElement("watcherinfo");
976                        if (watcherinfoElement) {
977
978                                watcherElement = watcherinfoElement->FirstChildElement("watcher");
979                                while (watcherElement) {
980
981                                        std::string watcher(watcherElement->Value());
982                                        p->allowWatcher(watcher);
983
984                                        watcherElement = watcherinfoElement->NextSiblingElement("watcher");
985                                }
986                        }
987                        break;*/
988
989                // TODO: To complete
990                case NOTIFICATION_MWI :
991                        break;
992
993                case NOTIFICATION_UNKNOWN :
994                        LOG_FATAL("unknown message event with content=" + std::string(info->szXmlContent));
995                        break;
996
997                default :
998                        LOG_FATAL("unknown message event with content=" + std::string(info->szXmlContent));
999                        break;
1000        }
1001}
1002
1003void PhApiCallbacks::errorNotify(OWPL_ERROR_INFO * info) {
1004        switch(info->event) {
1005                case OWPL_ERROR :
1006                        break;
1007
1008                case OWPL_ERROR_NO_AUDIO_DEVICE :
1009                        break;
1010
1011                default :
1012                        break;
1013        }
1014}
1015
1016std::string PhApiCallbacks::computeContactId(const std::string & contactFromPhApi) {
1017        std::string buddyTmp(contactFromPhApi);
1018        size_t colonIndex = buddyTmp.find(':', 0);
1019        size_t greaterIndex = buddyTmp.find('>');
1020
1021        if (colonIndex != std::string::npos) {
1022                std::string wengoRealm = PhApiWrapper::PhApiWrapperHack->getWengoRealm();
1023                return buddyTmp.substr(colonIndex + 1, greaterIndex - colonIndex - 1);
1024        }
1025
1026        return "";
1027}
Note: See TracBrowser for help on using the repository browser.