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; }
/* this request is only build within a dialog!! */ int generating_bye (osip_message_t ** bye, osip_dialog_t * dialog, char *transport) { int i; i = _eXosip_build_request_within_dialog (bye, "BYE", dialog, transport); if (i != 0) return i; 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; 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_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_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; }
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; }