~ubuntu-branches/ubuntu/quantal/linphone/quantal

« back to all changes in this revision

Viewing changes to exosip/jresponse.c

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Mimram
  • Date: 2006-11-15 10:34:50 UTC
  • mfrom: (1.2.1 upstream) (2.1.8 feisty)
  • Revision ID: james.westby@ubuntu.com-20061115103450-qgafwcks2lkhctlj
* New upstream release.
* Enable video support.
* Fix mismatched #endif in mscommon.h, closes: #398307.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  eXosip - This is the eXtended osip library.
 
3
  Copyright (C) 2002, 2003  Aymeric MOIZARD  - jack@atosc.org
 
4
  
 
5
  eXosip 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
  eXosip 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
#ifdef ENABLE_MPATROL
 
22
#include <mpatrol.h>
 
23
#endif
 
24
 
 
25
#include "eXosip2.h"
 
26
#include <eXosip_cfg.h>
 
27
 
 
28
extern eXosip_t eXosip;
 
29
 
 
30
/* Private functions */
 
31
static char *generating_no_sdp_answer(eXosip_call_t *jc, eXosip_dialog_t *jd,
 
32
                         osip_message_t *orig_request, char *local_sdp_port);
 
33
 
 
34
int
 
35
eXosip_build_response_default(int jid, int status)
 
36
{
 
37
  return -1;
 
38
}
 
39
 
 
40
int
 
41
_eXosip_build_response_default(osip_message_t **dest, osip_dialog_t *dialog,
 
42
                               int status, osip_message_t *request)
 
43
{
 
44
  osip_generic_param_t *tag;
 
45
  osip_message_t *response;
 
46
  int pos;
 
47
  int i;
 
48
 
 
49
  if (request==NULL) return -1;
 
50
 
 
51
  i = osip_message_init(&response);
 
52
  if (i!=0)
 
53
    return -1;
 
54
  /* initialise osip_message_t structure */
 
55
  /* yet done... */
 
56
 
 
57
  response->sip_version = (char *)osip_malloc(8*sizeof(char));
 
58
  sprintf(response->sip_version,"SIP/2.0");
 
59
  osip_message_set_status_code(response, status);
 
60
 
 
61
  /* handle some internal reason definitions. */
 
62
  if (MSG_IS_NOTIFY(request) && status==481)
 
63
    {
 
64
      response->reason_phrase = osip_strdup("Subcription Does Not Exist");
 
65
    }
 
66
  else if (MSG_IS_SUBSCRIBE(request) && status==202)
 
67
    {
 
68
      response->reason_phrase = osip_strdup("Accepted subscription");
 
69
    }
 
70
  else
 
71
    {
 
72
      response->reason_phrase = osip_strdup(osip_message_get_reason(status));
 
73
      if (response->reason_phrase==NULL)
 
74
        {
 
75
          if (response->status_code == 101)
 
76
            response->reason_phrase = osip_strdup("Dialog Establishement");
 
77
          else
 
78
            response->reason_phrase = osip_strdup("Unknown code");
 
79
        }
 
80
      response->req_uri     = NULL;
 
81
      response->sip_method = NULL;
 
82
    }
 
83
 
 
84
  i = osip_to_clone(request->to, &(response->to));
 
85
  if (i!=0) goto grd_error_1;
 
86
 
 
87
  i = osip_to_get_tag(response->to,&tag);
 
88
  if (i!=0)
 
89
    {  /* we only add a tag if it does not already contains one! */
 
90
      if ((dialog!=NULL) && (dialog->local_tag!=NULL))
 
91
        /* it should contain the local TAG we created */
 
92
        { osip_to_set_tag(response->to, osip_strdup(dialog->local_tag)); }
 
93
      else
 
94
        {
 
95
          if (status!=100)
 
96
            osip_to_set_tag(response->to, osip_to_tag_new_random());
 
97
        }
 
98
    }
 
99
 
 
100
  i = osip_from_clone(request->from, &(response->from));
 
101
  if (i!=0) goto grd_error_1;
 
102
 
 
103
  pos = 0;
 
104
  while (!osip_list_eol(request->vias,pos))
 
105
    {
 
106
      osip_via_t *via;
 
107
      osip_via_t *via2;
 
108
      via = (osip_via_t *)osip_list_get(request->vias,pos);
 
109
      i = osip_via_clone(via, &via2);
 
110
      if (i!=-0) goto grd_error_1;
 
111
      osip_list_add(response->vias, via2, -1);
 
112
      pos++;
 
113
    }
 
114
 
 
115
  i = osip_call_id_clone(request->call_id, &(response->call_id));
 
116
  if (i!=0) goto grd_error_1;
 
117
  i = osip_cseq_clone(request->cseq, &(response->cseq));
 
118
  if (i!=0) goto grd_error_1;
 
119
 
 
120
  if (MSG_IS_SUBSCRIBE(request))
 
121
    {
 
122
      osip_header_t *exp;
 
123
      osip_message_set_header(response, "Event", "presence");
 
124
      i = osip_message_get_expires(request, 0, &exp);
 
125
      if (exp==NULL)
 
126
        {
 
127
          osip_header_t *cp;
 
128
          i = osip_header_clone(exp, &cp);
 
129
          if (cp!=NULL)
 
130
            osip_list_add(response->headers, cp, 0);
 
131
        }
 
132
    }
 
133
    
 
134
  osip_message_set_allow(response, "INVITE");
 
135
  osip_message_set_allow(response, "ACK");
 
136
  osip_message_set_allow(response, "OPTIONS");
 
137
  osip_message_set_allow(response, "CANCEL");
 
138
  osip_message_set_allow(response, "BYE");
 
139
  osip_message_set_allow(response, "SUBSCRIBE");
 
140
  osip_message_set_allow(response, "NOTIFY");
 
141
  osip_message_set_allow(response, "MESSAGE");
 
142
  osip_message_set_allow(response, "INFO");
 
143
 
 
144
  *dest = response;
 
145
  return 0;
 
146
 
 
147
 grd_error_1:
 
148
  osip_message_free(response);
 
149
  return -1;
 
150
}
 
151
 
 
152
int
 
153
complete_answer_that_establish_a_dialog(osip_message_t *response, osip_message_t *request)
 
154
{
 
155
  int i;
 
156
  int pos=0;
 
157
  char contact[1000];
 
158
#ifdef SM
 
159
  char *locip=NULL;
 
160
#else
 
161
  char locip[50];
 
162
#endif
 
163
  /* 12.1.1:
 
164
     copy all record-route in response
 
165
     add a contact with global scope
 
166
  */
 
167
  while (!osip_list_eol(request->record_routes, pos))
 
168
    {
 
169
      osip_record_route_t *rr;
 
170
      osip_record_route_t *rr2;
 
171
      rr = osip_list_get(request->record_routes, pos);
 
172
      i = osip_record_route_clone(rr, &rr2);
 
173
      if (i!=0) return -1;
 
174
      osip_list_add(response->record_routes, rr2, -1);
 
175
      pos++;
 
176
    }
 
177
 
 
178
#ifdef SM
 
179
  eXosip_get_localip_from_via(response,&locip);
 
180
#else
 
181
  eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49);
 
182
#endif
 
183
  
 
184
  if (eXosip.answer_contact[0])
 
185
    snprintf(contact,1000, "%s", eXosip.answer_contact);
 
186
  else if (request->to->url->username==NULL)
 
187
    snprintf(contact,1000, "<sip:%s:%s>", locip, eXosip.localport);
 
188
  else
 
189
    snprintf(contact,1000, "<sip:%s@%s:%s>", request->to->url->username,
 
190
             locip, eXosip.localport);
 
191
 
 
192
  if (eXosip.j_firewall_ip[0]!='\0')
 
193
    {
 
194
      osip_contact_t *con = (osip_contact_t *) osip_list_get (request->contacts, 0);
 
195
      if (con!=NULL && con->url!=NULL && con->url->host!=NULL)
 
196
        {
 
197
          char *c_address = con->url->host;
 
198
 
 
199
          struct addrinfo *addrinfo;
 
200
          struct __eXosip_sockaddr addr;
 
201
          i = eXosip_get_addrinfo(&addrinfo, con->url->host, 5060);
 
202
          if (i==0)
 
203
                {
 
204
                  memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
 
205
                  freeaddrinfo (addrinfo);
 
206
                  c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr);
 
207
                  OSIP_TRACE (osip_trace
 
208
                          (__FILE__, __LINE__, OSIP_INFO1, NULL,
 
209
                          "eXosip: here is the resolved destination host=%s\n", c_address));
 
210
                }
 
211
 
 
212
          /* If c_address is a PUBLIC address, the request was
 
213
             coming from the PUBLIC network. */
 
214
          if (eXosip_is_public_address(c_address))
 
215
            {
 
216
              if (request->to->url->username==NULL)
 
217
                snprintf(contact,1000, "<sip:%s:%s>", eXosip.j_firewall_ip,
 
218
                         eXosip.localport);
 
219
              else
 
220
                snprintf(contact,1000, "<sip:%s@%s:%s>", request->to->url->username,
 
221
                         eXosip.j_firewall_ip, eXosip.localport);
 
222
            }
 
223
        }
 
224
    }
 
225
 
 
226
#ifdef SM
 
227
  osip_free(locip);
 
228
#endif
 
229
 
 
230
  osip_message_set_contact(response, contact);
 
231
        
 
232
  return 0;
 
233
}
 
234
 
 
235
static char *
 
236
generating_no_sdp_answer(eXosip_call_t *jc, eXosip_dialog_t *jd,
 
237
                         osip_message_t *orig_request, char *local_sdp_port)
 
238
{
 
239
  sdp_message_t *local_sdp = NULL;
 
240
  char *local_body = NULL;
 
241
  char *size;
 
242
  int i;
 
243
  
 
244
  jc->c_ack_sdp = 1;
 
245
  if(osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &local_sdp, local_sdp_port, NULL) != 0)
 
246
    return NULL;
 
247
  
 
248
  if (local_sdp!=NULL)
 
249
    {
 
250
      int pos=0;
 
251
      while (!sdp_message_endof_media (local_sdp, pos))
 
252
        {
 
253
          int k = 0;
 
254
          char *tmp = sdp_message_m_media_get (local_sdp, pos);
 
255
          if (0 == strncmp (tmp, "audio", 5))
 
256
            {
 
257
              char *payload = NULL;
 
258
              do {
 
259
                payload = sdp_message_m_payload_get (local_sdp, pos, k);
 
260
                if (payload == NULL)
 
261
                  {
 
262
                  }
 
263
                else if (0==strcmp("110",payload))
 
264
                  {
 
265
                    sdp_message_a_attribute_add (local_sdp,
 
266
                                                 pos,
 
267
                                                 osip_strdup ("AS"),
 
268
                                                 osip_strdup ("110 20"));
 
269
                  }
 
270
                else if (0==strcmp("111",payload))
 
271
                  {
 
272
                    sdp_message_a_attribute_add (local_sdp,
 
273
                                                 pos,
 
274
                                                 osip_strdup ("AS"),
 
275
                                                 osip_strdup ("111 20"));
 
276
                  }
 
277
                k++;
 
278
              } while (payload != NULL);
 
279
            }
 
280
          pos++;
 
281
        }
 
282
    }
 
283
  
 
284
  i = sdp_message_to_str(local_sdp, &local_body);
 
285
  
 
286
  if (local_body!=NULL)
 
287
    {
 
288
      size= (char *)osip_malloc(7*sizeof(char));
 
289
#ifdef __APPLE_CC__
 
290
      sprintf(size,"%li",strlen(local_body));
 
291
#else
 
292
      sprintf(size,"%i",strlen(local_body));
 
293
#endif
 
294
      osip_message_set_content_length(orig_request, size);
 
295
      osip_free(size);
 
296
  
 
297
      osip_message_set_body(orig_request, local_body, strlen(local_body));
 
298
      osip_message_set_content_type(orig_request, "application/sdp");
 
299
    }
 
300
  else
 
301
    osip_message_set_content_length(orig_request, "0");
 
302
  
 
303
  osip_negotiation_ctx_set_local_sdp(jc->c_ctx, local_sdp);
 
304
  
 
305
  OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO3,NULL,"200 OK w/ SDP (RESPONSE TO INVITE w/ NO SDP)=\n%s\n", local_body));
 
306
  
 
307
  return local_body;
 
308
}
 
309
 
 
310
char *
 
311
generating_sdp_answer(osip_message_t *request, osip_negotiation_ctx_t *context)
 
312
{
 
313
  sdp_message_t *remote_sdp;
 
314
  sdp_message_t *local_sdp = NULL;
 
315
  int i;
 
316
  char *local_body;
 
317
  if (context==NULL)
 
318
    return NULL;
 
319
 
 
320
  local_body = NULL;
 
321
  if (MSG_IS_INVITE(request)||MSG_IS_OPTIONS(request)||MSG_IS_RESPONSE_FOR(request, "INVITE"))
 
322
    {
 
323
      osip_body_t *body;
 
324
      body = (osip_body_t *)osip_list_get(request->bodies,0);
 
325
      if(body == NULL)
 
326
        return NULL;
 
327
      
 
328
      /* remote_sdp = (sdp_message_t *) osip_malloc(sizeof(sdp_message_t)); */
 
329
      i = sdp_message_init(&remote_sdp);
 
330
      if (i!=0) return NULL;
 
331
      
 
332
      /* WE ASSUME IT IS A SDP BODY AND THAT    */
 
333
      /* IT IS THE ONLY ONE, OF COURSE, THIS IS */
 
334
      /* NOT TRUE */
 
335
      i = sdp_message_parse(remote_sdp,body->body);
 
336
      if (i!=0) return NULL;
 
337
 
 
338
      i = osip_negotiation_ctx_set_remote_sdp(context, remote_sdp);
 
339
 
 
340
      i = osip_negotiation_ctx_execute_negotiation(eXosip.osip_negotiation, context);
 
341
      if (i==200)
 
342
        {
 
343
          local_sdp = osip_negotiation_ctx_get_local_sdp(context);
 
344
 
 
345
          if (eXosip.j_firewall_ip[0]!='\0')
 
346
          {
 
347
                  char *c_address = NULL;
 
348
                  int pos=0;
 
349
                  /* If remote message contains a Public IP, we have to replace the SDP
 
350
                        connection address */
 
351
                  c_address = sdp_message_c_addr_get(remote_sdp, -1, 0);
 
352
                  while (c_address==NULL)
 
353
                  {
 
354
                          c_address = sdp_message_c_addr_get(remote_sdp, pos, 0);
 
355
                          pos++;
 
356
                          if (pos>10)
 
357
                                  break;
 
358
                  }
 
359
                  if (c_address!=NULL) /* found a connection address: check if it is public */
 
360
                  {
 
361
 
 
362
                          struct addrinfo *addrinfo;
 
363
                          struct __eXosip_sockaddr addr;
 
364
                          i = eXosip_get_addrinfo(&addrinfo, c_address, 5060);
 
365
                          if (i==0)
 
366
                                {
 
367
                                  memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
 
368
                                  freeaddrinfo (addrinfo);
 
369
                                  c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr);
 
370
                                  OSIP_TRACE (osip_trace
 
371
                                          (__FILE__, __LINE__, OSIP_INFO1, NULL,
 
372
                                          "eXosip: here is the resolved destination host=%s\n", c_address));
 
373
                                }
 
374
 
 
375
                          if (eXosip_is_public_address(c_address))
 
376
                            {
 
377
                                  /* replace the IP with our firewall ip */
 
378
                                  sdp_connection_t *conn;
 
379
                                  pos=-1;
 
380
                                  conn = sdp_message_connection_get(local_sdp, pos, 0);
 
381
                                  while (conn!=NULL)
 
382
                                  {
 
383
                                          if (conn->c_addr!=NULL )
 
384
                                          {
 
385
                                                  osip_free(conn->c_addr);
 
386
                                                  conn->c_addr = osip_strdup(eXosip.j_firewall_ip);
 
387
                                          }
 
388
                                          pos++;
 
389
                                          conn = sdp_message_connection_get(local_sdp, pos, 0);
 
390
                                  }
 
391
                            }
 
392
                  }
 
393
          }
 
394
 
 
395
          i = sdp_message_to_str(local_sdp, &local_body);
 
396
 
 
397
          remote_sdp = osip_negotiation_ctx_get_remote_sdp(context);
 
398
          sdp_message_free(remote_sdp);
 
399
          osip_negotiation_ctx_set_remote_sdp(context, NULL);
 
400
 
 
401
          if (i!=0) {
 
402
            OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not parse local SDP answer %i\n",i));
 
403
            return NULL;
 
404
          }
 
405
          return local_body;
 
406
        }
 
407
      else if (i==415)
 
408
        {
 
409
          OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"WARNING: Unsupported media %i\n",i));
 
410
        }
 
411
      else
 
412
        {
 
413
          OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: while building answer to SDP (%i)\n",i));
 
414
        }
 
415
      remote_sdp = osip_negotiation_ctx_get_remote_sdp(context);
 
416
      sdp_message_free(remote_sdp);
 
417
      osip_negotiation_ctx_set_remote_sdp(context, NULL);
 
418
    }
 
419
  return NULL;
 
420
}
 
421
 
 
422
int
 
423
eXosip_answer_options_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
 
424
{
 
425
  osip_event_t *evt_answer;
 
426
  osip_transaction_t *tr;
 
427
  osip_message_t *response;
 
428
  int i;
 
429
 
 
430
  tr = eXosip_find_last_inc_options(jc, jd);
 
431
  if (tr==NULL)
 
432
    {
 
433
      OSIP_TRACE (osip_trace
 
434
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
435
         "eXosip: cannot find transaction to answer"));
 
436
      return -1;
 
437
    }
 
438
 
 
439
  if (jd!=NULL)
 
440
    {
 
441
      i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
442
    }
 
443
  else
 
444
    {
 
445
      i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
 
446
    }
 
447
 
 
448
  if (i!=0)
 
449
    {
 
450
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for OPTIONS\n"));
 
451
      return -1;
 
452
    }
 
453
 
 
454
  evt_answer = osip_new_outgoing_sipmessage(response);
 
455
  evt_answer->transactionid = tr->transactionid;
 
456
 
 
457
  osip_transaction_add_event(tr, evt_answer);
 
458
  __eXosip_wakeup();
 
459
  return 0;
 
460
}
 
461
 
 
462
int
 
463
eXosip_answer_options_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
 
464
{
 
465
  osip_event_t *evt_answer;
 
466
  osip_transaction_t *tr;
 
467
  osip_message_t *response;
 
468
  sdp_message_t *sdp;
 
469
  char *body;
 
470
  char size[10];
 
471
  int i;
 
472
 
 
473
  tr = eXosip_find_last_inc_options(jc, jd);
 
474
  if (tr==NULL)
 
475
    {
 
476
      OSIP_TRACE (osip_trace
 
477
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
478
         "eXosip: cannot find transaction to answer"));
 
479
      return -1;
 
480
    }
 
481
  osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &sdp, "10400", NULL);
 
482
  if (sdp==NULL)
 
483
    {
 
484
      return -1;
 
485
    }
 
486
  if (jd!=NULL)
 
487
    {
 
488
      i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
489
    }
 
490
  else
 
491
    {
 
492
      i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
 
493
    }
 
494
  if (i!=0)
 
495
    {
 
496
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n"));
 
497
      sdp_message_free(sdp); /* not used */
 
498
      return -1;
 
499
    }
 
500
  i = sdp_message_to_str(sdp, &body);
 
501
  sdp_message_free(sdp);
 
502
  if (i!=0) {
 
503
    osip_message_free(response);
 
504
    return -1;
 
505
  }
 
506
  i = osip_message_set_body(response, body, strlen(body));
 
507
  if (i!=0) {
 
508
    osip_message_free(response);
 
509
    return -1;
 
510
  }
 
511
#ifdef __APPLE_CC__
 
512
  snprintf(size, 9,"%li",strlen(body));
 
513
#else
 
514
  snprintf(size, 9,"%i",strlen(body));
 
515
#endif
 
516
  i = osip_message_set_content_length(response, size);
 
517
  if (i!=0) {
 
518
    osip_free(body);
 
519
    osip_message_free(response);
 
520
    return -1;
 
521
  }
 
522
  osip_free(body);
 
523
  i = osip_message_set_content_type(response, "application/sdp");
 
524
  if (i!=0) {
 
525
    osip_message_free(response);
 
526
    return -1;
 
527
  }
 
528
 
 
529
  evt_answer = osip_new_outgoing_sipmessage(response);
 
530
  evt_answer->transactionid = tr->transactionid;
 
531
 
 
532
  osip_transaction_add_event(tr, evt_answer);
 
533
  __eXosip_wakeup();
 
534
  return 0;
 
535
}
 
536
 
 
537
int
 
538
eXosip_answer_options_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
 
539
{
 
540
  osip_event_t *evt_answer;
 
541
  osip_transaction_t *tr;
 
542
  osip_message_t *response;
 
543
  int i;
 
544
  tr = eXosip_find_last_inc_options(jc, jd);
 
545
  if (tr==NULL)
 
546
    {
 
547
      OSIP_TRACE (osip_trace
 
548
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
549
         "eXosip: cannot find transaction to answer"));
 
550
      return -1;
 
551
    }
 
552
 
 
553
  if (jd!=NULL)
 
554
    {
 
555
      i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
556
    }
 
557
  else
 
558
    {
 
559
      i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
 
560
    }
 
561
  if (i!=0)
 
562
    {
 
563
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n"));
 
564
      return -1;
 
565
    }
 
566
 
 
567
  if (300<=code<=399)
 
568
    {
 
569
      /* Should add contact fields */
 
570
      /* ... */
 
571
      osip_message_set_contact(response, jc->c_redirection);
 
572
    }
 
573
 
 
574
  osip_message_set_content_length(response, "0");
 
575
  /*  send message to transaction layer */
 
576
 
 
577
  evt_answer = osip_new_outgoing_sipmessage(response);
 
578
  evt_answer->transactionid = tr->transactionid;
 
579
 
 
580
  osip_transaction_add_event(tr, evt_answer);
 
581
  __eXosip_wakeup();
 
582
 
 
583
  return 0;
 
584
}
 
585
 
 
586
int
 
587
_eXosip2_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer)
 
588
{
 
589
  int i;
 
590
  osip_transaction_t *tr;
 
591
  tr = eXosip_find_last_inc_invite(jc, jd);
 
592
  if (tr==NULL)
 
593
    {
 
594
      OSIP_TRACE (osip_trace
 
595
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
596
         "eXosip: cannot find transaction to answer"));
 
597
      return -1;
 
598
    }
 
599
  /* is the transaction already answered? */
 
600
  if (tr->state==IST_COMPLETED
 
601
      || tr->state==IST_CONFIRMED
 
602
      || tr->state==IST_TERMINATED)
 
603
    {
 
604
      OSIP_TRACE (osip_trace
 
605
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
606
         "eXosip: transaction already answered\n"));
 
607
      return -1;
 
608
    }
 
609
 
 
610
  if (jd==NULL)
 
611
    i = _eXosip_build_response_default(answer, NULL, code, tr->orig_request);
 
612
  else
 
613
    i = _eXosip_build_response_default(answer, jd->d_dialog, code, tr->orig_request);
 
614
 
 
615
  if (i!=0)
 
616
    {
 
617
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for invite\n"));
 
618
      return -2;
 
619
    }
 
620
 
 
621
  osip_message_set_content_length(*answer, "0");
 
622
  /*  send message to transaction layer */
 
623
 
 
624
  if (code>100)
 
625
    {
 
626
      i = complete_answer_that_establish_a_dialog(*answer, tr->orig_request);
 
627
    }
 
628
  
 
629
  return 0;
 
630
}
 
631
 
 
632
int
 
633
_eXosip2_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer)
 
634
{
 
635
  int i;
 
636
  osip_transaction_t *tr;
 
637
  tr = eXosip_find_last_inc_invite(jc, jd);
 
638
 
 
639
  if (tr==NULL || tr->orig_request==NULL)
 
640
    {
 
641
      OSIP_TRACE (osip_trace
 
642
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
643
         "eXosip: cannot find transaction to answer\n"));
 
644
      return -1;
 
645
    }
 
646
 
 
647
  if (jd!=NULL && jd->d_dialog==NULL)
 
648
    {  /* element previously removed */
 
649
      OSIP_TRACE (osip_trace
 
650
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
651
         "eXosip: cannot answer this closed transaction\n"));
 
652
      return -1;
 
653
    }
 
654
 
 
655
  /* is the transaction already answered? */
 
656
  if (tr->state==IST_COMPLETED
 
657
      || tr->state==IST_CONFIRMED
 
658
      || tr->state==IST_TERMINATED)
 
659
    {
 
660
      OSIP_TRACE (osip_trace
 
661
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
662
         "eXosip: transaction already answered\n"));
 
663
      return -1;
 
664
    }
 
665
  
 
666
  if (jd==NULL)
 
667
    i = _eXosip_build_response_default(answer, NULL, code, tr->orig_request);
 
668
  else
 
669
    i = _eXosip_build_response_default(answer, jd->d_dialog, code, tr->orig_request);
 
670
 
 
671
  if (i!=0)
 
672
    {
 
673
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
 
674
      return -1;
 
675
    }
 
676
 
 
677
  /* request that estabish a dialog: */
 
678
  /* 12.1.1 UAS Behavior */
 
679
  {
 
680
    i = complete_answer_that_establish_a_dialog(*answer, tr->orig_request);
 
681
    if (i!=0) goto g2atii_error_1;; /* ?? */
 
682
  }
 
683
 
 
684
  return 0;
 
685
 
 
686
 g2atii_error_1:
 
687
  osip_message_free(*answer);
 
688
  return -1;
 
689
}
 
690
 
 
691
int
 
692
_eXosip2_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer)
 
693
{
 
694
  int i;
 
695
  osip_transaction_t *tr;
 
696
  tr = eXosip_find_last_inc_invite(jc, jd);
 
697
  if (tr==NULL)
 
698
    {
 
699
      OSIP_TRACE (osip_trace
 
700
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
701
         "eXosip: cannot find transaction to answer"));
 
702
      return -1;
 
703
    }
 
704
  /* is the transaction already answered? */
 
705
  if (tr->state==IST_COMPLETED
 
706
      || tr->state==IST_CONFIRMED
 
707
      || tr->state==IST_TERMINATED)
 
708
    {
 
709
      OSIP_TRACE (osip_trace
 
710
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
711
         "eXosip: transaction already answered\n"));
 
712
      return -1;
 
713
    }
 
714
 
 
715
  i = _eXosip_build_response_default(answer, jd->d_dialog, code, tr->orig_request);
 
716
  if (i!=0)
 
717
    {
 
718
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
 
719
      return -1;
 
720
    }
 
721
 
 
722
  if (300<=code<=399)
 
723
    {
 
724
      /* Should add contact fields */
 
725
      /* ... */
 
726
    }
 
727
 
 
728
  osip_message_set_content_length(*answer, "0");
 
729
  /*  send message to transaction layer */
 
730
 
 
731
  return 0;
 
732
}
 
733
 
 
734
int
 
735
eXosip_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
 
736
{
 
737
  osip_event_t *evt_answer;
 
738
  osip_message_t *response;
 
739
  int i;
 
740
  osip_transaction_t *tr;
 
741
  tr = eXosip_find_last_inc_invite(jc, jd);
 
742
  if (tr==NULL)
 
743
    {
 
744
      OSIP_TRACE (osip_trace
 
745
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
746
         "eXosip: cannot find transaction to answer"));
 
747
      return -1;
 
748
    }
 
749
  /* is the transaction already answered? */
 
750
  if (tr->state==IST_COMPLETED
 
751
      || tr->state==IST_CONFIRMED
 
752
      || tr->state==IST_TERMINATED)
 
753
    {
 
754
      OSIP_TRACE (osip_trace
 
755
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
756
         "eXosip: transaction already answered\n"));
 
757
      return -1;
 
758
    }
 
759
 
 
760
  if (jd==NULL)
 
761
    i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
 
762
  else
 
763
    i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
764
 
 
765
  if (i!=0)
 
766
    {
 
767
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for invite\n"));
 
768
      return -2;
 
769
    }
 
770
 
 
771
  osip_message_set_content_length(response, "0");
 
772
  /*  send message to transaction layer */
 
773
 
 
774
  if (code>100)
 
775
    {
 
776
      /* request that estabish a dialog: */
 
777
      /* 12.1.1 UAS Behavior */
 
778
      i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
 
779
 
 
780
      if (jd==NULL)
 
781
        {
 
782
          i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
 
783
          if (i!=0)
 
784
            {
 
785
         OSIP_TRACE (osip_trace
 
786
                     (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
787
                 "eXosip: cannot create dialog!\n"));
 
788
            }
 
789
          ADD_ELEMENT(jc->c_dialogs, jd);
 
790
        }
 
791
    }
 
792
 
 
793
  evt_answer = osip_new_outgoing_sipmessage(response);
 
794
  evt_answer->transactionid = tr->transactionid;
 
795
 
 
796
  osip_transaction_add_event(tr, evt_answer);
 
797
  __eXosip_wakeup();
 
798
  
 
799
  return 0;
 
800
}
 
801
 
 
802
int
 
803
eXosip_answer_invite_2xx_with_body(eXosip_call_t *jc, eXosip_dialog_t *jd, int code,const char*bodytype, const char*body)
 
804
{
 
805
  osip_event_t *evt_answer;
 
806
  osip_message_t *response;
 
807
  int i;
 
808
  char *size;
 
809
  osip_transaction_t *tr;
 
810
  tr = eXosip_find_last_inc_invite(jc, jd);
 
811
 
 
812
  if (tr==NULL || tr->orig_request==NULL)
 
813
    {
 
814
      OSIP_TRACE (osip_trace
 
815
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
816
         "eXosip: cannot find transaction to answer\n"));
 
817
      return -1;
 
818
    }
 
819
 
 
820
  if (jd!=NULL && jd->d_dialog==NULL)
 
821
    {  /* element previously removed */
 
822
      OSIP_TRACE (osip_trace
 
823
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
824
         "eXosip: cannot answer this closed transaction\n"));
 
825
      return -1;
 
826
    }
 
827
 
 
828
  /* is the transaction already answered? */
 
829
  if (tr->state==IST_COMPLETED
 
830
      || tr->state==IST_CONFIRMED
 
831
      || tr->state==IST_TERMINATED)
 
832
    {
 
833
      OSIP_TRACE (osip_trace
 
834
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
835
         "eXosip: transaction already answered\n"));
 
836
      return -1;
 
837
    }
 
838
  
 
839
  if (jd==NULL)
 
840
    i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
 
841
  else
 
842
    i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
843
 
 
844
  if (i!=0)
 
845
    {
 
846
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
 
847
      code = 500; /* ? which code to use? */
 
848
      return -1;
 
849
    }
 
850
 
 
851
  if (code==488)
 
852
    {
 
853
      osip_message_set_content_length(response, "0");
 
854
      /*  TODO: send message to transaction layer */
 
855
      evt_answer = osip_new_outgoing_sipmessage(response);
 
856
      evt_answer->transactionid = tr->transactionid;
 
857
      osip_transaction_add_event(tr, evt_answer);
 
858
  __eXosip_wakeup();
 
859
      return 0;
 
860
    }
 
861
 
 
862
  i = osip_message_set_body(response, body, strlen(body));
 
863
  if (i!=0) {
 
864
    goto g2atii_error_1;
 
865
  }
 
866
  size = (char *) osip_malloc(6*sizeof(char));
 
867
  sprintf(size,"%i",strlen(body));
 
868
  i = osip_message_set_content_length(response, size);
 
869
  osip_free(size);
 
870
  if (i!=0) goto g2atii_error_1;
 
871
  i = osip_message_set_content_type(response, bodytype);
 
872
  if (i!=0) goto g2atii_error_1;
 
873
 
 
874
  /* request that estabish a dialog: */
 
875
  /* 12.1.1 UAS Behavior */
 
876
  {
 
877
    i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
 
878
    if (i!=0) goto g2atii_error_1;; /* ?? */
 
879
  }
 
880
  /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */
 
881
  /* this response must be stored at the upper layer!!! (it will be destroyed*/
 
882
  /* right after being sent! */
 
883
 
 
884
  if (jd==NULL)
 
885
    {
 
886
      i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
 
887
      if (i!=0)
 
888
        {
 
889
     OSIP_TRACE (osip_trace
 
890
                 (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
891
             "eXosip: cannot create dialog!\n"));
 
892
          return -1;
 
893
        }
 
894
      ADD_ELEMENT(jc->c_dialogs, jd);
 
895
    }
 
896
 
 
897
  eXosip_dialog_set_200ok(jd, response);
 
898
  evt_answer = osip_new_outgoing_sipmessage(response);
 
899
  evt_answer->transactionid = tr->transactionid;
 
900
 
 
901
  osip_transaction_add_event(tr, evt_answer);
 
902
 
 
903
  osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
 
904
  __eXosip_wakeup();
 
905
  return 0;
 
906
 
 
907
 g2atii_error_1:
 
908
  osip_message_free(response);
 
909
  return -1;
 
910
}
 
911
 
 
912
int
 
913
eXosip_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, char *local_sdp_port)
 
914
{
 
915
  osip_event_t *evt_answer;
 
916
  osip_message_t *response;
 
917
  int i;
 
918
  char *size;
 
919
  char *body = NULL;
 
920
  osip_transaction_t *tr;
 
921
  tr = eXosip_find_last_inc_invite(jc, jd);
 
922
 
 
923
  if (tr==NULL || tr->orig_request==NULL)
 
924
    {
 
925
      OSIP_TRACE (osip_trace
 
926
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
927
         "eXosip: cannot find transaction to answer\n"));
 
928
      return -1;
 
929
    }
 
930
 
 
931
  if (jd!=NULL && jd->d_dialog==NULL)
 
932
    {  /* element previously removed */
 
933
      OSIP_TRACE (osip_trace
 
934
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
935
         "eXosip: cannot answer this closed transaction\n"));
 
936
      return -1;
 
937
    }
 
938
 
 
939
  /* is the transaction already answered? */
 
940
  if (tr->state==IST_COMPLETED
 
941
      || tr->state==IST_CONFIRMED
 
942
      || tr->state==IST_TERMINATED)
 
943
    {
 
944
      OSIP_TRACE (osip_trace
 
945
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
946
         "eXosip: transaction already answered\n"));
 
947
      return -1;
 
948
    }
 
949
 
 
950
  /* WE SHOULD LOOK FOR A SDP PACKET!! */
 
951
  if(NULL != osip_list_get(tr->orig_request->bodies,0))
 
952
    {
 
953
      body = generating_sdp_answer(tr->orig_request, jc->c_ctx);
 
954
      if (body==NULL)
 
955
        code = 488; /* bad sdp */
 
956
    }
 
957
  else
 
958
    {
 
959
      if(local_sdp_port==NULL)
 
960
        code = 488; /* session description in the request is not acceptable. */
 
961
      else
 
962
        /* body is NULL (contains no SDP), generate a response to INVITE w/ no SDP */
 
963
        body = generating_no_sdp_answer(jc, jd, tr->orig_request, local_sdp_port);
 
964
    }
 
965
  
 
966
  if (jd==NULL)
 
967
    i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
 
968
  else
 
969
    i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
970
 
 
971
  if (i!=0)
 
972
    {
 
973
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
 
974
      code = 500; /* ? which code to use? */
 
975
      osip_free(body); /* not used */
 
976
      return -1;
 
977
    }
 
978
 
 
979
  if (code==488)
 
980
    {
 
981
      osip_message_set_content_length(response, "0");
 
982
      /*  TODO: send message to transaction layer */
 
983
      osip_free(body);
 
984
      evt_answer = osip_new_outgoing_sipmessage(response);
 
985
      evt_answer->transactionid = tr->transactionid;
 
986
      osip_transaction_add_event(tr, evt_answer);
 
987
          __eXosip_wakeup();
 
988
      return 0;
 
989
    }
 
990
 
 
991
  i = osip_message_set_body(response, body, strlen(body));
 
992
  if (i!=0) {
 
993
    goto g2atii_error_1;
 
994
  }
 
995
  size = (char *) osip_malloc(6*sizeof(char));
 
996
#ifdef __APPLE_CC__
 
997
  sprintf(size,"%li",strlen(body));
 
998
#else
 
999
  sprintf(size,"%i",strlen(body));
 
1000
#endif
 
1001
  i = osip_message_set_content_length(response, size);
 
1002
  osip_free(size);
 
1003
  if (i!=0) goto g2atii_error_1;
 
1004
  i = osip_message_set_content_type(response, "application/sdp");
 
1005
  if (i!=0) goto g2atii_error_1;
 
1006
 
 
1007
  /* request that estabish a dialog: */
 
1008
  /* 12.1.1 UAS Behavior */
 
1009
  {
 
1010
    i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
 
1011
    if (i!=0) goto g2atii_error_1;; /* ?? */
 
1012
  }
 
1013
 
 
1014
  osip_free(body);
 
1015
  /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */
 
1016
  /* this response must be stored at the upper layer!!! (it will be destroyed*/
 
1017
  /* right after being sent! */
 
1018
 
 
1019
  if (jd==NULL)
 
1020
    {
 
1021
      i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
 
1022
      if (i!=0)
 
1023
        {
 
1024
     OSIP_TRACE (osip_trace
 
1025
                 (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
1026
             "eXosip: cannot create dialog!\n"));
 
1027
          return -1;
 
1028
        }
 
1029
      ADD_ELEMENT(jc->c_dialogs, jd);
 
1030
    }
 
1031
 
 
1032
  eXosip_dialog_set_200ok(jd, response);
 
1033
  evt_answer = osip_new_outgoing_sipmessage(response);
 
1034
  evt_answer->transactionid = tr->transactionid;
 
1035
 
 
1036
  osip_transaction_add_event(tr, evt_answer);
 
1037
 
 
1038
  osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
 
1039
  __eXosip_wakeup();
 
1040
  return 0;
 
1041
 
 
1042
 g2atii_error_1:
 
1043
  osip_free(body);
 
1044
  osip_message_free(response);
 
1045
  return -1;
 
1046
}
 
1047
 
 
1048
int
 
1049
eXosip_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
 
1050
{
 
1051
  osip_event_t *evt_answer;
 
1052
  osip_message_t *response;
 
1053
  int i;
 
1054
  osip_transaction_t *tr;
 
1055
  tr = eXosip_find_last_inc_invite(jc, jd);
 
1056
  if (tr==NULL)
 
1057
    {
 
1058
      OSIP_TRACE (osip_trace
 
1059
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
1060
         "eXosip: cannot find transaction to answer"));
 
1061
      return -1;
 
1062
    }
 
1063
  /* is the transaction already answered? */
 
1064
  if (tr->state==IST_COMPLETED
 
1065
      || tr->state==IST_CONFIRMED
 
1066
      || tr->state==IST_TERMINATED)
 
1067
    {
 
1068
      OSIP_TRACE (osip_trace
 
1069
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
1070
         "eXosip: transaction already answered\n"));
 
1071
      return -1;
 
1072
    }
 
1073
 
 
1074
  i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
1075
  if (i!=0)
 
1076
    {
 
1077
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
 
1078
      return -1;
 
1079
    }
 
1080
 
 
1081
  if (300<=code<=399)
 
1082
    {
 
1083
      /* Should add contact fields */
 
1084
      /* ... */
 
1085
      osip_message_set_contact(response, jc->c_redirection);
 
1086
    }
 
1087
 
 
1088
  osip_message_set_content_length(response, "0");
 
1089
  /*  send message to transaction layer */
 
1090
 
 
1091
  evt_answer = osip_new_outgoing_sipmessage(response);
 
1092
  evt_answer->transactionid = tr->transactionid;
 
1093
 
 
1094
  osip_transaction_add_event(tr, evt_answer);
 
1095
  __eXosip_wakeup();
 
1096
  return 0;
 
1097
}
 
1098
 
 
1099
 
 
1100
void
 
1101
eXosip_notify_answer_subscribe_1xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code)
 
1102
{
 
1103
  osip_event_t *evt_answer;
 
1104
  osip_message_t *response;
 
1105
  int i;
 
1106
  osip_transaction_t *tr;
 
1107
  tr = eXosip_find_last_inc_subscribe(jn, jd);
 
1108
  if (tr==NULL)
 
1109
    {
 
1110
      OSIP_TRACE (osip_trace
 
1111
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
1112
         "eXosip: cannot find transaction to answer"));
 
1113
      return;
 
1114
    }
 
1115
 
 
1116
  if (jd==NULL)
 
1117
    i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
 
1118
  else
 
1119
    i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
1120
 
 
1121
  if (i!=0)
 
1122
    {
 
1123
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for subscribe\n"));
 
1124
      return;
 
1125
    }
 
1126
 
 
1127
  if (code>100)
 
1128
    {
 
1129
      /* request that estabish a dialog: */
 
1130
      /* 12.1.1 UAS Behavior */
 
1131
      i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
 
1132
 
 
1133
      if (jd==NULL)
 
1134
        {
 
1135
          i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
 
1136
          if (i!=0)
 
1137
            {
 
1138
         OSIP_TRACE (osip_trace
 
1139
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
1140
                 "eXosip: cannot create dialog!\n"));
 
1141
            }
 
1142
          ADD_ELEMENT(jn->n_dialogs, jd);
 
1143
        }
 
1144
    }
 
1145
 
 
1146
  evt_answer = osip_new_outgoing_sipmessage(response);
 
1147
  evt_answer->transactionid = tr->transactionid;
 
1148
 
 
1149
  osip_transaction_add_event(tr, evt_answer);
 
1150
  __eXosip_wakeup();
 
1151
  return ;
 
1152
}
 
1153
 
 
1154
void
 
1155
eXosip_notify_answer_subscribe_2xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code)
 
1156
{
 
1157
  osip_event_t *evt_answer;
 
1158
  osip_message_t *response;
 
1159
  int i;
 
1160
  osip_transaction_t *tr;
 
1161
  tr = eXosip_find_last_inc_subscribe(jn, jd);
 
1162
 
 
1163
  if (tr==NULL || tr->orig_request==NULL)
 
1164
    {
 
1165
      OSIP_TRACE (osip_trace
 
1166
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
1167
         "eXosip: cannot find transaction to answer\n"));
 
1168
      return;
 
1169
    }
 
1170
 
 
1171
  if (jd!=NULL && jd->d_dialog==NULL)
 
1172
    {  /* element previously removed, this is a no hop! */
 
1173
      OSIP_TRACE (osip_trace
 
1174
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
1175
         "eXosip: cannot answer this closed transaction\n"));
 
1176
      return ;
 
1177
    }
 
1178
 
 
1179
  if (jd==NULL)
 
1180
    i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
 
1181
  else
 
1182
    i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
1183
 
 
1184
  if (i!=0)
 
1185
    {
 
1186
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for subscribe\n"));
 
1187
      code = 500; /* ? which code to use? */
 
1188
      return;
 
1189
    }
 
1190
 
 
1191
  /* request that estabish a dialog: */
 
1192
  /* 12.1.1 UAS Behavior */
 
1193
  {
 
1194
    i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
 
1195
    if (i!=0) goto g2atii_error_1;; /* ?? */
 
1196
  }
 
1197
 
 
1198
  /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */
 
1199
  /* this response must be stored at the upper layer!!! (it will be destroyed*/
 
1200
  /* right after being sent! */
 
1201
 
 
1202
  if (jd==NULL)
 
1203
    {
 
1204
      i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
 
1205
      if (i!=0)
 
1206
        {
 
1207
     OSIP_TRACE (osip_trace
 
1208
       (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
1209
             "eXosip: cannot create dialog!\n"));
 
1210
          return;
 
1211
        }
 
1212
      ADD_ELEMENT(jn->n_dialogs, jd);
 
1213
    }
 
1214
 
 
1215
  eXosip_dialog_set_200ok(jd, response);
 
1216
  evt_answer = osip_new_outgoing_sipmessage(response);
 
1217
  evt_answer->transactionid = tr->transactionid;
 
1218
 
 
1219
  osip_transaction_add_event(tr, evt_answer);
 
1220
  __eXosip_wakeup();
 
1221
 
 
1222
  osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
 
1223
  return ;
 
1224
 
 
1225
 g2atii_error_1:
 
1226
  osip_message_free(response);
 
1227
  return ;
 
1228
}
 
1229
 
 
1230
void
 
1231
eXosip_notify_answer_subscribe_3456xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code)
 
1232
{
 
1233
  osip_event_t *evt_answer;
 
1234
  osip_message_t *response;
 
1235
  int i;
 
1236
  osip_transaction_t *tr;
 
1237
  tr = eXosip_find_last_inc_subscribe(jn, jd);
 
1238
  if (tr==NULL)
 
1239
    {
 
1240
      OSIP_TRACE (osip_trace
 
1241
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
 
1242
         "eXosip: cannot find transaction to answer"));
 
1243
      return;
 
1244
    }
 
1245
  i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
 
1246
  if (i!=0)
 
1247
    {
 
1248
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for subscribe\n"));
 
1249
      return;
 
1250
    }
 
1251
 
 
1252
  if (300<=code<=399)
 
1253
    {
 
1254
      /* Should add contact fields */
 
1255
      /* ... */
 
1256
    }
 
1257
 
 
1258
  evt_answer = osip_new_outgoing_sipmessage(response);
 
1259
  evt_answer->transactionid = tr->transactionid;
 
1260
 
 
1261
  osip_transaction_add_event(tr, evt_answer);
 
1262
  __eXosip_wakeup();
 
1263
  return ;
 
1264
}