/**Reply to an incoming transaction request (stdarg version). * * @deprecated * Use nta_incoming_treply() instead. */ int nta_incoming_vreply(nta_incoming_t *irq, int status, char const *phrase, void const *extra, va_list headers) { if (irq->irq_status < 200 || status < 200 || (irq->irq_method == sip_method_invite && status < 300)) { msg_t *msg = nta_msg_create(irq->irq_agent, 0); sip_t *sip = sip_object(msg); if (!msg) return -1; else if (nta_msg_response_complete(msg, irq, status, phrase) < 0) msg_destroy(msg); else if (sip_add_headers(msg, sip, extra, headers) < 0 ) msg_destroy(msg); else if (sip_message_complete(msg) < 0) msg_destroy(msg); else if (nta_incoming_mreply(irq, msg) < 0) msg_destroy(msg); else return 0; } return -1; }
/**Create a request belonging to the leg * (stdarg version of nta_outgoing_create()). * * @deprecated * Use nta_outgoing_tcreate() or nta_outgoing_mcreate() instead. */ nta_outgoing_t *nta_outgoing_vcreate(nta_leg_t *leg, nta_response_f *callback, nta_outgoing_magic_t *magic, url_string_t const *route_url, sip_method_t method, char const *name, url_string_t const *request_uri, void const *extra, va_list headers) { nta_agent_t *agent = leg->leg_agent; msg_t *msg = nta_msg_create(agent, 0); sip_t *sip = sip_object(msg); nta_outgoing_t *orq; if (extra && sip_add_headers(msg, sip, extra, headers) < 0) orq = NULL; else if (route_url && leg->leg_route && !sip->sip_route && sip_add_dup(msg, sip, (sip_header_t *)leg->leg_route) < 0) orq = NULL; else if (nta_msg_request_complete(msg, leg, method, name, request_uri) < 0) orq = NULL; else orq = nta_outgoing_mcreate(agent, callback, magic, route_url, msg); if (!orq) msg_destroy(msg); return orq; }
/**Forward a request. * * @deprecated * Use nta_outgoing_mcreate() instead. */ nta_outgoing_t *nta_outgoing_tclone(nta_agent_t *agent, nta_response_f *callback, nta_outgoing_magic_t *magic, url_string_t const *route_url, msg_t *parent, tag_type_t tag, tag_value_t value, ...) { ta_list ta; msg_t *msg; nta_outgoing_t *orq = NULL; if (parent == NULL) return NULL; if ((msg = nta_msg_create(agent, 0)) == NULL) return NULL; ta_start(ta, tag, value); msg_clone(msg, parent); if (parent && sip_copy_all(msg, sip_object(msg), sip_object(parent)) < 0) ; else if (sip_add_tl(msg, sip_object(msg), ta_tags(ta)) < 0) ; else orq = nta_outgoing_mcreate(agent, callback, magic, route_url, msg); ta_end(ta); if (!orq) msg_destroy(msg); return orq; }
msg_t *nua_client_request_template(nua_client_request_t *cr) { nua_handle_t *nh = cr->cr_owner; nua_t *nua = nh->nh_nua; nua_dialog_state_t *ds = nh->nh_ds; msg_t *msg = nta_msg_create(nua->nua_nta, 0); sip_t *sip = sip_object(msg); if (!sip) return NULL; if (nh->nh_tags) { tagi_t const *t = nh->nh_tags; /* Use the From header from the dialog. If From is set, it is always first tag in the handle */ if (ds->ds_leg && t->t_tag == siptag_from) t++; /* When the INVITE message (or any other SIP message) is * created, the tagged values saved with nua_handle() are used first. */ sip_add_tagis(msg, sip, &t); } return msg; }
/** Fork an outgoing request (stdarg version of nta_outgoing_fork()). * * @deprecated * Use nta_outgoing_mcreate() instead. */ nta_outgoing_t *nta_outgoing_vfork(nta_outgoing_t *old_orq, nta_response_f *callback, nta_outgoing_magic_t *magic, url_string_t const *route_url, url_string_t const *request_uri, void const *extra, va_list headers) { nta_outgoing_t * orq; msg_t *msg, *imsg; sip_t *sip, *isip; nta_agent_t *agent; su_home_t *home; if (!old_orq || !old_orq->orq_request || !request_uri) return NULL; agent = old_orq->orq_agent; imsg = old_orq->orq_request; if (!(msg = nta_msg_create(agent, 0))) return NULL; msg_clone(msg, imsg); sip = sip_object(msg); isip = sip_object(imsg); home = msg_home(msg); /* Copy the SIP headers from the imsg message */ if (sip_copy_all(msg, sip, isip) < 0) orq = NULL; else if (sip_via_remove(msg, sip) == NULL) orq = NULL; else if (sip_add_dup(msg, sip_object(msg), (sip_header_t const *) sip_request_create(home, sip->sip_request->rq_method, sip->sip_request->rq_method_name, request_uri, NULL)) < 0) orq = NULL; else if (sip_add_headers(msg, sip, extra, headers) < 0) orq = NULL; else orq = nta_outgoing_mcreate(agent, callback, magic, route_url, msg); if (!orq) msg_destroy(msg); return orq; }
/** Reply to the request message (stdarg version of nta_msg_reply()). */ int nta_msg_vreply(nta_agent_t *agent, msg_t *req_msg, int status, char const *phrase, void *extra, va_list headers) { msg_t *reply = nta_msg_create(agent, 0); sip_t *sip = sip_object(reply); if (sip_add_headers(reply, sip, extra, headers) < 0) sip = NULL; return nta_msg_mreply(agent, reply, sip, status, phrase, req_msg, TAG_END()); }
/**Get request message. * * The function nta_outgoing_getrequest() retrieves the request message sent * to the network. The request message is copied; the original copy is kept * by the transaction. * * @param orq outgoing transaction handle * * @retval * A pointer to the copy of the request message is returned, or NULL if an * error occurred. */ msg_t *nta_outgoing_getrequest(nta_outgoing_t *orq) { if (orq && orq->orq_request) { msg_t *msg = nta_msg_create(orq->orq_agent, 0); sip_t *sip = sip_object(msg); msg_clone(msg, orq->orq_request); /* Copy the SIP headers from the old message */ if (sip_copy_all(msg, sip, sip_object(orq->orq_request)) >= 0) return msg; msg_destroy(msg); } return NULL; }
/**Get response message. * * The function nta_incoming_getresponse() retrieves a copy of the latest * outgoing response message. The response message is copied; the original * copy is kept by the transaction. * * @param irq incoming (server) transaction handle * * @retval * A pointer to the copy of the response message is returned, or NULL if an * error occurred. */ msg_t *nta_incoming_getresponse(nta_incoming_t *irq) { if (irq && irq->irq_response) { msg_t *msg = nta_msg_create(irq->irq_agent, 0); sip_t *sip = sip_object(msg); msg_clone(msg, irq->irq_response); /* Copy the SIP headers from the old message */ if (msg_copy_all(msg, sip, sip_object(irq->irq_response)) >= 0) return msg; msg_destroy(msg); } return NULL; }
/** Send a BYE to an INVITE. * * @deprecated * This function should used only if application requires * RFC2543 compatibility. */ nta_outgoing_t *nta_outgoing_tbye(nta_outgoing_t *orq, nta_response_f *callback, nta_outgoing_magic_t *magic, url_string_t const *route_url, tag_type_t tag, tag_value_t value, ...) { msg_t *msg; sip_t *sip, *inv; sip_cseq_t *cs; sip_request_t *rq; su_home_t *home; url_string_t *url; if (orq == NULL || orq->orq_method != sip_method_invite) return NULL; inv = sip_object(orq->orq_request); msg = nta_msg_create(orq->orq_agent, 0); home = msg_home(msg); sip = sip_object(msg); if (inv == NULL || sip == NULL) { msg_destroy(msg); return NULL; } sip_add_tl(msg, sip, SIPTAG_TO(inv->sip_to), SIPTAG_FROM(inv->sip_from), SIPTAG_CALL_ID(inv->sip_call_id), SIPTAG_ROUTE(inv->sip_route), TAG_END()); url = (url_string_t *)inv->sip_request->rq_url; rq = sip_request_create(home, SIP_METHOD_BYE, url, NULL); sip_header_insert(msg, sip, (sip_header_t*)rq); cs = sip_cseq_create(home, inv->sip_cseq->cs_seq + 1, SIP_METHOD_BYE); sip_header_insert(msg, sip, (sip_header_t*)cs); return nta_outgoing_mcreate(orq->orq_agent, callback, magic, route_url, msg); }
/**Forward a request belonging to the leg * (stdarg version of nta_outgoing_forward()). * * @deprecated * Use nta_outgoing_mcreate() instead. */ nta_outgoing_t *nta_outgoing_vforward(nta_leg_t *leg, nta_response_f *callback, nta_outgoing_magic_t *magic, url_string_t const *route_url, url_string_t const *request_uri, nta_incoming_t const *ireq, sip_t const *isip, void const *extra, va_list headers) { nta_agent_t *agent = leg->leg_agent; nta_outgoing_t *orq = NULL; msg_t *msg, *imsg; sip_t *sip; su_home_t *home; assert(leg); assert(ireq); if (isip == NULL) imsg = ireq->irq_request, isip = sip_object(ireq->irq_request); else if (isip == sip_object(ireq->irq_request)) imsg = ireq->irq_request; else if (isip == sip_object(ireq->irq_request2)) imsg = ireq->irq_request2; else { SU_DEBUG_3(("nta_outgoing_forward: invalid arguments\n")); return NULL; } assert(isip); assert(isip->sip_request); if (!route_url) route_url = (url_string_t *)agent->sa_default_proxy; if (!(msg = nta_msg_create(agent, 0))) return NULL; msg_clone(msg, imsg); sip = sip_object(msg); home = msg_home(msg); /* Copy the SIP headers from the @c imsg message */ do { if (sip_copy_all(msg, sip, isip) < 0) break; if (sip_add_headers(msg, sip, extra, headers) < 0) break; if (!route_url && sip->sip_route) { request_uri = (url_string_t *)sip->sip_route->r_url; if (!sip_route_remove(msg, sip)) break; } if (request_uri) { sip_request_t *rq; rq = sip_request_create(home, sip->sip_request->rq_method, sip->sip_request->rq_method_name, request_uri, NULL); if (!rq || sip_header_insert(msg, sip, (sip_header_t *)rq) < 0) break; } if ((orq = nta_outgoing_mcreate(agent, callback, magic, route_url, msg))) return orq; } while (0); msg_destroy(msg); return NULL; }
/** @internal Create a message template for keepalive. */ static int create_keepalive_message(outbound_t *ob, sip_t const *regsip) { msg_t *msg = nta_msg_create(ob->ob_nta, MSG_FLG_COMPACT), *previous; sip_t *osip = sip_object(msg); sip_contact_t *m = ob->ob_rcontact; unsigned d = ob->ob_keepalive.interval; if (msg == NULL) return -1; assert(regsip); assert(regsip->sip_request); if (m && m->m_params) { sip_accept_contact_t *ac; size_t i; int features = 0; ac = sip_accept_contact_make(msg_home(msg), "*;require;explicit"); for (i = 0; m->m_params[i]; i++) { char const *s = m->m_params[i]; if (!sip_is_callerpref(s)) continue; features++; s = su_strdup(msg_home(msg), s); msg_header_add_param(msg_home(msg), ac->cp_common, s); } if (features) msg_header_insert(msg, NULL, (void *)ac); else msg_header_free(msg_home(msg), (void *)ac); } if (0 > /* Duplicate essential headers from REGISTER request: */ sip_add_tl(msg, osip, SIPTAG_TO(regsip->sip_to), SIPTAG_FROM(regsip->sip_from), /* XXX - we should only use loose routing here */ /* XXX - if we used strict routing, the route header/request_uri must be restored */ SIPTAG_ROUTE(regsip->sip_route), /* Add Max-Forwards 0 */ TAG_IF(d, SIPTAG_MAX_FORWARDS_STR("0")), TAG_IF(d, SIPTAG_SUBJECT_STR("KEEPALIVE")), SIPTAG_CALL_ID_STR(ob->ob_cookie), SIPTAG_ACCEPT_STR(outbound_content_type), TAG_END()) || /* Create request-line, Call-ID, CSeq */ nta_msg_request_complete(msg, nta_default_leg(ob->ob_nta), SIP_METHOD_OPTIONS, (void *)regsip->sip_to->a_url) < 0 || msg_serialize(msg, (void *)osip) < 0 || msg_prepare(msg) < 0) return msg_destroy(msg), -1; previous = ob->ob_keepalive.msg; ob->ob_keepalive.msg = msg; msg_destroy(previous); return 0; }