2
The osipua library is a library based on oSIP that implements CallLeg and User Agent
4
Copyright (C) 2001 Simon MORLAT simon.morlat@free.fr
5
Aymeric MOIZARD jack@atosc.org
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Lesser General Public
8
License as published by the Free Software Foundation; either
9
version 2.1 of the License, or (at your option) any later version.
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Lesser General Public License for more details.
16
You should have received a copy of the GNU Lesser General Public
17
License along with this library; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
#include "uatransaction.h"
24
#include "osipmanager.h"
25
#include <osip/smsg.h>
26
#include <osip/smsgtypes.h>
28
int ua_transaction_get_destination(transaction_t *trn, char **destination, int *port)
30
if (trn->ctx_type==ICT){
31
*destination=trn->ict_context->destination;
32
*port=trn->ict_context->port;
34
else if (trn->ctx_type==NICT){
35
*destination=trn->nict_context->destination;
36
*port=trn->nict_context->port;
38
osip_trace(OSIP_ERROR,("Could not get destination for transaction: ctx_type=%i\n",trn->ctx_type));
46
void ua_transaction_set_destination(transaction_t *trn,char *destination, int port)
48
if (trn->ctx_type==ICT){
49
ict_set_destination(trn->ict_context,destination,port);
51
else if (trn->ctx_type==NICT){
52
nict_set_destination(trn->nict_context,destination,port);
54
osip_trace(OSIP_ERROR,("Could not set destination for transaction: ctx_type=%i\n",trn->ctx_type));
58
transaction_t * ua_transaction_new(OsipDialog *call,sip_t *sipmsg)
60
transaction_t *transaction;
65
if (call==NULL) return NULL;
68
if (MSG_IS_INVITE(sipmsg))
72
transaction_init(&transaction,
76
transaction->your_instance=(void*)call;
77
if (transaction==NULL) return NULL;
78
transaction_set_out_socket(transaction,ua->manager->send_sock);
79
/* if an outbound proxy is set for this call-leg, then set it to the transaction */
80
if ((ua->registrar!=NULL) && (ua->flags & OSIP_UA_USE_PROXY) )
83
if (ua->registrar->port!=NULL) port=atoi(ua->registrar->port);
84
ua_transaction_set_destination(transaction,sgetcopy(ua->registrar->host),port);
88
/* else set the destination in the req uri */
89
msg_getroute(sipmsg, 0, &route);
93
if (route->url->port!=NULL)
94
port = satoi(route->url->port);
95
if (MSG_IS_INVITE(sipmsg))
96
ict_set_destination(transaction->ict_context,
97
sgetcopy(route->url->host),
100
nict_set_destination(transaction->nict_context,
101
sgetcopy(route->url->host),
107
if (sipmsg->strtline->rquri->port!=NULL)
108
port = satoi(sipmsg->strtline->rquri->port);
109
if (MSG_IS_INVITE(sipmsg))
110
ict_set_destination(transaction->ict_context,
111
sgetcopy(sipmsg->strtline->rquri->host),
114
nict_set_destination(transaction->nict_context,
115
sgetcopy(sipmsg->strtline->rquri->host),
120
if (MSG_IS_INVITE(sipmsg))
121
ua_transaction_set_outgoing_invite_tr(transaction, call);
122
else if (MSG_IS_REGISTER(sipmsg))
123
ua_transaction_set_outgoing_register_tr(transaction, call);
124
else if (MSG_IS_BYE(sipmsg))
125
ua_transaction_set_outgoing_bye_tr(transaction, call);
126
else if (MSG_IS_CANCEL(sipmsg))
127
ua_transaction_set_outgoing_cancel_tr(transaction,call);
132
void ua_transaction_set_incoming_invite_tr(transaction_t *trn,OsipDialog *call)
134
OsipUA *ua = osip_dialog_get_ua (call);
135
if (call->inc_invite_tr)
136
call->inc_invite_tr->your_instance = NULL;
137
call->inc_invite_tr = trn;
138
trn->your_instance=call;
139
transaction_set_out_socket(trn,ua->manager->send_sock);
142
void ua_transaction_set_outgoing_invite_tr(transaction_t *trn,OsipDialog *call)
144
OsipUA *ua = osip_dialog_get_ua (call);
145
if (call->out_invite_tr)
146
call->out_invite_tr->your_instance = NULL;
147
call->out_invite_tr = trn;
148
trn->your_instance=call;
149
transaction_set_out_socket(trn,ua->manager->send_sock);
152
void ua_transaction_set_incoming_bye_tr(transaction_t *trn,OsipDialog *call)
154
OsipUA *ua = osip_dialog_get_ua (call);
155
if (call->inc_bye_tr)
156
call->inc_bye_tr->your_instance = NULL;
157
call->inc_bye_tr = trn;
158
trn->your_instance=call;
159
transaction_set_out_socket(trn,ua->manager->send_sock);
162
void ua_transaction_set_outgoing_bye_tr(transaction_t *trn,OsipDialog *call)
164
OsipUA *ua = osip_dialog_get_ua (call);
165
if (call->out_bye_tr)
166
call->out_bye_tr->your_instance = NULL;
167
call->out_bye_tr = trn;
168
trn->your_instance=call;
169
transaction_set_out_socket(trn,ua->manager->send_sock);
172
void ua_transaction_set_outgoing_register_tr(transaction_t *trn,OsipDialog *call)
174
OsipUA *ua = osip_dialog_get_ua (call);
175
if (call->out_register_tr)
176
call->out_register_tr->your_instance = NULL;
177
call->out_register_tr = trn;
178
trn->your_instance=call;
179
transaction_set_out_socket(trn,ua->manager->send_sock);
182
void ua_transaction_set_outgoing_cancel_tr(transaction_t *trn,OsipDialog *call)
184
OsipUA *ua = osip_dialog_get_ua (call);
185
if (call->out_cancel_tr)
186
call->out_cancel_tr->your_instance = NULL;
187
call->out_cancel_tr = trn;
188
trn->your_instance=call;
189
transaction_set_out_socket(trn,ua->manager->send_sock);
192
void ua_transaction_set_incoming_cancel_tr(transaction_t *trn,OsipDialog *call)
194
OsipUA *ua = osip_dialog_get_ua (call);
195
if (call->inc_cancel_tr)
196
call->inc_cancel_tr->your_instance = NULL;
197
call->inc_cancel_tr = trn;
198
trn->your_instance=call;
199
transaction_set_out_socket(trn,ua->manager->send_sock);
204
void ua_transaction_incoming_set_dialog(transaction_t *trn,OsipDialog *call)
206
OsipUA *ua=osip_dialog_get_ua(call);
207
list_add(&call->incoming_transactions,trn,-1);
208
trn->your_instance=call;
209
transaction_set_out_socket(trn,ua->manager->send_sock);
213
void ua_transaction_outgoing_set_dialog(transaction_t *trn,OsipDialog *call)
215
list_add(&call->outgoing_transactions,trn,-1);
216
trn->your_instance=call;
220
int is_in_recv_thread_context(OsipManager *manager)
222
return (manager->thread_pid==getpid());
225
void ua_transaction_free(transaction_t *transaction)
230
OsipManager *manager=def_manager;
232
/* check if the call_leg that the transaction is part of should not be deleted too*/
233
call=ua_transaction_get_dialog(transaction);
236
goto free_transaction;
237
osip_trace(OSIP_WARNING,("error: dialog==NULL ! "));
240
ua=osip_dialog_get_ua(call);
243
if (transaction==call->inc_invite_tr)
245
call->inc_invite_tr = NULL;
247
else if (transaction==call->out_invite_tr)
249
call->out_invite_tr = NULL;
251
else if (transaction==call->inc_bye_tr)
253
call->inc_bye_tr = NULL;
255
else if (transaction==call->out_bye_tr)
257
call->out_bye_tr = NULL;
259
else if (transaction==call->out_register_tr)
261
call->out_register_tr = NULL;
263
else if (transaction==call->out_cancel_tr){
264
call->out_cancel_tr = NULL;
265
}else if (transaction==call->inc_cancel_tr){
266
call->inc_cancel_tr = NULL;
268
transaction->your_instance=NULL;
270
/* now if it was the last active transaction of the dialog, delete the dialog*/
271
if (call->out_invite_tr==NULL && call->inc_invite_tr==NULL &&
272
call->out_bye_tr==NULL && call->inc_bye_tr==NULL &&
273
call->out_register_tr==NULL &&
274
call->out_cancel_tr == NULL && call->inc_cancel_tr == NULL)
276
switch (call->status)
279
case DIALOG_INVITING:
280
/* if the transaction timed out, notify it */
281
if (transaction->last_response==NULL){
284
/* the invite times out. The call-leg is lost. */
285
if (ua->faillure!=NULL)
286
ua->faillure(call,transaction,NULL,(void*)&error);
287
/* then destroy the dialog*/
288
osip_dialog_destroy(call);
292
case DIALOG_CANCELLING:
294
case DIALOG_CANCELLED:
295
case DIALOG_TERMINATED:
296
osip_dialog_destroy(call);
302
if (is_in_recv_thread_context(manager) ){
303
/* put the transaction in the free list */
304
fifo_add(&manager->garbage_trn,(void*)transaction);
306
smutex_lock(manager->mutex);
307
fifo_add(&manager->garbage_trn,(void*)transaction);
308
smutex_unlock(manager->mutex);
313
/* execute a transaction outside the receiving thread */
314
void ua_transaction_execute(transaction_t *trn, sipevent_t *ev)
317
OsipManager *manager;
318
OsipDialog *dialog=ua_transaction_get_dialog(trn);
322
printf("Executing transaction...\n");
326
osip_trace(OSIP_WARNING,("ua_transaction_execute: could not get dialog transaction.\n"));
329
ua=osip_dialog_get_ua(dialog);
332
/* check if we are within the process of the receiving thread
333
If you we are in, (probably in one of the osip callbacks), then we can safely run
334
fifo_add(trn->transactionff,ev);
335
If not the we have to take a lock to prevent the receiving thread from executing
336
the transaction while we process it */
337
cond=is_in_recv_thread_context(manager);
340
fifo_add(trn->transactionff,ev);
341
//transaction_execute(trn,ev);
344
smutex_lock(manager->mutex);
345
fifo_add(trn->transactionff,ev);
346
smutex_unlock(manager->mutex);
348
//osip_manager_wake_up(manager);