source: mediastreamer2/linphone/coreapi/friend.c @ 295:7c2d63cfbe15

Last change on this file since 295:7c2d63cfbe15 was 295:7c2d63cfbe15, checked in by smorlat <smorlat@…>, 4 years ago

fix bug when adding contacts
sipsetup plugins work in progress.

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@298 3f6dc0c8-ddfe-455d-9043-3cd528dc4637

File size: 20.6 KB
Line 
1/***************************************************************************
2 *            friend.c
3 *
4 *  Sat May 15 15:25:16 2004
5 *  Copyright  2004  Simon Morlat
6 *  Email
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License as published by
12 *  the Free Software Foundation; either version 2 of the License, or
13 *  (at your option) any later version.
14 *
15 *  This program is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU Library General Public License for more details.
19 *
20 *  You should have received a copy of the GNU General Public License
21 *  along with this program; if not, write to the Free Software
22 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25#include "linphonecore.h"
26#include "private.h"
27#include <eXosip2/eXosip.h>
28#include <osipparser2/osip_message.h>
29#include "lpconfig.h"
30
31const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){
32        const char *str=NULL;
33        switch(ss){
34                case LINPHONE_STATUS_UNKNOWN:
35                str=_("Unknown");
36                break;
37                case LINPHONE_STATUS_ONLINE:
38                str=_("Online");
39                break;
40                case LINPHONE_STATUS_BUSY:
41                str=_("Busy");
42                break;
43                case LINPHONE_STATUS_BERIGHTBACK:
44                str=_("Be right back");
45                break;
46                case LINPHONE_STATUS_AWAY:
47                str=_("Away");
48                break;
49                case LINPHONE_STATUS_ONTHEPHONE:
50                str=_("On the phone");
51                break;
52                case LINPHONE_STATUS_OUTTOLUNCH:
53                str=_("Out to lunch");
54                break;
55                case LINPHONE_STATUS_NOT_DISTURB:
56                str=_("Do not disturb");
57                break;
58                case LINPHONE_STATUS_MOVED:
59                str=_("Moved");
60                break;
61                case LINPHONE_STATUS_ALT_SERVICE:
62                str=_("Using another messaging service");
63                break;
64                case LINPHONE_STATUS_OFFLINE:
65                str=_("Offline");
66                break;
67                case LINPHONE_STATUS_PENDING:
68                str=_("Pending");
69                break;
70                case LINPHONE_STATUS_CLOSED:
71                str=_("Closed");
72                break;
73                default:
74                str=_("Unknown-bug");
75        }
76        return str;
77}
78
79static int friend_data_compare(const void * a, const void * b, void * data){
80        osip_from_t *fa=((LinphoneFriend*)a)->url;
81        osip_from_t *fb=((LinphoneFriend*)b)->url;
82        char *ua,*ub;
83        ua=fa->url->username;
84        ub=fb->url->username;
85        if (ua!=NULL && ub!=NULL) {
86                //printf("Comparing usernames %s,%s\n",ua,ub);
87                return strcasecmp(ua,ub);
88        }
89        else {
90                /* compare hosts*/
91                ua=fa->url->host;
92                ub=fb->url->host;
93                if (ua!=NULL && ub!=NULL){
94                        int ret=strcasecmp(ua,ub);
95                        //printf("Comparing hostnames %s,%s,res=%i\n",ua,ub,ret);
96                        return ret;
97                }
98                else return -1;
99        }
100}
101
102static int friend_compare(const void * a, const void * b){
103        return friend_data_compare(a,b,NULL);
104}
105
106
107MSList *find_friend(MSList *fl, const osip_from_t *friend, LinphoneFriend **lf){
108        MSList *res=NULL;
109        LinphoneFriend dummy;
110        if (lf!=NULL) *lf=NULL;
111        dummy.url=(osip_from_t*)friend;
112        res=ms_list_find_custom(fl,friend_compare,&dummy);
113        if (lf!=NULL && res!=NULL) *lf=(LinphoneFriend*)res->data;
114        return res;
115}
116
117LinphoneFriend *linphone_find_friend_by_nid(MSList *l, int nid){
118        MSList *elem;
119        for (elem=l;elem!=NULL;elem=elem->next){
120                LinphoneFriend *lf=(LinphoneFriend*)elem->data;
121                if (lf->nid==nid) return lf;
122        }
123        return NULL;
124}
125
126LinphoneFriend *linphone_find_friend_by_sid(MSList *l, int sid){
127        MSList *elem;
128        for (elem=l;elem!=NULL;elem=elem->next){
129                LinphoneFriend *lf=(LinphoneFriend*)elem->data;
130                if (lf->sid==sid) return lf;
131        }
132        return NULL;
133}
134
135void __linphone_friend_do_subscribe(LinphoneFriend *fr){
136        char *friend=NULL;
137        const char *route=NULL;
138        const char *from=NULL;
139        osip_message_t *msg=NULL;
140        osip_from_to_str(fr->url,&friend);
141        if (fr->proxy!=NULL){
142                route=fr->proxy->reg_route;
143                from=fr->proxy->reg_identity;
144        }else from=linphone_core_get_primary_contact(fr->lc);
145        if (fr->sid<0){
146                /* people for which we don't have yet an answer should appear as offline */
147                fr->lc->vtable.notify_recv(fr->lc,(LinphoneFriend*)fr,friend,_("Gone"),"sip-closed.png");
148        }
149        eXosip_lock();
150        eXosip_subscribe_build_initial_request(&msg,friend,from,route,"presence",600);
151        eXosip_subscribe_send_initial_request(msg);
152        eXosip_unlock();
153        osip_free(friend);
154}
155
156
157LinphoneFriend * linphone_friend_new(){
158        LinphoneFriend *obj=ms_new0(LinphoneFriend,1);
159        obj->out_did=-1;
160        obj->in_did=-1;
161        obj->nid=-1;
162        obj->sid=-1;
163        obj->pol=LinphoneSPAccept;
164        obj->status=LINPHONE_STATUS_OFFLINE;
165        obj->subscribe=TRUE;
166        return obj;     
167}
168
169LinphoneFriend *linphone_friend_new_with_addr(const char *addr){
170        LinphoneFriend *fr=linphone_friend_new();
171        if (linphone_friend_set_sip_addr(fr,addr)<0){
172                linphone_friend_destroy(fr);
173                return NULL;
174        }
175        return fr;
176}
177
178void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char **result){
179        int err;
180        osip_from_t *fr=NULL;
181        osip_from_init(&fr);
182        err=osip_from_parse(fr,uri);
183        if (err<0){
184                char *tmp=NULL;
185                if (strchr(uri,'@')!=NULL){
186                        /*try adding sip:*/
187                        tmp=ms_strdup_printf("sip:%s",uri);
188                }else if (lc->default_proxy!=NULL){
189                        /*try adding domain part from default current proxy*/
190                        osip_from_t *id=NULL;
191                        osip_from_init(&id);
192                        if (osip_from_parse(id,linphone_core_get_identity(lc))==0){
193                                if (id->url->port!=NULL && strlen(id->url->port)>0)
194                                        tmp=ms_strdup_printf("sip:%s@%s:%s",uri,id->url->host,id->url->port);
195                                else tmp=ms_strdup_printf("sip:%s@%s",uri,id->url->host);
196                        }
197                        osip_from_free(id);
198                }
199                if (osip_from_parse(fr,tmp)==0){
200                        /*looks good */
201                        ms_message("%s interpreted as %s",uri,tmp);
202                        *result=tmp;
203                }else *result=NULL;
204        }else *result=ms_strdup(uri);
205        osip_from_free(fr);
206}
207
208int linphone_friend_set_sip_addr(LinphoneFriend *lf, const char *addr){
209        int err;
210        osip_from_t *fr=NULL;
211        osip_from_init(&fr);
212        err=osip_from_parse(fr,addr);
213        if (err<0) {
214                ms_warning("Invalid friend sip uri: %s",addr);
215                osip_from_free(fr);
216                return -1;
217        }
218        if (lf->url!=NULL) osip_from_free(lf->url);     
219        lf->url=fr;
220        return 0;
221}
222
223int linphone_friend_set_name(LinphoneFriend *lf, const char *name){
224        osip_from_t *fr=lf->url;
225        if (fr==NULL){
226                ms_error("linphone_friend_set_sip_addr() must be called before linphone_friend_set_name().");
227                return -1;
228        }
229        if (fr->displayname!=NULL){
230                osip_free(fr->displayname);
231                fr->displayname=NULL;
232        }
233        if (name && name[0]!='\0'){
234                fr->displayname=osip_strdup(name);
235        }
236        return 0;
237}
238
239int linphone_friend_send_subscribe(LinphoneFriend *fr, bool_t val){
240        fr->subscribe=val;
241        return 0;
242}
243
244int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol)
245{
246        fr->pol=pol;
247        return 0;
248}
249
250int linphone_friend_set_proxy(LinphoneFriend *fr, struct _LinphoneProxyConfig *cfg){
251        fr->proxy=cfg;
252        return 0;
253}
254
255void linphone_friend_set_sid(LinphoneFriend *lf, int sid){
256        lf->sid=sid;
257}
258void linphone_friend_set_nid(LinphoneFriend *lf, int nid){
259        lf->nid=nid;
260        lf->inc_subscribe_pending=TRUE;
261}
262
263void add_presence_body(osip_message_t *notify, LinphoneOnlineStatus online_status)
264{
265        char buf[1000];
266#ifdef SUPPORT_MSN
267        int atom_id = 1000;
268#endif
269        char *contact_info;
270
271        osip_contact_t *ct=NULL;
272        osip_message_get_contact(notify,0,&ct);
273        osip_contact_to_str(ct,&contact_info);
274
275#ifdef SUPPORT_MSN
276
277  if (online_status==LINPHONE_STATUS_ONLINE)
278    {
279      sprintf(buf, "<?xml version=\"1.0\"?>\n\
280<!DOCTYPE presence\n\
281PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
282<presence>\n\
283<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
284<atom id=\"%i\">\n\
285<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
286<status status=\"open\" />\n\
287<msnsubstatus substatus=\"online\" />\n\
288</address>\n\
289</atom>\n\
290</presence>", contact_info, atom_id, contact_info);
291
292    }
293  else if (online_status==LINPHONE_STATUS_BUSY)
294    {
295      sprintf(buf, "<?xml version=\"1.0\"?>\n\
296<!DOCTYPE presence\n\
297PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
298<presence>\n\
299<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
300<atom id=\"%i\">\n\
301<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
302<status status=\"inuse\" />\n\
303<msnsubstatus substatus=\"busy\" />\n\
304</address>\n\
305</atom>\n\
306</presence>", contact_info, atom_id, contact_info);
307
308    }
309  else if (online_status==LINPHONE_STATUS_BERIGHTBACK)
310    {
311      sprintf(buf, "<?xml version=\"1.0\"?>\n\
312<!DOCTYPE presence\n\
313PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
314<presence>\n\
315<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
316<atom id=\"%i\">\n\
317<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
318<status status=\"inactive\" />\n\
319<msnsubstatus substatus=\"berightback\" />\n\
320</address>\n\
321</atom>\n\
322</presence>", contact_info, atom_id, contact_info);
323
324    }
325  else if (online_status==LINPHONE_STATUS_AWAY)
326    {
327      sprintf(buf, "<?xml version=\"1.0\"?>\n\
328<!DOCTYPE presence\n\
329PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
330<presence>\n\
331<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
332<atom id=\"%i\">\n\
333<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
334<status status=\"inactive\" />\n\
335<msnsubstatus substatus=\"away\" />\n\
336</address>\n\
337</atom>\n\
338</presence>", contact_info, atom_id, contact_info);
339
340    }
341  else if (online_status==LINPHONE_STATUS_ONTHEPHONE)
342    {
343      sprintf(buf, "<?xml version=\"1.0\"?>\n\
344<!DOCTYPE presence\n\
345PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
346<presence>\n\
347<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
348<atom id=\"%i\">\n\
349<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
350<status status=\"inuse\" />\n\
351<msnsubstatus substatus=\"onthephone\" />\n\
352</address>\n\
353</atom>\n\
354</presence>", contact_info, atom_id, contact_info);
355
356    }
357  else if (online_status==LINPHONE_STATUS_OUTTOLUNCH)
358    {
359      sprintf(buf, "<?xml version=\"1.0\"?>\n\
360<!DOCTYPE presence\n\
361PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
362<presence>\n\
363<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
364<atom id=\"%i\">\n\
365<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
366<status status=\"inactive\" />\n\
367<msnsubstatus substatus=\"outtolunch\" />\n\
368</address>\n\
369</atom>\n\
370</presence>", contact_info, atom_id, contact_info);
371
372    }
373  else
374    {
375      sprintf(buf, "<?xml version=\"1.0\"?>\n\
376<!DOCTYPE presence\n\
377PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
378<presence>\n\
379<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
380<atom id=\"%i\">\n\
381<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
382<status status=\"inactive\" />\n\
383<msnsubstatus substatus=\"away\" />\n\
384</address>\n\
385</atom>\n\
386</presence>", contact_info, atom_id, contact_info);
387    }
388
389  osip_message_set_body(notify, buf, strlen(buf));
390  osip_message_set_content_type(notify, "application/xpidf+xml");
391#else
392
393  if (online_status==LINPHONE_STATUS_ONLINE)
394    {
395      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
396<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
397          entity=\"%s\">\n\
398<tuple id=\"sg89ae\">\n\
399<status>\n\
400<basic>open</basic>\n\
401</status>\n\
402<contact priority=\"0.8\">%s</contact>\n\
403<note>online</note>\n\
404</tuple>\n\
405</presence>",
406              contact_info, contact_info);
407    }
408  else if (online_status==LINPHONE_STATUS_BUSY)
409    {
410      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
411<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
412          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
413          entity=\"%s\">\n\
414<tuple id=\"sg89ae\">\n\
415<status>\n\
416<basic>open</basic>\n\
417<es:activities>\n\
418  <es:activity>busy</es:activity>\n\
419</es:activities>\n\
420</status>\n\
421<contact priority=\"0.8\">%s</contact>\n\
422<note>busy</note>\n\
423</tuple>\n\
424</presence>",
425              contact_info, contact_info);
426    }
427  else if (online_status==LINPHONE_STATUS_BERIGHTBACK)
428    {
429      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
430<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
431          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
432          entity=\"%s\">\n\
433<tuple id=\"sg89ae\">\n\
434<status>\n\
435<basic>open</basic>\n\
436<es:activities>\n\
437  <es:activity>in-transit</es:activity>\n\
438</es:activities>\n\
439</status>\n\
440<contact priority=\"0.8\">%s</contact>\n\
441<note>be right back</note>\n\
442</tuple>\n\
443</presence>",
444              contact_info, contact_info);
445    }
446  else if (online_status==LINPHONE_STATUS_AWAY)
447    {
448      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
449<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
450          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
451          entity=\"%s\">\n\
452<tuple id=\"sg89ae\">\n\
453<status>\n\
454<basic>open</basic>\n\
455<es:activities>\n\
456  <es:activity>away</es:activity>\n\
457</es:activities>\n\
458</status>\n\
459<contact priority=\"0.8\">%s</contact>\n\
460<note>away</note>\n\
461</tuple>\n\
462</presence>",
463              contact_info, contact_info);
464    }
465  else if (online_status==LINPHONE_STATUS_ONTHEPHONE)
466    {
467      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
468<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
469          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
470          entity=\"%s\">\n\
471<tuple id=\"sg89ae\">\n\
472<status>\n\
473<basic>open</basic>\n\
474<es:activities>\n\
475  <es:activity>on-the-phone</es:activity>\n\
476</es:activities>\n\
477</status>\n\
478<contact priority=\"0.8\">%s</contact>\n\
479<note>on the phone</note>\n\
480</tuple>\n\
481</presence>",
482              contact_info, contact_info);
483    }
484  else if (online_status==LINPHONE_STATUS_OUTTOLUNCH)
485    {
486      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
487<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
488          xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
489          entity=\"%s\">\n\
490<tuple id=\"sg89ae\">\n\
491<status>\n\
492<basic>open</basic>\n\
493<es:activities>\n\
494  <es:activity>meal</es:activity>\n\
495</es:activities>\n\
496</status>\n\
497<contact priority=\"0.8\">%s</contact>\n\
498<note>out to lunch</note>\n\
499</tuple>\n\
500</presence>",
501              contact_info, contact_info);
502    }
503  else
504    {
505      /* */
506      sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
507<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
508xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
509entity=\"%s\">\n%s",
510              contact_info,
511"<tuple id=\"sg89ae\">\n\
512<status>\n\
513<basic>closed</basic>\n\
514<es:activities>\n\
515  <es:activity>permanent-absence</e:activity>\n\
516</es:activities>\n\
517</status>\n\
518</tuple>\n\
519\n</presence>\n");
520    }
521  osip_message_set_body(notify, buf, strlen(buf));
522  osip_message_set_content_type(notify, "application/pidf+xml");
523
524#endif
525        osip_free(contact_info);
526}
527
528
529void linphone_friend_notify(LinphoneFriend *lf, int ss, LinphoneOnlineStatus os){
530        //printf("Wish to notify %p, lf->nid=%i\n",lf,lf->nid);
531        if (lf->in_did!=-1){
532                osip_message_t *msg=NULL;
533                const char *identity;
534                if (lf->proxy!=NULL) identity=lf->proxy->reg_identity;
535                else identity=linphone_core_get_primary_contact(lf->lc);
536                eXosip_lock();
537                eXosip_insubscription_build_notify(lf->in_did,ss,0,&msg);
538                if (msg!=NULL){
539                        osip_message_set_contact(msg,identity);
540                        add_presence_body(msg,os);
541                        eXosip_insubscription_send_request(lf->in_did,msg);
542                }else ms_error("could not create notify for incoming subscription.");
543                eXosip_unlock();
544        }
545}
546
547static void linphone_friend_unsubscribe(LinphoneFriend *lf){
548        if (lf->out_did!=-1) {
549                osip_message_t *msg=NULL;
550                eXosip_lock();
551                eXosip_subscribe_build_refresh_request(lf->out_did,&msg);
552                if (msg){
553                        osip_message_set_expires(msg,"0");
554                        eXosip_subscribe_send_refresh_request(lf->out_did,msg);
555                }else ms_error("Could not build subscribe refresh request !");
556                eXosip_unlock();
557        }
558}
559
560void linphone_friend_destroy(LinphoneFriend *lf){
561        linphone_friend_notify(lf,EXOSIP_SUBCRSTATE_TERMINATED,LINPHONE_STATUS_CLOSED);
562        linphone_friend_unsubscribe(lf);
563        if (lf->url!=NULL) osip_from_free(lf->url);
564        ms_free(lf);
565}
566
567void linphone_friend_check_for_removed_proxy(LinphoneFriend *lf, LinphoneProxyConfig *cfg){
568        if (lf->proxy==cfg){
569                lf->proxy=NULL;
570        }
571}
572
573char *linphone_friend_get_addr(LinphoneFriend *lf){
574        char *ret,*tmp;
575        if (lf->url==NULL) return NULL;
576        osip_uri_to_str(lf->url->url,&tmp);
577        ret=ms_strdup(tmp);
578        osip_free(tmp);
579        return ret;
580}
581
582char *linphone_friend_get_name(LinphoneFriend *lf){
583        if (lf->url==NULL) return NULL;
584        if (lf->url->displayname==NULL) return NULL;
585        return ms_strdup(lf->url->displayname);
586}
587
588char * linphone_friend_get_url(LinphoneFriend *lf){
589        char *tmp,*ret;
590        if (lf->url==NULL) return NULL;
591        osip_from_to_str(lf->url,&tmp);
592        ret=ms_strdup(tmp);
593        ms_free(tmp);
594        return ret;
595}
596
597bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf){
598        return lf->subscribe;
599}
600
601LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneFriend *lf){
602        return lf->pol;
603}
604
605LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){
606        return lf->status;
607}
608
609
610void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
611        if (fr->url==NULL) {
612                ms_warning("No sip url defined.");
613                return;
614        }
615        fr->lc=lc;
616       
617        linphone_core_write_friends_config(lc);
618
619        if (fr->inc_subscribe_pending){
620                switch(fr->pol){
621                        case LinphoneSPWait:
622                                linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_PENDING,LINPHONE_STATUS_PENDING);
623                                break;
624                        case LinphoneSPAccept:
625                                if (fr->lc!=NULL)
626                                  {
627                                        linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_ACTIVE,fr->lc->presence_mode);
628                                  }
629                                break;
630                        case LinphoneSPDeny:
631                                linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_TERMINATED,LINPHONE_STATUS_CLOSED);
632                                break;
633                }
634                fr->inc_subscribe_pending=FALSE;
635        }
636        if (fr->subscribe && fr->out_did==-1){
637               
638                __linphone_friend_do_subscribe(fr);
639        }
640        ms_message("linphone_friend_apply() done.");
641}
642
643void linphone_friend_edit(LinphoneFriend *fr){
644}
645
646void linphone_friend_done(LinphoneFriend *fr){
647        ms_return_if_fail(fr!=NULL);
648        if (fr->lc==NULL) return;
649        linphone_friend_apply(fr,fr->lc);
650}
651
652void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf)
653{
654        ms_return_if_fail(lf->lc==NULL);
655        ms_return_if_fail(lf->url!=NULL);
656        lc->friends=ms_list_append(lc->friends,lf);
657        linphone_friend_apply(lf,lc);
658        return ;
659}
660
661void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){
662        MSList *el=ms_list_find(lc->friends,(void *)fl);
663        if (el!=NULL){
664                lc->friends=ms_list_remove_link(lc->friends,el);
665                linphone_friend_destroy((LinphoneFriend*)el->data);
666        }
667}
668
669#define key_compare(key, word) strncasecmp((key),(word),strlen(key))
670
671LinphoneSubscribePolicy __policy_str_to_enum(const char* pol){
672        if (key_compare("accept",pol)==0){
673                return LinphoneSPAccept;
674        }
675        if (key_compare("deny",pol)==0){
676                return LinphoneSPDeny;
677        }
678        if (key_compare("wait",pol)==0){
679                return LinphoneSPWait;
680        }
681        ms_warning("Unrecognized subscribe policy: %s",pol);
682        return LinphoneSPWait;
683}
684
685LinphoneProxyConfig *__index_to_proxy(LinphoneCore *lc, int index){
686        if (index>=0) return (LinphoneProxyConfig*)ms_list_nth_data(lc->sip_conf.proxies,index);
687        else return NULL;
688}
689
690LinphoneFriend * linphone_friend_new_from_config_file(LinphoneCore *lc, int index){
691        const char *tmp;
692        char item[50];
693        int a;
694        LinphoneFriend *lf;
695        LpConfig *config=lc->config;
696       
697        sprintf(item,"friend_%i",index);
698       
699        if (!lp_config_has_section(config,item)){
700                return NULL;
701        }
702       
703        tmp=lp_config_get_string(config,item,"url",NULL);
704        if (tmp==NULL) {
705                return NULL;
706        }
707        lf=linphone_friend_new_with_addr(tmp);
708        if (lf==NULL) {
709                return NULL;
710        }
711        tmp=lp_config_get_string(config,item,"pol",NULL);
712        if (tmp==NULL) linphone_friend_set_inc_subscribe_policy(lf,LinphoneSPWait);
713        else{
714                linphone_friend_set_inc_subscribe_policy(lf,__policy_str_to_enum(tmp));
715        }
716        a=lp_config_get_int(config,item,"subscribe",0);
717        linphone_friend_send_subscribe(lf,a);
718               
719        a=lp_config_get_int(config,item,"proxy",-1);
720        if (a!=-1) {
721                linphone_friend_set_proxy(lf,__index_to_proxy(lc,a));
722        }
723        return lf;
724}
725
726const char *__policy_enum_to_str(LinphoneSubscribePolicy pol){
727        switch(pol){
728                case LinphoneSPAccept:
729                        return "accept";
730                        break;
731                case LinphoneSPDeny:
732                        return "deny";
733                        break;
734                case LinphoneSPWait:
735                        return "wait";
736                        break;
737        }
738        ms_warning("Invalid policy enum value.");
739        return "wait";
740}
741
742void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf, int index){
743        char key[50];
744        char *tmp;
745        int a;
746       
747        sprintf(key,"friend_%i",index);
748       
749        if (lf==NULL){
750                lp_config_clean_section(config,key);
751                return;
752        }
753        if (lf->url!=NULL){
754                osip_from_to_str(lf->url,&tmp);
755                if (tmp==NULL) {
756                        return;
757                }
758                lp_config_set_string(config,key,"url",tmp);
759                osip_free(tmp);
760        }
761        lp_config_set_string(config,key,"pol",__policy_enum_to_str(lf->pol));
762        lp_config_set_int(config,key,"subscribe",lf->subscribe);
763        if (lf->proxy!=NULL){
764                a=ms_list_index(lf->lc->sip_conf.proxies,lf->proxy);
765                lp_config_set_int(config,key,"proxy",a);
766        }else lp_config_set_int(config,key,"proxy",-1);
767}
768
769void linphone_core_write_friends_config(LinphoneCore* lc)
770{
771        MSList *elem;
772        int i;
773        if (!lc->ready) return; /*dont write config when reading it !*/
774        for (elem=lc->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){
775                linphone_friend_write_to_config_file(lc->config,(LinphoneFriend*)elem->data,i);
776        }
777        linphone_friend_write_to_config_file(lc->config,NULL,i);        /* set the end */
778}
779
Note: See TracBrowser for help on using the repository browser.