]> sjero.net Git - linphone/blob - coreapi/sal.c
4e09846f696cb5c857e7b73bad1e1ab7dd1dcf00
[linphone] / coreapi / sal.c
1 /*
2 linphone
3 Copyright (C) 2010  Simon MORLAT (simon.morlat@free.fr)
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (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 /** 
21  This header files defines the Signaling Abstraction Layer.
22  The purpose of this layer is too allow experiment different call signaling 
23  protocols and implementations under linphone, for example SIP, JINGLE...
24 **/
25
26 #include "sal.h"
27
28 SalMediaDescription *sal_media_description_new(){
29         SalMediaDescription *md=ms_new0(SalMediaDescription,1);
30         md->refcount=1;
31         return md;
32 }
33
34 static void sal_media_description_destroy(SalMediaDescription *md){
35         int i;
36         for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;i++){
37                 ms_list_for_each(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
38                 ms_list_free(md->streams[i].payloads);
39                 md->streams[i].payloads=NULL;
40         }
41         ms_free(md);
42 }
43
44 void sal_media_description_ref(SalMediaDescription *md){
45         md->refcount++;
46 }
47
48 void sal_media_description_unref(SalMediaDescription *md){
49         md->refcount--;
50         if (md->refcount==0){
51                 sal_media_description_destroy (md);
52         }
53 }
54
55 SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
56     SalMediaProto proto, SalStreamType type){
57         int i;
58         for(i=0;i<md->nstreams;++i){
59                 SalStreamDescription *ss=&md->streams[i];
60                 if (ss->proto==proto && ss->type==type) return ss;
61         }
62         return NULL;
63 }
64
65 bool_t sal_media_description_empty(const SalMediaDescription *md){
66         int i;
67         for(i=0;i<md->nstreams;++i){
68                 const SalStreamDescription *ss=&md->streams[i];
69                 if (ss->port!=0) return FALSE;
70         }
71         return TRUE;
72 }
73
74 void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir){
75         int i;
76         for(i=0;i<md->nstreams;++i){
77                 SalStreamDescription *ss=&md->streams[i];
78                 ss->dir=stream_dir;
79         }
80 }
81
82 bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
83         int i;
84         bool_t found=FALSE;
85
86         /* we are looking for at least one stream with requested direction, inactive streams are ignored*/
87         for(i=0;i<md->nstreams;++i){
88                 const SalStreamDescription *ss=&md->streams[i];
89                 if (ss->dir==stream_dir) found=TRUE;
90                 else{
91                         if (ss->dir!=SalStreamInactive) return FALSE;
92                 }
93         }
94         return found;
95 }
96
97 /*
98 static bool_t fmtp_equals(const char *p1, const char *p2){
99         if (p1 && p2 && strcmp(p1,p2)==0) return TRUE;
100         if (p1==NULL && p2==NULL) return TRUE;
101         return FALSE;
102 }
103 */
104
105 static bool_t payload_type_equals(const PayloadType *p1, const PayloadType *p2){
106         if (p1->type!=p2->type) return FALSE;
107         if (strcmp(p1->mime_type,p2->mime_type)!=0) return FALSE;
108         if (p1->clock_rate!=p2->clock_rate) return FALSE;
109         if (p1->channels!=p2->channels) return FALSE;
110         /*
111          Do not compare fmtp right now: they are modified internally when the call is started
112         */
113         /*
114         if (!fmtp_equals(p1->recv_fmtp,p2->recv_fmtp) ||
115             !fmtp_equals(p1->send_fmtp,p2->send_fmtp))
116                 return FALSE;
117         */
118         return TRUE;
119 }
120
121 static bool_t payload_list_equals(const MSList *l1, const MSList *l2){
122         const MSList *e1,*e2;
123         for(e1=l1,e2=l2;e1!=NULL && e2!=NULL; e1=e1->next,e2=e2->next){
124                 PayloadType *p1=(PayloadType*)e1->data;
125                 PayloadType *p2=(PayloadType*)e2->data;
126                 if (!payload_type_equals(p1,p2))
127                         return FALSE;
128         }
129         if (e1!=NULL || e2!=NULL){
130                 /*means one list is longer than the other*/
131                 abort();
132                 return FALSE;
133         }
134         return TRUE;
135 }
136
137 bool_t sal_stream_description_equals(const SalStreamDescription *sd1, const SalStreamDescription *sd2){
138         if (sd1->proto!=sd2->proto) return FALSE;
139         if (sd1->type!=sd2->type) return FALSE;
140         if (strcmp(sd1->addr,sd2->addr)!=0) return FALSE;
141         if (sd1->port!=sd2->port) return FALSE;
142         if (!payload_list_equals(sd1->payloads,sd2->payloads)) return FALSE;
143         if (sd1->bandwidth!=sd2->bandwidth) return FALSE;
144         if (sd1->ptime!=sd2->ptime) return FALSE;
145         /* compare candidates: TODO */
146         if (sd1->dir!=sd2->dir) return FALSE;
147         return TRUE;
148 }
149
150 bool_t sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2){
151         int i;
152         
153         if (strcmp(md1->addr,md2->addr)!=0) return FALSE;
154         if (md1->nstreams!=md2->nstreams) return FALSE;
155         if (md1->bandwidth!=md2->bandwidth) return FALSE;
156         for(i=0;i<md1->nstreams;++i){
157                 if (!sal_stream_description_equals(&md1->streams[i],&md2->streams[i]))
158                         return FALSE;
159         }
160         return TRUE;
161 }
162
163 static void assign_string(char **str, const char *arg){
164         if (*str){
165                 ms_free(*str);
166                 *str=NULL;
167         }
168         if (arg)
169                 *str=ms_strdup(arg);
170 }
171
172 void sal_op_set_contact(SalOp *op, const char *contact){
173         assign_string(&((SalOpBase*)op)->contact,contact);
174 }
175
176 void sal_op_set_route(SalOp *op, const char *route){
177         assign_string(&((SalOpBase*)op)->route,route);
178 }
179
180 void sal_op_set_from(SalOp *op, const char *from){
181         assign_string(&((SalOpBase*)op)->from,from);
182 }
183
184 void sal_op_set_to(SalOp *op, const char *to){
185         assign_string(&((SalOpBase*)op)->to,to);
186 }
187
188 void sal_op_set_user_pointer(SalOp *op, void *up){
189         ((SalOpBase*)op)->user_pointer=up;
190 }
191
192 Sal *sal_op_get_sal(const SalOp *op){
193         return ((SalOpBase*)op)->root;
194 }
195
196 const char *sal_op_get_from(const SalOp *op){
197         return ((SalOpBase*)op)->from;
198 }
199
200 const char *sal_op_get_to(const SalOp *op){
201         return ((SalOpBase*)op)->to;
202 }
203
204 const char *sal_op_get_contact(const SalOp *op){
205         return ((SalOpBase*)op)->contact;
206 }
207
208 const char *sal_op_get_route(const SalOp *op){
209         return ((SalOpBase*)op)->route;
210 }
211
212 const char *sal_op_get_remote_ua(const SalOp *op){
213         return ((SalOpBase*)op)->remote_ua;
214 }
215
216 void *sal_op_get_user_pointer(const SalOp *op){
217         return ((SalOpBase*)op)->user_pointer;
218 }
219
220 const char *sal_op_get_proxy(const SalOp *op){
221         return ((SalOpBase*)op)->route;
222 }
223
224 const char *sal_op_get_network_origin(const SalOp *op){
225         return ((SalOpBase*)op)->origin;
226 }
227
228 void __sal_op_init(SalOp *b, Sal *sal){
229         memset(b,0,sizeof(SalOpBase));
230         ((SalOpBase*)b)->root=sal;
231 }
232
233 void __sal_op_set_network_origin(SalOp *op, const char *origin){
234         assign_string(&((SalOpBase*)op)->origin,origin);
235 }
236
237
238 void __sal_op_free(SalOp *op){
239         SalOpBase *b=(SalOpBase *)op;
240         if (b->from) {
241                 ms_free(b->from);
242                 b->from=NULL;
243         }
244         if (b->to) {
245                 ms_free(b->to);
246                 b->to=NULL;
247         }
248         if (b->route) {
249                 ms_free(b->route);
250                 b->route=NULL;
251         }
252         if (b->contact) {
253                 ms_free(b->contact);
254                 b->contact=NULL;
255         }
256         if (b->origin){
257                 ms_free(b->origin);
258                 b->origin=NULL;
259         }
260         if (b->remote_ua){
261                 ms_free(b->remote_ua);
262                 b->remote_ua=NULL;
263         }
264         if (b->local_media)
265                 sal_media_description_unref(b->local_media);
266         if (b->remote_media)
267                 sal_media_description_unref(b->remote_media);
268         ms_free(op);
269 }
270 SalAuthInfo* sal_auth_info_new() {
271         return ms_new0(SalAuthInfo,1);
272 }
273 SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info) {
274         SalAuthInfo* new_auth_info=sal_auth_info_new();
275         new_auth_info->username=auth_info->username?ms_strdup(auth_info->username):NULL;
276         new_auth_info->userid=auth_info->userid?ms_strdup(auth_info->userid):NULL;
277         new_auth_info->realm=auth_info->realm?ms_strdup(auth_info->realm):NULL;
278         new_auth_info->password=auth_info->password?ms_strdup(auth_info->password):NULL;
279         return new_auth_info;
280 }
281 void sal_auth_info_delete(const SalAuthInfo* auth_info) {
282         if (auth_info->username) ms_free(auth_info->username);
283         if (auth_info->userid) ms_free(auth_info->userid);
284         if (auth_info->realm) ms_free(auth_info->realm);
285         if (auth_info->password) ms_free(auth_info->password);
286         ms_free((void*)auth_info);
287 }