sdp_message_t * eXosip_get_previous_local_sdp (int jid) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *invite_tr = NULL; if (jid > 0) { eXosip_call_dialog_find (jid, &jc, &jd); } if (jc == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return NULL; } invite_tr = eXosip_find_last_invite (jc, jd); if (invite_tr == NULL) return NULL; invite_tr = eXosip_find_previous_invite (jc, jd, invite_tr); if (invite_tr == NULL) return NULL; return _eXosip_get_local_sdp (invite_tr); }
int eXosip_call_get_referto (int did, char *refer_to, size_t refer_to_len) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *tr = NULL; osip_uri_t *referto_uri; char atmp[256]; char *referto_tmp = NULL; int i; if (did <= 0) return OSIP_BADPARAMETER; eXosip_call_dialog_find (did, &jc, &jd); if (jc == NULL || jd == NULL || jd->d_dialog == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return OSIP_NOTFOUND; } tr = eXosip_find_last_invite (jc, jd); if (tr == NULL || tr->orig_request == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No transaction for call?\n")); return OSIP_NOTFOUND; } i = osip_uri_clone (jd->d_dialog->remote_uri->url, &referto_uri); if (i != 0) return i; snprintf (atmp, sizeof (atmp), "%s;to-tag=%s;from-tag=%s", jd->d_dialog->call_id, jd->d_dialog->remote_tag, jd->d_dialog->local_tag); osip_uri_uheader_add (referto_uri, osip_strdup ("Replaces"), osip_strdup (atmp)); i = osip_uri_to_str (referto_uri, &referto_tmp); if (i != 0) { osip_uri_free (referto_uri); return i; } snprintf (refer_to, refer_to_len, "%s", referto_tmp); osip_uri_free (referto_uri); return OSIP_SUCCESS; }
int eXosip_call_set_reference (int id, void *reference) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; if (id > 0) { eXosip_call_dialog_find (id, &jc, &jd); if (jc == NULL) { eXosip_call_find (id, &jc); } } if (jc == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return OSIP_NOTFOUND; } jc->external_reference = reference; return OSIP_SUCCESS; }
int eXosip_call_terminate (int cid, int did) { int i; osip_transaction_t *tr; osip_message_t *request = NULL; eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; if (did <= 0 && cid <= 0) return OSIP_BADPARAMETER; if (did > 0) { eXosip_call_dialog_find (did, &jc, &jd); if (jd == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return OSIP_NOTFOUND; } } else { eXosip_call_find (cid, &jc); } if (jc == NULL) { return OSIP_NOTFOUND; } tr = eXosip_find_last_out_invite (jc, jd); if (jd != NULL && jd->d_dialog != NULL && jd->d_dialog->state == DIALOG_CONFIRMED) { /* don't send CANCEL on re-INVITE: send BYE instead */ } else if (tr != NULL && tr->last_response != NULL && MSG_IS_STATUS_1XX (tr->last_response)) { i = generating_cancel (&request, tr->orig_request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot terminate this call!\n")); return i; } i = eXosip_create_cancel_transaction (jc, jd, request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot initiate SIP transaction!\n")); return i; } if (jd != NULL) { osip_dialog_free (jd->d_dialog); jd->d_dialog = NULL; eXosip_update (); /* AMD 30/09/05 */ } return OSIP_SUCCESS; } if (jd == NULL || jd->d_dialog == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No established dialog!\n")); return OSIP_WRONG_STATE; } if (tr == NULL) { /*this may not be enough if it's a re-INVITE! */ tr = eXosip_find_last_inc_invite (jc, jd); if (tr != NULL && tr->last_response != NULL && MSG_IS_STATUS_1XX (tr->last_response)) { /* answer with 603 */ osip_generic_param_t *to_tag; osip_from_param_get_byname (tr->orig_request->to, "tag", &to_tag); i = eXosip_call_send_answer (tr->transactionid, 603, NULL); if (to_tag == NULL) return i; } } if (jd->d_dialog == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot terminate this call!\n")); return OSIP_WRONG_STATE; } i = generating_bye (&request, jd->d_dialog, eXosip.transport); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot terminate this call!\n")); return i; } eXosip_add_authentication_information (request, NULL); i = eXosip_create_transaction (jc, jd, request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot initiate SIP transaction!\n")); return i; } osip_dialog_free (jd->d_dialog); jd->d_dialog = NULL; eXosip_update (); /* AMD 30/09/05 */ 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_call_build_request (int jid, const char *method, osip_message_t ** request) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *transaction; int i; *request = NULL; if (jid <= 0) return OSIP_BADPARAMETER; if (method == NULL || method[0] == '\0') return OSIP_BADPARAMETER; if (jid > 0) { eXosip_call_dialog_find (jid, &jc, &jd); } if (jd == NULL || jd->d_dialog == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return OSIP_NOTFOUND; } transaction = NULL; if (0 == osip_strcasecmp (method, "INVITE")) { transaction = eXosip_find_last_invite (jc, jd); } else /* OPTIONS, UPDATE, INFO, REFER, ?... */ { transaction = eXosip_find_last_transaction (jc, jd, method); } if (transaction != NULL) { if (0 != osip_strcasecmp (method, "INVITE")) { if (transaction->state != NICT_TERMINATED && transaction->state != NIST_TERMINATED && transaction->state != NICT_COMPLETED && transaction->state != NIST_COMPLETED) return OSIP_WRONG_STATE; } else { if (transaction->state != ICT_TERMINATED && transaction->state != IST_TERMINATED && transaction->state != IST_CONFIRMED && transaction->state != ICT_COMPLETED) return OSIP_WRONG_STATE; } } i = _eXosip_build_request_within_dialog (request, method, jd->d_dialog, eXosip.transport); if (i != 0) return i; eXosip_add_authentication_information (*request, NULL); return OSIP_SUCCESS; }
int eXosip_call_send_ack (int did, osip_message_t * ack) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; int i; osip_route_t *route; char *host; int port; if (did <= 0) return OSIP_BADPARAMETER; if (did > 0) { eXosip_call_dialog_find (did, &jc, &jd); } if (jc == NULL || jd == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); if (ack != NULL) osip_message_free (ack); return OSIP_NOTFOUND; } if (ack == NULL) { i = eXosip_call_build_ack (did, &ack); if (i != 0) { return i; } } osip_message_get_route (ack, 0, &route); if (route != NULL) { osip_uri_param_t *lr_param = NULL; osip_uri_uparam_get_byname (route->url, "lr", &lr_param); if (lr_param == NULL) route = NULL; } if (route != NULL) { port = 5060; if (route->url->port != NULL) port = osip_atoi (route->url->port); host = route->url->host; } else { /* search for maddr parameter */ osip_uri_param_t *maddr_param = NULL; osip_uri_uparam_get_byname (ack->req_uri, "maddr", &maddr_param); host = NULL; if (maddr_param != NULL && maddr_param->gvalue != NULL) host = maddr_param->gvalue; port = 5060; if (ack->req_uri->port != NULL) port = osip_atoi (ack->req_uri->port); if (host == NULL) host = ack->req_uri->host; } i = cb_snd_message (NULL, ack, host, port, -1); if (jd->d_ack != NULL) osip_message_free (jd->d_ack); jd->d_ack = ack; if (i < 0) return i; /* TODO: could be 1 for icmp... */ return OSIP_SUCCESS; }
int eXosip_call_build_ack (int did, osip_message_t ** _ack) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *tr = NULL; osip_message_t *ack; char *transport; int i; *_ack = NULL; if (did <= 0) return OSIP_BADPARAMETER; if (did > 0) { eXosip_call_dialog_find (did, &jc, &jd); } if (jc == NULL || jd == NULL || jd->d_dialog == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return OSIP_NOTFOUND; } tr = eXosip_find_last_invite (jc, jd); if (tr == NULL || tr->orig_request == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No transaction for call?\n")); return OSIP_NOTFOUND; } if (0 != osip_strcasecmp (tr->orig_request->sip_method, "INVITE")) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: ACK are only sent for invite transactions\n")); return OSIP_BADPARAMETER; } transport = NULL; transport = _eXosip_transport_protocol (tr->orig_request); if (transport == NULL) i = _eXosip_build_request_within_dialog (&ack, "ACK", jd->d_dialog, "UDP"); else i = _eXosip_build_request_within_dialog (&ack, "ACK", jd->d_dialog, transport); if (i != 0) { return i; } _eXosip_call_reuse_contact (tr->orig_request, ack); /* Fix CSeq Number when request has been exchanged during INVITE transactions */ if (tr->orig_request->cseq != NULL && tr->orig_request->cseq->number != NULL) { if (ack != NULL && ack->cseq != NULL && ack->cseq->number != NULL) { osip_free (ack->cseq->number); ack->cseq->number = osip_strdup (tr->orig_request->cseq->number); } } /* copy all credentials from INVITE! */ { int pos = 0; osip_proxy_authorization_t *pa = NULL; i = osip_message_get_proxy_authorization (tr->orig_request, pos, &pa); while (i >= 0 && pa != NULL) { osip_proxy_authorization_t *pa2; i = osip_proxy_authorization_clone (pa, &pa2); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Error in credential from INVITE\n")); break; } osip_list_add (&ack->proxy_authorizations, pa2, -1); pa = NULL; pos++; i = osip_message_get_proxy_authorization (tr->orig_request, pos, &pa); } } *_ack = ack; return OSIP_SUCCESS; }