int eXosip_insubscription_build_request (int did, const char *method, osip_message_t ** request) { eXosip_dialog_t *jd = NULL; eXosip_notify_t *jn = NULL; osip_transaction_t *transaction; char *transport; int i; *request = NULL; if (method == NULL || method[0] == '\0') 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")); 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) return -1; } transport = NULL; if (transaction == NULL) transaction = jn->n_inc_tr; if (transaction != NULL && transaction->orig_request != NULL) transport = _eXosip_transport_protocol (transaction->orig_request); transaction = NULL; if (transport == NULL) i = _eXosip_build_request_within_dialog (request, method, jd->d_dialog, "UDP"); else i = _eXosip_build_request_within_dialog (request, method, jd->d_dialog, transport); if (i != 0) return -2; return 0; }
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; }
int eXosip_call_build_prack (int tid, osip_message_t ** prack) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *tr = NULL; osip_header_t *rseq; char *transport; int i; *prack = NULL; if (tid < 0) 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")); return OSIP_NOTFOUND; } if (0 != osip_strcasecmp (tr->orig_request->sip_method, "INVITE")) return OSIP_BADPARAMETER; /* PRACK are only send in the PROCEEDING state */ if (tr->state != ICT_PROCEEDING) return OSIP_WRONG_STATE; if (tr->orig_request->cseq == NULL || tr->orig_request->cseq->number == NULL || tr->orig_request->cseq->method == NULL) return OSIP_SYNTAXERROR; transport = NULL; if (tr != NULL && tr->orig_request != NULL) transport = _eXosip_transport_protocol (tr->orig_request); if (transport == NULL) i = _eXosip_build_request_within_dialog (prack, "PRACK", jd->d_dialog, "UDP"); else i = _eXosip_build_request_within_dialog (prack, "PRACK", jd->d_dialog, transport); if (i != 0) return i; osip_message_header_get_byname (tr->last_response, "RSeq", 0, &rseq); if (rseq != NULL && rseq->hvalue != NULL) { char tmp[128]; memset (tmp, '\0', sizeof (tmp)); snprintf (tmp, 127, "%s %s %s", rseq->hvalue, tr->orig_request->cseq->number, tr->orig_request->cseq->method); osip_message_set_header (*prack, "RAck", tmp); } return OSIP_SUCCESS; }
int eXosip_subscribe_build_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; char *transport; int i; *sub = NULL; 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")); 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) return OSIP_WRONG_STATE; } transport = NULL; if (transaction != NULL && transaction->orig_request != NULL) transport = _eXosip_transport_protocol (transaction->orig_request); if (transport == NULL) i = _eXosip_build_request_within_dialog (excontext, sub, "SUBSCRIBE", jd->d_dialog, "UDP"); else i = _eXosip_build_request_within_dialog (excontext, sub, "SUBSCRIBE", jd->d_dialog, transport); if (i != 0) return i; if (transaction != NULL && transaction->orig_request != NULL) { int pos = 0; osip_header_t *_header = NULL; osip_call_info_t *_call_info_header = NULL; pos = osip_message_get_supported (transaction->orig_request, pos, &_header); while (pos >= 0 && _header != NULL) { osip_header_t *_header2; i = osip_header_clone (_header, &_header2); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Error in Supported header\n")); break; } osip_list_add (&(*sub)->headers, _header2, -1); _header = NULL; pos++; pos = osip_message_get_supported (transaction->orig_request, pos, &_header); } pos = 0; pos = osip_message_get_call_info (transaction->orig_request, pos, &_call_info_header); while (pos >= 0 && _call_info_header != NULL) { osip_call_info_t *_header2; i = osip_call_info_clone (_call_info_header, &_header2); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Error in Call-Info header\n")); break; } osip_list_add (&(*sub)->call_infos, _header2, -1); _call_info_header = NULL; pos++; pos = osip_message_get_call_info (transaction->orig_request, pos, &_call_info_header); } } _eXosip_add_authentication_information (excontext, *sub, NULL); return OSIP_SUCCESS; }