int _eXosip_insubscription_answer_3456xx (struct eXosip_t *excontext, 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 OSIP_NOTFOUND; } if (jd == NULL) i = _eXosip_build_response_default (excontext, &response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default (excontext, &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 i; } if ((300 <= code) && (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 (excontext); return OSIP_SUCCESS; }
int eXosip_subscribe_send_refresh_request (struct eXosip_t *excontext, int did, osip_message_t * sub) { eXosip_dialog_t *jd = NULL; eXosip_subscribe_t *js = NULL; osip_transaction_t *transaction; osip_event_t *sipevent; int i; if (did <= 0) return OSIP_BADPARAMETER; if (did > 0) { _eXosip_subscribe_dialog_find (excontext, did, &js, &jd); } if (jd == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No subscribe here?\n")); osip_message_free (sub); return OSIP_NOTFOUND; } transaction = NULL; transaction = _eXosip_find_last_out_subscribe (js, jd); if (transaction != NULL) { if (transaction->state != NICT_TERMINATED && transaction->state != NIST_TERMINATED && transaction->state != NICT_COMPLETED && transaction->state != NIST_COMPLETED) { osip_message_free (sub); return OSIP_WRONG_STATE; } transaction = NULL; } transaction = NULL; i = _eXosip_transaction_init (excontext, &transaction, NICT, excontext->j_osip, sub); if (i != 0) { osip_message_free (sub); return i; } js->s_reg_period = 3600; _eXosip_subscribe_set_refresh_interval (js, sub); osip_list_add (jd->d_out_trs, transaction, 0); sipevent = osip_new_outgoing_sipmessage (sub); sipevent->transactionid = transaction->transactionid; osip_transaction_set_reserved5 (transaction, js); osip_transaction_set_reserved3 (transaction, jd); osip_transaction_add_event (transaction, sipevent); _eXosip_wakeup (excontext); return OSIP_SUCCESS; }
int eXosip_options_send_answer(struct eXosip_t *excontext, 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(excontext, tid, &tr); } if (tr == NULL) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No OPTIONS 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(excontext, &answer, NULL, status, tr->orig_request); else if (status > 300 && status <= 699) i = _eXosip_build_response_default(excontext, &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(excontext); return OSIP_SUCCESS; }
int _eXosip_insubscription_answer_1xx (struct eXosip_t *excontext, 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 OSIP_NOTFOUND; } if (jd == NULL) i = _eXosip_build_response_default (excontext, &response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default (excontext, &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 i; } if (code > 100) { /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ i = _eXosip_complete_answer_that_establish_a_dialog (excontext, response, tr->orig_request); if (i != 0) { } 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 (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 (excontext); return i; }
int eXosip_options_send_request(struct eXosip_t *excontext, osip_message_t * options) { osip_transaction_t *transaction; osip_event_t *sipevent; int i; i = _eXosip_transaction_init(excontext, &transaction, NICT, excontext->j_osip, options); if (i != 0) { osip_message_free(options); return i; } osip_list_add(&excontext->j_transactions, transaction, 0); sipevent = osip_new_outgoing_sipmessage(options); sipevent->transactionid = transaction->transactionid; osip_transaction_add_event(transaction, sipevent); _eXosip_wakeup(excontext); return OSIP_SUCCESS; }
int eXosip_subscribe_send_initial_request (struct eXosip_t *excontext, osip_message_t * subscribe) { eXosip_subscribe_t *js = NULL; osip_transaction_t *transaction; osip_event_t *sipevent; int i; i = _eXosip_subscribe_init (&js); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot subscribe.")); osip_message_free (subscribe); return i; } i = _eXosip_transaction_init (excontext, &transaction, NICT, excontext->j_osip, subscribe); if (i != 0) { _eXosip_subscribe_free (excontext, js); osip_message_free (subscribe); return i; } js->s_reg_period = 3600; _eXosip_subscribe_set_refresh_interval (js, subscribe); js->s_out_tr = transaction; sipevent = osip_new_outgoing_sipmessage (subscribe); sipevent->transactionid = transaction->transactionid; osip_transaction_set_reserved5 (transaction, js); osip_transaction_add_event (transaction, sipevent); ADD_ELEMENT (excontext->j_subscribes, js); _eXosip_update (excontext); /* fixed? */ _eXosip_wakeup (excontext); return js->s_id; }
int eXosip_publish (struct eXosip_t *excontext, osip_message_t * message, const char *to) { osip_transaction_t *transaction; osip_event_t *sipevent; int i; eXosip_pub_t *pub = NULL; if (message == NULL) return OSIP_BADPARAMETER; if (message->cseq == NULL || message->cseq->number == NULL) { osip_message_free (message); return OSIP_SYNTAXERROR; } if (to == NULL) { osip_message_free (message); return OSIP_BADPARAMETER; } i = _eXosip_pub_find_by_aor (excontext, &pub, to); if (i != 0 || pub == NULL) { osip_header_t *expires; osip_message_get_expires (message, 0, &expires); if (expires == NULL || expires->hvalue == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing expires header in PUBLISH!")); osip_message_free (message); return OSIP_SYNTAXERROR; } else { /* start a new publication context */ i = _eXosip_pub_init (&pub, to, expires->hvalue); if (i != 0) { osip_message_free (message); return i; } ADD_ELEMENT (excontext->j_pub, pub); } } else { if (pub->p_sip_etag[0] != '\0') { /* increase cseq */ osip_message_set_header (message, "SIP-If-Match", pub->p_sip_etag); } { osip_header_t *expires; osip_message_get_expires (message, 0, &expires); if (expires == NULL || expires->hvalue == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing expires header in PUBLISH!")); osip_message_free (message); return OSIP_SYNTAXERROR; } pub->p_period = atoi (expires->hvalue); } if (pub->p_last_tr != NULL && pub->p_last_tr->cseq != NULL && pub->p_last_tr->cseq->number != NULL) { int osip_cseq_num = osip_atoi (pub->p_last_tr->cseq->number); int length = (int) strlen (pub->p_last_tr->cseq->number); osip_cseq_num++; osip_free (message->cseq->number); message->cseq->number = (char *) osip_malloc (length + 2); /* +2 like for 9 to 10 */ if (message->cseq->number == NULL) { osip_message_free (message); return OSIP_NOMEM; } snprintf (message->cseq->number, length + 2, "%i", osip_cseq_num); } } i = _eXosip_transaction_init (excontext, &transaction, NICT, excontext->j_osip, message); if (i != 0) { osip_message_free (message); return i; } if (pub->p_last_tr != NULL) osip_list_add (&excontext->j_transactions, pub->p_last_tr, 0); pub->p_last_tr = transaction; sipevent = osip_new_outgoing_sipmessage (message); sipevent->transactionid = transaction->transactionid; osip_transaction_add_event (transaction, sipevent); _eXosip_wakeup (excontext); return transaction->transactionid; }
int _eXosip_subscribe_send_request_with_credential (struct eXosip_t *excontext, eXosip_subscribe_t * js, 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; int i; if (js == NULL) return OSIP_BADPARAMETER; if (jd != NULL) { if (jd->d_out_trs == NULL) return OSIP_BADPARAMETER; } if (out_tr == NULL) { out_tr = _eXosip_find_last_out_subscribe (js, jd); } if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL) return OSIP_NOTFOUND; 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; } { osip_generic_param_t *tag = NULL; osip_to_get_tag (msg->to, &tag); if (NULL == tag && jd != NULL && jd->d_dialog != NULL && jd->d_dialog->remote_tag != NULL) { osip_to_set_tag (msg->to, osip_strdup (jd->d_dialog->remote_tag)); } } 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; } /* increment cseq */ cseq = atoi (msg->cseq->number); osip_free (msg->cseq->number); msg->cseq->number = _eXosip_strdup_printf ("%i", cseq + 1); if (msg->cseq->number == NULL) { osip_message_free (msg); return OSIP_NOMEM; } 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; } osip_list_special_free (&msg->authorizations, (void (*)(void *)) &osip_authorization_free); osip_list_special_free (&msg->proxy_authorizations, (void (*)(void *)) &osip_proxy_authorization_free); if (out_tr->last_response->status_code == 401 || out_tr->last_response->status_code == 407) { _eXosip_add_authentication_information (excontext, msg, out_tr->last_response); } else _eXosip_add_authentication_information (excontext, msg, NULL); if (out_tr != NULL && out_tr->last_response != NULL && out_tr->last_response->status_code == 423) { /* increase expires value to "min-expires" value */ osip_header_t *exp; osip_header_t *min_exp; osip_message_header_get_byname (msg, "expires", 0, &exp); osip_message_header_get_byname (out_tr->last_response, "min-expires", 0, &min_exp); if (exp != NULL && exp->hvalue != NULL && min_exp != NULL && min_exp->hvalue != NULL) { osip_free (exp->hvalue); exp->hvalue = osip_strdup (min_exp->hvalue); } else { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing Min-Expires or Expires in PUBLISH\n")); return OSIP_SYNTAXERROR; } } osip_message_force_update (msg); i = _eXosip_transaction_init (excontext, &tr, NICT, excontext->j_osip, msg); if (i != 0) { osip_message_free (msg); return i; } if (out_tr == js->s_out_tr) { /* replace with the new tr */ osip_list_add (&excontext->j_transactions, js->s_out_tr, 0); js->s_out_tr = tr; } else { /* 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_reserved5 (tr, js); osip_transaction_set_reserved3 (tr, jd); osip_transaction_add_event (tr, sipevent); _eXosip_update (excontext); /* fixed? */ _eXosip_wakeup (excontext); return OSIP_SUCCESS; }
int _eXosip_answer_invite_123456xx (struct eXosip_t *excontext, eXosip_call_t * jc, eXosip_dialog_t * jd, int code, osip_message_t ** answer, int send) { int i; osip_transaction_t *tr; *answer = NULL; 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 OSIP_NOTFOUND; } if (code >= 200 && code < 300 && 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 OSIP_WRONG_STATE; } /* 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 OSIP_WRONG_STATE; } if (jd == NULL) i = _eXosip_build_response_default (excontext, answer, NULL, code, tr->orig_request); else i = _eXosip_build_response_default (excontext, answer, 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")); *answer = NULL; return i; } /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ if (code > 100 && code < 300) { i = _eXosip_complete_answer_that_establish_a_dialog (excontext, *answer, tr->orig_request); if (i != 0) { osip_message_free (*answer); *answer = NULL; return i; } } if (send == 1) { osip_event_t *evt_answer; if (code >= 200 && code < 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_wakeup (excontext); *answer = NULL; } return OSIP_SUCCESS; }