void eXosip_notify_answer_subscribe_3456xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code) { osip_event_t *evt_answer; osip_message_t *response; int i; osip_transaction_t *tr; tr = eXosip_find_last_inc_subscribe(jn, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return; } i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for subscribe\n")); return; } /* if (300<=code<=399) */ /* { */ /* /\* Should add contact fields *\/ */ /* /\* ... *\/ */ /* } */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return ; }
static int eXosip_create_cancel_transaction (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_message_t * request) { osip_event_t *sipevent; osip_transaction_t *tr; int i; i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, request); if (i != 0) { /* TODO: release the j_call.. */ osip_message_free (request); return i; } osip_list_add (&eXosip.j_transactions, tr, 0); sipevent = osip_new_outgoing_sipmessage (request); sipevent->transactionid = tr->transactionid; osip_transaction_add_event (tr, sipevent); __eXosip_wakeup (); return OSIP_SUCCESS; }
static int eXosip_create_transaction (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_message_t * request) { osip_event_t *sipevent; osip_transaction_t *tr; int i; i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, request); if (i != 0) { /* TODO: release the j_call.. */ osip_message_free (request); return i; } if (jd != NULL) osip_list_add (jd->d_out_trs, tr, 0); sipevent = osip_new_outgoing_sipmessage (request); sipevent->transactionid = tr->transactionid; #ifndef MINISIZE osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd, NULL, NULL)); #else osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd)); #endif osip_transaction_add_event (tr, sipevent); __eXosip_wakeup (); return OSIP_SUCCESS; }
int eXosip_message_send_request (osip_message_t * message) { osip_transaction_t *transaction; osip_event_t *sipevent; int i; i = _eXosip_transaction_init (&transaction, NICT, eXosip.j_osip, message); if (i != 0) { osip_message_free (message); return -1; } osip_list_add (eXosip.j_transactions, transaction, 0); sipevent = osip_new_outgoing_sipmessage (message); sipevent->transactionid = transaction->transactionid; #ifndef MINISIZE osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (NULL, NULL, NULL, NULL)); #else osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (NULL, NULL)); #endif osip_transaction_add_event (transaction, sipevent); __eXosip_wakeup (); return 0; }
int eXosip_options_send_request (osip_message_t * options) { osip_transaction_t *transaction; osip_event_t *sipevent; int i; i = osip_transaction_init (&transaction, NICT, eXosip.j_osip, options); if (i != 0) { osip_message_free (options); return -1; } osip_list_add (eXosip.j_transactions, transaction, 0); sipevent = osip_new_outgoing_sipmessage (options); sipevent->transactionid = transaction->transactionid; osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (NULL, NULL, NULL, NULL)); osip_transaction_add_event (transaction, sipevent); __eXosip_wakeup (); return 0; }
int eXosip_insubscription_send_request (int did, osip_message_t * request) { eXosip_dialog_t *jd = NULL; eXosip_notify_t *jn = NULL; osip_transaction_t *transaction; osip_event_t *sipevent; int i; if (request == NULL) return -1; if (did > 0) { eXosip_notify_dialog_find (did, &jn, &jd); } if (jd == NULL || jn == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No incoming subscription here?\n")); osip_message_free (request); return -1; } transaction = NULL; transaction = eXosip_find_last_out_notify (jn, jd); if (transaction != NULL) { if (transaction->state != NICT_TERMINATED && transaction->state != NIST_TERMINATED && transaction->state != NICT_COMPLETED && transaction->state != NIST_COMPLETED) { osip_message_free (request); return -1; } transaction = NULL; } i = osip_transaction_init (&transaction, NICT, eXosip.j_osip, request); if (i != 0) { osip_message_free (request); return -1; } osip_list_add (jd->d_out_trs, transaction, 0); sipevent = osip_new_outgoing_sipmessage (request); sipevent->transactionid = transaction->transactionid; osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (NULL, jd, NULL, jn)); osip_transaction_add_event (transaction, sipevent); __eXosip_wakeup (); return 0; }
int _eXosip_insubscription_answer_1xx (eXosip_notify_t * jn, eXosip_dialog_t * jd, int code) { osip_event_t *evt_answer; osip_message_t *response; int i; osip_transaction_t *tr; tr = eXosip_find_last_inc_subscribe (jn, jd); if (tr == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } if (jd == NULL) i = _eXosip_build_response_default (&response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default (&response, jd->d_dialog, code, tr->orig_request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ERROR: Could not create response for subscribe\n")); return -1; } if (code > 100) { /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ i = complete_answer_that_establish_a_dialog (response, tr->orig_request); if (jd == NULL) { i = eXosip_dialog_init_as_uas (&jd, tr->orig_request, response); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n")); } ADD_ELEMENT (jn->n_dialogs, jd); } } evt_answer = osip_new_outgoing_sipmessage (response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event (tr, evt_answer); __eXosip_wakeup (); return 0; }
int eXosip_message_send_answer (int tid, int status, osip_message_t * answer) { osip_transaction_t *tr = NULL; osip_event_t *evt_answer; int i = -1; if (tid <= 0) return OSIP_BADPARAMETER; if (status <= 100 || status > 699) return OSIP_BADPARAMETER; if (answer == NULL && status > 100 && status < 200) return OSIP_BADPARAMETER; if (tid > 0) { eXosip_transaction_find (tid, &tr); } if (tr == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No MESSAGE transaction found\n")); osip_message_free (answer); return OSIP_NOTFOUND; } /* is the transaction already answered? */ if (tr->state == NIST_COMPLETED || tr->state == NIST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); osip_message_free (answer); return OSIP_WRONG_STATE; } if (answer == NULL) { i = -1; if (status > 199 && status < 300) i = _eXosip_build_response_default (&answer, NULL, status, tr->orig_request); else if (status > 300 && status <= 699) i = _eXosip_build_response_default (&answer, NULL, status, tr->orig_request); if (i != 0) return i; } evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event (tr, evt_answer); __eXosip_wakeup (); return OSIP_SUCCESS; }
int eXosip_register_send_register (int rid, osip_message_t * reg) { osip_transaction_t *transaction; osip_event_t *sipevent; eXosip_reg_t *jr; int i; jr = eXosip_reg_find (rid); if (jr == NULL) { osip_message_free (reg); return -1; } if (jr->r_last_tr != NULL) { if (jr->r_last_tr->state != NICT_TERMINATED && jr->r_last_tr->state != NICT_COMPLETED) { osip_message_free (reg); return -1; } } if (reg == NULL) { i = _eXosip_register_build_register (jr, ®); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot build REGISTER!")); return i; } } i = _eXosip_transaction_init (&transaction, NICT, eXosip.j_osip, reg); if (i != 0) { /* TODO: release the j_call.. */ osip_message_free (reg); return -2; } jr->r_last_tr = transaction; /* send REGISTER */ sipevent = osip_new_outgoing_sipmessage (reg); sipevent->transactionid = transaction->transactionid; osip_message_force_update (reg); osip_transaction_add_event (transaction, sipevent); __eXosip_wakeup (); return 0; }
extern int _eXosip_answer_refer_123456(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) { osip_event_t *evt_answer; osip_transaction_t *tr; osip_message_t *response; int i; tr = eXosip_find_last_inc_refer(jc, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } if (jd!=NULL) { i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); } else { i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); } if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for REFER\n")); return -1; } if ( ( code >= 200 ) && ( code <= 299) ) complete_answer_that_establish_a_dialog(response, tr->orig_request); /* Yet another eeek */ /* if (300<=code<=399) */ /* { */ /* /\* Should add contact fields *\/ */ /* /\* ... *\/ */ /* } */ osip_message_set_content_length(response, "0"); /* send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; }
int eXosip_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, const char *contact) { osip_event_t *evt_answer; osip_message_t *response; int i; osip_transaction_t *tr; tr = eXosip_find_last_inc_invite(jc, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } /* is the transaction already answered? */ if (tr->state==IST_COMPLETED || tr->state==IST_CONFIRMED || tr->state==IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); return -1; } if ( ( code >= 300 ) && ( code <= 399 ) && ( contact != 0 ) ) { owsip_message_clean_contacts(response); osip_message_set_contact(response, contact); } osip_message_set_content_length(response, "0"); /* send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; }
int eXosip_call_send_initial_invite (osip_message_t * invite) { eXosip_call_t *jc; osip_transaction_t *transaction; osip_event_t *sipevent; int i; if (invite == NULL) { osip_message_free (invite); return OSIP_BADPARAMETER; } i = eXosip_call_init (&jc); if (i != 0) { osip_message_free (invite); return i; } i = _eXosip_transaction_init (&transaction, ICT, eXosip.j_osip, invite); if (i != 0) { eXosip_call_free (jc); osip_message_free (invite); return i; } jc->c_out_tr = transaction; sipevent = osip_new_outgoing_sipmessage (invite); sipevent->transactionid = transaction->transactionid; #ifndef MINISIZE osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, NULL, NULL, NULL)); #else osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, NULL)); #endif osip_transaction_add_event (transaction, sipevent); jc->external_reference = NULL; ADD_ELEMENT (eXosip.j_calls, jc); eXosip_update (); /* fixed? */ __eXosip_wakeup (); return jc->c_id; }
int eXosip_answer_options_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) { osip_event_t *evt_answer; osip_transaction_t *tr; osip_message_t *response; int i; tr = eXosip_find_last_inc_options(jc, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } if (jd!=NULL) { i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); } else { i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); } if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n")); return -1; } /* eeeeeeekkk! should be OUT of wengophone! */ /* if (300<=code<=399) */ /* { */ /* /\* Should add contact fields *\/ */ /* /\* ... *\/ */ /* } */ osip_message_set_content_length(response, "0"); /* send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; }
int eXosip_subscribe_send_subscribe(eXosip_subscribe_t *js, eXosip_dialog_t *jd, const char *expires) { osip_transaction_t *transaction; osip_message_t *subscribe; osip_event_t *sipevent; int i; transaction = eXosip_find_last_out_subscribe(js, jd); if (transaction!=NULL) { if (transaction->state!=NICT_TERMINATED && transaction->state!=NIST_TERMINATED) return -1; } i = _eXosip_build_request_within_dialog(&subscribe, "SUBSCRIBE", jd->d_dialog, "UDP"); if (i!=0) return -2; osip_message_set_expires(subscribe, expires); i = osip_transaction_init(&transaction, NICT, eXosip.j_osip, subscribe); if (i!=0) { /* TODO: release the j_call.. */ osip_message_free(subscribe); return -1; } _eXosip_subscribe_set_refresh_interval(js, subscribe); osip_list_add(jd->d_out_trs, transaction, 0); sipevent = osip_new_outgoing_sipmessage(subscribe); sipevent->transactionid = transaction->transactionid; osip_transaction_add_event(transaction, sipevent); osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, jd, js, NULL)); __eXosip_wakeup(); return 0; }
int eXosip_answer_options_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) { osip_event_t *evt_answer; osip_transaction_t *tr; osip_message_t *response; int i; tr = eXosip_find_last_inc_options(jc, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } if (jd!=NULL) { i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); } else { i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); } if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for OPTIONS\n")); return -1; } evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; }
int eXosip_call_send_answer (int tid, int status, osip_message_t * answer) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *tr = NULL; osip_event_t *evt_answer; if (tid < 0) { osip_message_free (answer); return OSIP_BADPARAMETER; } if (status <= 100) { osip_message_free (answer); return OSIP_BADPARAMETER; } if (status > 699) { osip_message_free (answer); return OSIP_BADPARAMETER; } if (tid > 0) { _eXosip_call_transaction_find (tid, &jc, &jd, &tr); } if (jd == NULL || tr == NULL || tr->orig_request == NULL || tr->orig_request->sip_method == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here or no transaction for call\n")); osip_message_free (answer); return OSIP_NOTFOUND; } if (answer == NULL) { if (0 == osip_strcasecmp (tr->orig_request->sip_method, "INVITE")) { if (status >= 200 && status <= 299) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Wrong parameter?\n")); osip_message_free (answer); return OSIP_BADPARAMETER; } } } /* is the transaction already answered? */ if (tr->state == IST_COMPLETED || tr->state == IST_CONFIRMED || tr->state == IST_TERMINATED || tr->state == NIST_COMPLETED || tr->state == NIST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); osip_message_free (answer); return OSIP_WRONG_STATE; } if (answer == NULL) { if (0 == osip_strcasecmp (tr->orig_request->sip_method, "INVITE")) { osip_message_t *response; return _eXosip_answer_invite_123456xx (jc, jd, status, &response, 1); } osip_message_free (answer); return OSIP_BADPARAMETER; } if (0 == osip_strcasecmp (tr->orig_request->sip_method, "INVITE")) { if (MSG_IS_STATUS_2XX (answer) && jd != NULL) { if (status >= 200 && status < 300 && jd != NULL) { eXosip_dialog_set_200ok (jd, answer); /* wait for a ACK */ osip_dialog_set_state (jd->d_dialog, DIALOG_CONFIRMED); } } } evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event (tr, evt_answer); eXosip_update (); __eXosip_wakeup (); return OSIP_SUCCESS; }
int eXosip_call_send_request (int jid, osip_message_t * request) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *transaction; osip_event_t *sipevent; int i; if (request == NULL) return OSIP_BADPARAMETER; if (jid <= 0) { osip_message_free (request); return OSIP_BADPARAMETER; } if (request->sip_method == NULL) { osip_message_free (request); return OSIP_BADPARAMETER; } if (jid > 0) { eXosip_call_dialog_find (jid, &jc, &jd); } if (jd == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); osip_message_free (request); return OSIP_NOTFOUND; } transaction = NULL; if (0 == osip_strcasecmp (request->sip_method, "INVITE")) { transaction = eXosip_find_last_invite (jc, jd); } else /* OPTIONS, UPDATE, INFO, REFER, ?... */ { transaction = eXosip_find_last_transaction (jc, jd, request->sip_method); } if (transaction != NULL) { if (0 != osip_strcasecmp (request->sip_method, "INVITE")) { if (transaction->state != NICT_TERMINATED && transaction->state != NIST_TERMINATED && transaction->state != NICT_COMPLETED && transaction->state != NIST_COMPLETED) { osip_message_free (request); return OSIP_WRONG_STATE; } } else { if (transaction->state != ICT_TERMINATED && transaction->state != IST_TERMINATED && transaction->state != IST_CONFIRMED && transaction->state != ICT_COMPLETED) { osip_message_free (request); return OSIP_WRONG_STATE; } } } transaction = NULL; if (0 != osip_strcasecmp (request->sip_method, "INVITE")) { i = _eXosip_transaction_init (&transaction, NICT, eXosip.j_osip, request); } else { i = _eXosip_transaction_init (&transaction, ICT, eXosip.j_osip, request); } if (i != 0) { osip_message_free (request); return i; } osip_list_add (jd->d_out_trs, transaction, 0); sipevent = osip_new_outgoing_sipmessage (request); sipevent->transactionid = transaction->transactionid; #ifndef MINISIZE osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd, NULL, NULL)); #else osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd)); #endif osip_transaction_add_event (transaction, sipevent); __eXosip_wakeup (); return OSIP_SUCCESS; }
int eXosip_subscribe_send_subscribe(eXosip_subscribe_t *js, eXosip_dialog_t *jd, const char *expires) { osip_transaction_t *transaction; osip_message_t *subscribe; osip_event_t *sipevent; int i; if (!jd || !jd->d_dialog) { // JULIEN : Maybe the first SUBSCRIBE didn't work // that's why there's no more dialog return -1; } transaction = eXosip_find_last_out_subscribe(js, jd); if (transaction!=NULL) { if (transaction->state!=NICT_TERMINATED && transaction->state!=NIST_TERMINATED) return -1; //<MINHPQ> // Remove the transaction from dialog structure if (jd) owsip_list_remove_element (jd->d_out_trs, transaction); // Remove the transaction from jd->d_out_trs list if (js && (js->s_out_tr == transaction)) { js->s_out_tr = NULL; // Remove the transaction from js->s_out_tr } eXosip_transaction_free(transaction); transaction = NULL; //</MINHPQ> } i = _eXosip_build_request_within_dialog(&subscribe, "SUBSCRIBE", jd->d_dialog); if (i!=0) return -2; //<MINHPQ> if (js->winfo) { owsip_message_set_header(subscribe, "Event", "presence.winfo"); owsip_message_set_header(subscribe, "Accept", "application/watcherinfo+xml"); } //</MINHPQ> owsip_message_set_expires(subscribe, expires); i = osip_transaction_init(&transaction, NICT, eXosip.j_osip, subscribe); if (i!=0) { /* TODO: release the j_call.. */ osip_message_free(subscribe); return -1; } _eXosip_subscribe_set_refresh_interval(js, subscribe); osip_list_add(jd->d_out_trs, transaction, 0); sipevent = osip_new_outgoing_sipmessage(subscribe); sipevent->transactionid = transaction->transactionid; osip_transaction_add_event(transaction, sipevent); osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(owsip_dialog_account_get (jd), NULL, jd, js, NULL)); __eXosip_wakeup(); return 0; }
int _eXosip_insubscription_answer_2xx (eXosip_notify_t * jn, eXosip_dialog_t * jd, int code) { osip_event_t *evt_answer; osip_message_t *response; int i; osip_transaction_t *tr; tr = eXosip_find_last_inc_subscribe (jn, jd); if (tr == NULL || tr->orig_request == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer\n")); return -1; } if (jd != NULL && jd->d_dialog == NULL) { /* element previously removed, this is a no hop! */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot answer this closed transaction\n")); return -1; } if (jd == NULL) i = _eXosip_build_response_default (&response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default (&response, jd->d_dialog, code, tr->orig_request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ERROR: Could not create response for subscribe\n")); code = 500; /* ? which code to use? */ return -1; } /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ { i = complete_answer_that_establish_a_dialog (response, tr->orig_request); if (i != 0) goto g2atii_error_1;; /* ?? */ } /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */ /* this response must be stored at the upper layer!!! (it will be destroyed */ /* right after being sent! */ if (jd == NULL) { i = eXosip_dialog_init_as_uas (&jd, tr->orig_request, response); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n")); return -1; } ADD_ELEMENT (jn->n_dialogs, jd); } eXosip_dialog_set_200ok (jd, response); evt_answer = osip_new_outgoing_sipmessage (response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event (tr, evt_answer); __eXosip_wakeup (); osip_dialog_set_state (jd->d_dialog, DIALOG_CONFIRMED); return 0; g2atii_error_1: osip_message_free (response); return -1; }
int _eXosip_default_answer_invite_1xx (eXosip_call_t * jc, eXosip_dialog_t * jd, int code) { osip_event_t *evt_answer; osip_message_t *response; int i; osip_transaction_t *tr; tr = eXosip_find_last_inc_invite (jc, jd); if (tr == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } /* is the transaction already answered? */ if (tr->state == IST_COMPLETED || tr->state == IST_CONFIRMED || tr->state == IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } if (jd == NULL) i = _eXosip_build_response_default (&response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default (&response, jd->d_dialog, code, tr->orig_request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ERROR: Could not create response for invite\n")); return -2; } osip_message_set_content_length (response, "0"); /* send message to transaction layer */ if (code > 100) { /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ i = complete_answer_that_establish_a_dialog (response, tr->orig_request); if (jd == NULL) { i = eXosip_dialog_init_as_uas (&jd, tr->orig_request, response); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n")); } else { ADD_ELEMENT (jc->c_dialogs, jd); } } } evt_answer = osip_new_outgoing_sipmessage (response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event (tr, evt_answer); __eXosip_wakeup (); return 0; }
int eXosip_insubscription_send_answer (int tid, int status, osip_message_t * answer) { int i = -1; eXosip_dialog_t *jd = NULL; eXosip_notify_t *jn = NULL; osip_transaction_t *tr = NULL; osip_event_t *evt_answer; if (tid > 0) { _eXosip_insubscription_transaction_find (tid, &jn, &jd, &tr); } if (jd == NULL || tr == NULL || tr->orig_request == NULL || tr->orig_request->sip_method == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No incoming subscription here?\n")); osip_message_free (answer); return -1; } if (answer == NULL) { if (0 == osip_strcasecmp (tr->orig_request->sip_method, "SUBSCRIBE")) { if (status >= 101 && status <= 199) { } else if (status >= 300 && status <= 699) { } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Wrong parameter?\n")); return -1; } } } /* is the transaction already answered? */ if (tr->state == NIST_COMPLETED || tr->state == NIST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); osip_message_free (answer); return -1; } if (answer == NULL) { if (0 == osip_strcasecmp (tr->orig_request->sip_method, "SUBSCRIBE")) { if (status < 200) i = _eXosip_insubscription_answer_1xx (jn, jd, status); else i = _eXosip_insubscription_answer_3456xx (jn, jd, status); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot send response!\n")); return -1; } } else { /* TODO */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: a response must be given!\n")); return -1; } return 0; } else { i = 0; } if (0 == osip_strcasecmp (tr->orig_request->sip_method, "SUBSCRIBE")) { if (MSG_IS_STATUS_1XX (answer)) { } else if (MSG_IS_STATUS_2XX (answer)) { eXosip_dialog_set_200ok (jd, answer); osip_dialog_set_state (jd->d_dialog, DIALOG_CONFIRMED); } else if (answer->status_code >= 300 && answer->status_code <= 699) { i = 0; } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: wrong status code (101<status<699)\n")); osip_message_free (answer); return -1; } if (i != 0) { osip_message_free (answer); return -1; } } evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event (tr, evt_answer); eXosip_update (); __eXosip_wakeup (); return 0; }
int eXosip_reinvite_with_authentication (struct eXosip_call_t *jc) { struct eXosip_call_t *jcc; #ifdef SM char *locip; #else char locip[50]; #endif osip_message_t * cloneinvite; osip_event_t *sipevent; osip_transaction_t *transaction; int osip_cseq_num,length; osip_via_t *via; char *tmp; int i; osip_message_clone (jc->c_out_tr->orig_request, &cloneinvite); osip_cseq_num = osip_atoi(jc->c_out_tr->orig_request->cseq->number); length = strlen(jc->c_out_tr->orig_request->cseq->number); tmp = (char *)osip_malloc(90*sizeof(char)); via = (osip_via_t *) osip_list_get (cloneinvite->vias, 0); osip_list_remove(cloneinvite->vias, 0); osip_via_free(via); #ifdef SM eXosip_get_localip_for(cloneinvite->req_uri->host,&locip); #else eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49); #endif if (eXosip.ip_family==AF_INET6) { sprintf(tmp, "SIP/2.0/UDP [%s]:%s;branch=z9hG4bK%u", locip, eXosip.localport, via_branch_new_random()); } else { sprintf(tmp, "SIP/2.0/UDP %s:%s;branch=z9hG4bK%u", locip, eXosip.localport, via_branch_new_random()); } #ifdef SM osip_free(locip); #endif osip_via_init(&via); osip_via_parse(via, tmp); osip_list_add(cloneinvite->vias, via, 0); osip_free(tmp); osip_cseq_num++; osip_free(cloneinvite->cseq->number); cloneinvite->cseq->number = (char*)osip_malloc(length + 2); sprintf(cloneinvite->cseq->number, "%i", osip_cseq_num); eXosip_add_authentication_information(cloneinvite, jc->c_out_tr->last_response); cloneinvite->message_property = 0; eXosip_call_init(&jcc); i = osip_transaction_init(&transaction, ICT, eXosip.j_osip, cloneinvite); if (i!=0) { eXosip_call_free(jc); osip_message_free(cloneinvite); return -1; } jcc->c_out_tr = transaction; sipevent = osip_new_outgoing_sipmessage(cloneinvite); sipevent->transactionid = transaction->transactionid; osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jcc, NULL, NULL, NULL)); osip_transaction_add_event(transaction, sipevent); jcc->external_reference = 0; ADD_ELEMENT(eXosip.j_calls, jcc); eXosip_update(); /* fixed? */ __eXosip_wakeup(); return 0; }
int eXosip_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, char *local_sdp_port, char *ctct, char *local_video_port, char *public_sdp_port, char *public_video_port) { osip_event_t *evt_answer; osip_message_t *response; int i; char *size; char *body = NULL; osip_transaction_t *tr; tr = eXosip_find_last_inc_invite(jc, jd); if (tr==NULL || tr->orig_request==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer\n")); return -1; } if (jd!=NULL && jd->d_dialog==NULL) { /* element previously removed */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot answer this closed transaction\n")); return -1; } /* is the transaction already answered? */ if (tr->state==IST_COMPLETED || tr->state==IST_CONFIRMED || tr->state==IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } /* WE SHOULD LOOK FOR A SDP PACKET!! */ if(NULL != osip_list_get(&tr->orig_request->bodies,0)) { body = generating_sdp_answer(tr->orig_request, jc->c_ctx); if (body==NULL) code = 488; /* bad sdp */ } else { if(local_sdp_port==NULL && local_video_port == NULL) code = 488; /* session description in the request is not acceptable. */ else /* body is NULL (contains no SDP), generate a response to INVITE w/ no SDP */ body = generating_no_sdp_answer(jc, jd, tr->orig_request, public_sdp_port ? public_sdp_port : local_sdp_port , public_video_port ? public_video_port : local_video_port); } if (jd==NULL) i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); code = 500; /* ? which code to use? */ osip_free(body); /* not used */ return -1; } if (code==488) { osip_message_set_content_length(response, "0"); /* TODO: send message to transaction layer */ osip_free(body); evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; } if ( ! body ) { fprintf(stderr, "%s,%d: body is NULL\n", __FILE__, __LINE__); return -1; } i = osip_message_set_body(response, body, strlen(body)); if (i!=0) { goto g2atii_error_1; } size = (char *) osip_malloc(6*sizeof(char)); #ifdef __APPLE_CC__ sprintf(size,"%li",strlen(body)); #else sprintf(size,"%i",strlen(body)); #endif i = osip_message_set_content_length(response, size); osip_free(size); if (i!=0) goto g2atii_error_1; i = osip_message_set_content_type(response, "application/sdp"); if (i!=0) goto g2atii_error_1; /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ { i = complete_answer_that_establish_a_dialog2(response, tr->orig_request, ctct); if (i!=0) goto g2atii_error_1;; /* ?? */ } osip_free(body); /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */ /* this response must be stored at the upper layer!!! (it will be destroyed*/ /* right after being sent! */ if (jd==NULL) { i = eXosip_dialog_init_as_uas(&jd, owsip_transaction_account_get (tr), tr->orig_request, response); if (i!=0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n")); return -1; } ADD_ELEMENT(jc->c_dialogs, jd); } eXosip_dialog_set_200ok(jd, response); evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); __eXosip_wakeup(); return 0; g2atii_error_1: osip_free(body); osip_message_free(response); return -1; }
int eXosip_answer_invite_2xx_with_body(eXosip_call_t *jc, eXosip_dialog_t *jd, int code,const char*bodytype, const char*body) { osip_event_t *evt_answer; osip_message_t *response; int i; char *size; osip_transaction_t *tr; tr = eXosip_find_last_inc_invite(jc, jd); if (tr==NULL || tr->orig_request==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer\n")); return -1; } if (jd!=NULL && jd->d_dialog==NULL) { /* element previously removed */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot answer this closed transaction\n")); return -1; } /* is the transaction already answered? */ if (tr->state==IST_COMPLETED || tr->state==IST_CONFIRMED || tr->state==IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } if (jd==NULL) i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); code = 500; /* ? which code to use? */ return -1; } if (code==488) { osip_message_set_content_length(response, "0"); /* TODO: send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; } if ( ! body ) { fprintf(stderr, "%s,%d: body is NULL\n", __FILE__, __LINE__); return -1; } i = osip_message_set_body(response, body, strlen(body)); if (i!=0) { goto g2atii_error_1; } size = (char *) osip_malloc(6*sizeof(char)); sprintf(size,"%i",strlen(body)); i = osip_message_set_content_length(response, size); osip_free(size); if (i!=0) goto g2atii_error_1; i = owsip_message_set_header(response, "content-type", bodytype); if (i!=0) goto g2atii_error_1; /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ i = complete_answer_that_establish_a_dialog(response, tr->orig_request); if (i!=0) goto g2atii_error_1; /* ?? */ /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */ /* this response must be stored at the upper layer!!! (it will be destroyed*/ /* right after being sent! */ if (jd==NULL) { i = eXosip_dialog_init_as_uas(&jd, owsip_transaction_account_get (tr), tr->orig_request, response); if (i!=0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n")); return -1; } ADD_ELEMENT(jc->c_dialogs, jd); } eXosip_dialog_set_200ok(jd, response); evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); __eXosip_wakeup(); return 0; g2atii_error_1: osip_message_free(response); return -1; }
int _eXosip_insubscription_send_request_with_credential (eXosip_notify_t * jn, eXosip_dialog_t * jd, osip_transaction_t * out_tr) { osip_transaction_t *tr = NULL; osip_message_t *msg = NULL; osip_event_t *sipevent; char locip[256]; int cseq; char tmp[256]; osip_via_t *via; int i; if (jn == NULL) return -1; if (jd != NULL) { if (jd->d_out_trs == NULL) return -1; } if (out_tr == NULL) { out_tr = eXosip_find_last_out_notify (jn, jd); } if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL) return -1; osip_message_clone (out_tr->orig_request, &msg); if (msg == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: could not clone msg for authentication\n")); return -1; } via = (osip_via_t *) osip_list_get (msg->vias, 0); if (via == NULL || msg->cseq == NULL || msg->cseq->number == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via or cseq header\n")); return -1; } /* increment cseq */ cseq = atoi (msg->cseq->number); osip_free (msg->cseq->number); msg->cseq->number = strdup_printf ("%i", cseq + 1); if (jd != NULL && jd->d_dialog != NULL) { jd->d_dialog->local_cseq++; } osip_list_remove (msg->vias, 0); osip_via_free (via); i = _eXosip_find_protocol (out_tr->orig_request); if (i == IPPROTO_UDP) { eXosip_guess_ip_for_via (eXosip.net_interfaces[0].net_ip_family, locip, sizeof (locip)); if (eXosip.net_interfaces[0].net_ip_family == AF_INET6) snprintf (tmp, 256, "SIP/2.0/UDP [%s]:%s;branch=z9hG4bK%u", locip, eXosip.net_interfaces[0].net_port, via_branch_new_random ()); else snprintf (tmp, 256, "SIP/2.0/UDP %s:%s;rport;branch=z9hG4bK%u", locip, eXosip.net_interfaces[0].net_port, via_branch_new_random ()); } else if (i == IPPROTO_TCP) { eXosip_guess_ip_for_via (eXosip.net_interfaces[1].net_ip_family, locip, sizeof (locip)); if (eXosip.net_interfaces[1].net_ip_family == AF_INET6) snprintf (tmp, 256, "SIP/2.0/TCP [%s]:%s;branch=z9hG4bK%u", locip, eXosip.net_interfaces[1].net_port, via_branch_new_random ()); else snprintf (tmp, 256, "SIP/2.0/TCP %s:%s;rport;branch=z9hG4bK%u", locip, eXosip.net_interfaces[1].net_port, via_branch_new_random ()); } else { /* tls? */ osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: unsupported protocol\n")); return -1; } osip_via_init (&via); osip_via_parse (via, tmp); osip_list_add (msg->vias, via, 0); eXosip_add_authentication_information (msg, out_tr->last_response); osip_message_force_update (msg); i = osip_transaction_init (&tr, NICT, eXosip.j_osip, msg); if (i != 0) { osip_message_free (msg); return -1; } /* add the new tr for the current dialog */ osip_list_add (jd->d_out_trs, tr, 0); sipevent = osip_new_outgoing_sipmessage (msg); osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (NULL, jd, NULL, jn)); osip_transaction_add_event (tr, sipevent); eXosip_update (); /* fixed? */ __eXosip_wakeup (); return 0; }
int eXosip_call_send_prack (int tid, osip_message_t * prack) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *tr = NULL; osip_event_t *sipevent; int i; if (tid < 0) return OSIP_BADPARAMETER; if (prack == NULL) return OSIP_BADPARAMETER; if (tid > 0) { _eXosip_call_transaction_find (tid, &jc, &jd, &tr); } if (jc == NULL || jd == NULL || jd->d_dialog == NULL || tr == NULL || tr->orig_request == NULL || tr->orig_request->sip_method == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here or no transaction for call\n")); osip_message_free (prack); return OSIP_NOTFOUND; } if (0 != osip_strcasecmp (tr->orig_request->sip_method, "INVITE")) { osip_message_free (prack); return OSIP_BADPARAMETER; } /* PRACK are only send in the PROCEEDING state */ if (tr->state != ICT_PROCEEDING) { osip_message_free (prack); return OSIP_WRONG_STATE; } tr = NULL; i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, prack); if (i != 0) { osip_message_free (prack); return i; } jd->d_mincseq++; osip_list_add (jd->d_out_trs, tr, 0); sipevent = osip_new_outgoing_sipmessage (prack); sipevent->transactionid = tr->transactionid; #ifndef MINISIZE osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd, NULL, NULL)); #else osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd)); #endif osip_transaction_add_event (tr, sipevent); __eXosip_wakeup (); return OSIP_SUCCESS; }
int eXosip_message_send_answer (int tid, int status, osip_message_t * answer) { osip_transaction_t *tr = NULL; osip_event_t *evt_answer; int i = -1; if (tid > 0) { eXosip_transaction_find (tid, &tr); } if (tr == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No MESSAGE transaction found\n")); osip_message_free (answer); return -1; } /* is the transaction already answered? */ if (tr->state == NIST_COMPLETED || tr->state == NIST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); osip_message_free (answer); return -1; } if (answer == NULL) { if (status > 100 && status < 200) { #if 0 /* TODO: not implemented */ i = _eXosip_build_response_default (response, NULL, code, tr->orig_request); #endif OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: status code 1xx for message not implemented (use 200<status<699)\n")); return -1; } else if (status > 199 && status < 300) { i = _eXosip_build_response_default (&answer, NULL, status, tr->orig_request); } else if (status > 300 && status <= 699) { i = _eXosip_build_response_default (&answer, NULL, status, tr->orig_request); } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: wrong status code (200<status<=699)\n")); return -1; } if (i != 0) return -1; } evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event (tr, evt_answer); __eXosip_wakeup (); return 0; }
int _eXosip_call_retry_request (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * out_tr) { osip_transaction_t *tr = NULL; osip_message_t *msg = NULL; osip_event_t *sipevent; int cseq; osip_via_t *via; osip_contact_t *co; int pos; int i; int protocol = IPPROTO_UDP; if (jc == NULL) return OSIP_BADPARAMETER; if (jd != NULL) { if (jd->d_out_trs == NULL) return OSIP_BADPARAMETER; } if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL) return OSIP_BADPARAMETER; i = osip_message_clone (out_tr->orig_request, &msg); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: could not clone msg for authentication\n")); return i; } via = (osip_via_t *) osip_list_get (&msg->vias, 0); if (via == NULL || msg->cseq == NULL || msg->cseq->number == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via or cseq header\n")); return OSIP_SYNTAXERROR; } if (MSG_IS_STATUS_3XX (out_tr->last_response)) { co = NULL; pos = 0; while (!osip_list_eol (&out_tr->last_response->contacts, pos)) { co = (osip_contact_t *) osip_list_get (&out_tr->last_response->contacts, pos); if (co != NULL && co->url != NULL) { /* check tranport? Only allow UDP, right now */ osip_uri_param_t *u_param; int pos2; u_param = NULL; pos2 = 0; while (!osip_list_eol (&co->url->url_params, pos2)) { u_param = (osip_uri_param_t *) osip_list_get (&co->url->url_params, pos2); if (u_param == NULL || u_param->gname == NULL || u_param->gvalue == NULL) { u_param = NULL; /* skip */ } else if (0 == osip_strcasecmp (u_param->gname, "transport")) { if (0 == osip_strcasecmp (u_param->gvalue, "udp")) { u_param = NULL; protocol = IPPROTO_UDP; break; /* ok */ } else if (0 == osip_strcasecmp (u_param->gvalue, "tcp")) { protocol = IPPROTO_TCP; u_param = NULL; } break; } pos2++; } if (u_param == NULL || u_param->gname == NULL || u_param->gvalue == NULL) { break; /* default is udp! */ } } pos++; co = NULL; } if (co == NULL || co->url == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: contact header\n")); return OSIP_SYNTAXERROR; } /* TODO: remove extra parameter from new request-uri check usual parameter like "transport" */ if (msg->req_uri != NULL && msg->req_uri->host != NULL && co->url->host != NULL && 0 == osip_strcasecmp (co->url->host, msg->req_uri->host)) { osip_uri_param_t *maddr_param = NULL; osip_uri_uparam_get_byname (co->url, "maddr", &maddr_param); if (maddr_param != NULL && maddr_param->gvalue != NULL) { /* This is a redirect server, the route should probably be removed? */ osip_route_t *route = NULL; osip_generic_param_t *tag = NULL; osip_message_get_route (msg, 0, &route); if (route != NULL) { osip_to_get_tag (msg->to, &tag); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_remove (&msg->routes, 0); osip_route_free (route); } } } } /* replace request-uri with NEW contact address */ osip_uri_free (msg->req_uri); msg->req_uri = NULL; osip_uri_clone (co->url, &msg->req_uri); /* support for diversions headers/draft! */ { int count = 0; pos = 0; while (!osip_list_eol (&out_tr->last_response->headers, pos)) { osip_header_t *copy = NULL; osip_header_t *head = osip_list_get (&out_tr->last_response->headers, pos); if (head != NULL && 0 == osip_strcasecmp (head->hname, "diversion")) { i = osip_header_clone (head, ©); if (i == 0) { osip_list_add (&msg->headers, copy, count); count++; } } pos++; } } } /* remove all previous authentication headers */ osip_list_special_free (&msg->authorizations, (void *(*)(void *)) &osip_authorization_free); osip_list_special_free (&msg->proxy_authorizations, (void *(*)(void *)) &osip_proxy_authorization_free); /* increment cseq */ cseq = atoi (msg->cseq->number); osip_free (msg->cseq->number); msg->cseq->number = strdup_printf ("%i", cseq + 1); if (jd != NULL && jd->d_dialog != NULL) { jd->d_dialog->local_cseq++; } i = eXosip_update_top_via (msg); if (i != 0) { osip_message_free (msg); return i; } if (out_tr->last_response->status_code == 401 || out_tr->last_response->status_code == 407) eXosip_add_authentication_information (msg, out_tr->last_response); else eXosip_add_authentication_information (msg, NULL); osip_message_force_update (msg); if (0 != osip_strcasecmp (msg->sip_method, "INVITE")) { i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, msg); } else { i = _eXosip_transaction_init (&tr, ICT, eXosip.j_osip, msg); } if (i != 0) { osip_message_free (msg); return i; } if (out_tr == jc->c_out_tr) { /* replace with the new tr */ osip_list_add (&eXosip.j_transactions, jc->c_out_tr, 0); jc->c_out_tr = tr; /* fix dialog issue */ if (jd != NULL) { REMOVE_ELEMENT (jc->c_dialogs, jd); eXosip_dialog_free (jd); jd = NULL; } } else { /* add the new tr for the current dialog */ osip_list_add (jd->d_out_trs, tr, 0); } sipevent = osip_new_outgoing_sipmessage (msg); #ifndef MINISIZE osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd, NULL, NULL)); #else osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd)); #endif osip_transaction_add_event (tr, sipevent); eXosip_update (); /* fixed? */ __eXosip_wakeup (); return OSIP_SUCCESS; }
static int _eXosip_retry_with_auth (eXosip_dialog_t * jd, osip_transaction_t ** ptr, int *retry) { osip_transaction_t *out_tr = NULL; osip_transaction_t *tr = NULL; osip_message_t *msg = NULL; osip_event_t *sipevent; jinfo_t *ji = NULL; int cseq; osip_via_t *via; int i; if (!ptr) return -1; if (jd != NULL) { if (jd->d_out_trs == NULL) return -1; } out_tr = *ptr; if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL) return -1; if (retry && (*retry >= 3)) return -1; osip_message_clone (out_tr->orig_request, &msg); if (msg == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: could not clone msg for authentication\n")); return -1; } via = (osip_via_t *) osip_list_get (&msg->vias, 0); if (via == NULL || msg->cseq == NULL || msg->cseq->number == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via or cseq header\n")); return -1; } /* increment cseq */ cseq = atoi (msg->cseq->number); osip_free (msg->cseq->number); msg->cseq->number = strdup_printf ("%i", cseq + 1); if (jd != NULL && jd->d_dialog != NULL) { jd->d_dialog->local_cseq++; } i = eXosip_update_top_via(msg); if (i!=0) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: unsupported protocol\n")); return -1; } if (eXosip_add_authentication_information (msg, out_tr->last_response) < 0) { osip_message_free (msg); return -1; } osip_message_force_update (msg); if (MSG_IS_INVITE (msg)) i = _eXosip_transaction_init (&tr, ICT, eXosip.j_osip, msg); else i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, msg); if (i != 0) { osip_message_free (msg); return -1; } /* replace with the new tr */ if (MSG_IS_PUBLISH(msg)) { /* old transaction is put in the garbage list */ osip_list_add (eXosip.j_transactions, out_tr, 0); /* new transaction is put in the publish context */ *ptr = tr; } else osip_list_add (eXosip.j_transactions, tr, 0); sipevent = osip_new_outgoing_sipmessage (msg); ji = osip_transaction_get_your_instance (out_tr); osip_transaction_set_your_instance (out_tr, NULL); osip_transaction_set_your_instance (tr, ji); osip_transaction_add_event (tr, sipevent); if (retry) (*retry)++; eXosip_update (); /* fixed? */ __eXosip_wakeup (); return 0; }
int eXosip_answer_options_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) { osip_event_t *evt_answer; osip_transaction_t *tr; osip_message_t *response; sdp_message_t *sdp; char *body; char size[10]; int i; tr = eXosip_find_last_inc_options(jc, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &sdp, "10400", NULL); if (sdp==NULL) { return -1; } if (jd!=NULL) { i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); } else { i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); } if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n")); sdp_message_free(sdp); /* not used */ return -1; } i = sdp_message_to_str(sdp, &body); sdp_message_free(sdp); if ( ( i!=0 ) || ( ! body ) ) { osip_message_free(response); return -1; } i = osip_message_set_body(response, body, strlen(body)); if (i!=0) { osip_message_free(response); return -1; } #ifdef __APPLE_CC__ snprintf(size, 9,"%li",strlen(body)); #else snprintf(size, 9,"%i",strlen(body)); #endif i = osip_message_set_content_length(response, size); if (i!=0) { osip_free(body); osip_message_free(response); return -1; } osip_free(body); i = osip_message_set_content_type(response, "application/sdp"); if (i!=0) { osip_message_free(response); return -1; } evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; }