|
@@ -1,4 +1,4 @@
|
|
-/*
|
|
|
|
|
|
+/*
|
|
* Copyright (C) 2009 iptelorg GmbH
|
|
* Copyright (C) 2009 iptelorg GmbH
|
|
*
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
@@ -42,7 +42,7 @@
|
|
* @param rpc - rpc handle
|
|
* @param rpc - rpc handle
|
|
* @param c - rpc context handle
|
|
* @param c - rpc context handle
|
|
* @param msg - faked sip msg
|
|
* @param msg - faked sip msg
|
|
- * @param method
|
|
|
|
|
|
+ * @param method
|
|
* @param body
|
|
* @param body
|
|
* @param fromtag - filled on success (1 if fromtag present, 0 if not)
|
|
* @param fromtag - filled on success (1 if fromtag present, 0 if not)
|
|
* @param cseq_is - filled on success (1 if cseq present, 0 if not)
|
|
* @param cseq_is - filled on success (1 if cseq present, 0 if not)
|
|
@@ -51,10 +51,10 @@
|
|
* @return -1 on error (and sends the rpc reply), 0 on success
|
|
* @return -1 on error (and sends the rpc reply), 0 on success
|
|
*/
|
|
*/
|
|
static int rpc_uac_check_msg(rpc_t *rpc, void* c,
|
|
static int rpc_uac_check_msg(rpc_t *rpc, void* c,
|
|
- struct sip_msg* msg,
|
|
|
|
- str* method, str* body,
|
|
|
|
- int* fromtag, int *cseq_is, int* cseq,
|
|
|
|
- str* callid)
|
|
|
|
|
|
+ struct sip_msg* msg,
|
|
|
|
+ str* method, str* body,
|
|
|
|
+ int* fromtag, int *cseq_is, int* cseq,
|
|
|
|
+ str* callid)
|
|
{
|
|
{
|
|
struct to_body* parsed_from;
|
|
struct to_body* parsed_from;
|
|
struct cseq_body *parsed_cseq;
|
|
struct cseq_body *parsed_cseq;
|
|
@@ -98,14 +98,14 @@ static int rpc_uac_check_msg(rpc_t *rpc, void* c,
|
|
if (ch >= '0' && ch <= '9' ) {
|
|
if (ch >= '0' && ch <= '9' ) {
|
|
*cseq = (*cseq) * 10 + ch - '0';
|
|
*cseq = (*cseq) * 10 + ch - '0';
|
|
} else {
|
|
} else {
|
|
- DBG("check_msg: Found non-numerical in CSeq: <%i>='%c'\n",
|
|
|
|
- (unsigned int)ch, ch);
|
|
|
|
|
|
+ DBG("check_msg: Found non-numerical in CSeq: <%i>='%c'\n",
|
|
|
|
+ (unsigned int)ch, ch);
|
|
rpc->fault(c, 400, "Non-numerical CSeq");
|
|
rpc->fault(c, 400, "Non-numerical CSeq");
|
|
goto err;
|
|
goto err;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
- if (parsed_cseq->method.len != method->len ||
|
|
|
|
|
|
+
|
|
|
|
+ if (parsed_cseq->method.len != method->len ||
|
|
memcmp(parsed_cseq->method.s, method->s, method->len) !=0 ) {
|
|
memcmp(parsed_cseq->method.s, method->s, method->len) !=0 ) {
|
|
rpc->fault(c, 400, "CSeq method mismatch");
|
|
rpc->fault(c, 400, "CSeq method mismatch");
|
|
goto err;
|
|
goto err;
|
|
@@ -132,12 +132,12 @@ err:
|
|
|
|
|
|
|
|
|
|
/** construct a "header block" from a header list.
|
|
/** construct a "header block" from a header list.
|
|
- *
|
|
|
|
- * @return pkg_malloc'ed header block on success (with *l set to its length),
|
|
|
|
- * 0 on error.
|
|
|
|
- */
|
|
|
|
|
|
+ *
|
|
|
|
+ * @return pkg_malloc'ed header block on success (with *l set to its length),
|
|
|
|
+ * 0 on error.
|
|
|
|
+ */
|
|
static char *get_hfblock(str *uri, struct hdr_field *hf, int proto,
|
|
static char *get_hfblock(str *uri, struct hdr_field *hf, int proto,
|
|
- struct socket_info* ssock, int* l)
|
|
|
|
|
|
+ struct socket_info* ssock, int* l)
|
|
{
|
|
{
|
|
struct str_list sl, *last, *i, *foo;
|
|
struct str_list sl, *last, *i, *foo;
|
|
int p, frag_len, total_len;
|
|
int p, frag_len, total_len;
|
|
@@ -158,10 +158,10 @@ static char *get_hfblock(str *uri, struct hdr_field *hf, int proto,
|
|
for (; hf; hf = hf->next) {
|
|
for (; hf; hf = hf->next) {
|
|
if (tm_skip_hf(hf)) continue;
|
|
if (tm_skip_hf(hf)) continue;
|
|
|
|
|
|
- begin = needle = hf->name.s;
|
|
|
|
|
|
+ begin = needle = hf->name.s;
|
|
p = hf->len;
|
|
p = hf->len;
|
|
|
|
|
|
- /* substitution loop */
|
|
|
|
|
|
+ /* substitution loop */
|
|
while(p) {
|
|
while(p) {
|
|
d = q_memchr(needle, SUBST_CHAR, p);
|
|
d = q_memchr(needle, SUBST_CHAR, p);
|
|
if (!d || d + 1 >= needle + p) { /* nothing to substitute */
|
|
if (!d || d + 1 >= needle + p) { /* nothing to substitute */
|
|
@@ -171,46 +171,46 @@ static char *get_hfblock(str *uri, struct hdr_field *hf, int proto,
|
|
frag_len = d - begin;
|
|
frag_len = d - begin;
|
|
d++; /* d not at the second substitution char */
|
|
d++; /* d not at the second substitution char */
|
|
switch(*d) {
|
|
switch(*d) {
|
|
- case SUBST_CHAR: /* double SUBST_CHAR: IP */
|
|
|
|
- /* string before substitute */
|
|
|
|
- if (!append_str_list(begin, frag_len, &last, &total_len))
|
|
|
|
- goto error;
|
|
|
|
- /* substitute */
|
|
|
|
- if (!sock_name) {
|
|
|
|
- if (
|
|
|
|
|
|
+ case SUBST_CHAR: /* double SUBST_CHAR: IP */
|
|
|
|
+ /* string before substitute */
|
|
|
|
+ if (!append_str_list(begin, frag_len, &last, &total_len))
|
|
|
|
+ goto error;
|
|
|
|
+ /* substitute */
|
|
|
|
+ if (!sock_name) {
|
|
|
|
+ if (
|
|
#ifdef USE_DNS_FAILOVER
|
|
#ifdef USE_DNS_FAILOVER
|
|
- uri2dst(0, &di, 0, uri, proto)
|
|
|
|
|
|
+ uri2dst(0, &di, 0, uri, proto)
|
|
#else
|
|
#else
|
|
- uri2dst(&di, 0, uri, proto)
|
|
|
|
|
|
+ uri2dst(&di, 0, uri, proto)
|
|
#endif /* USE_DNS_FAILOVER */
|
|
#endif /* USE_DNS_FAILOVER */
|
|
== 0 ){
|
|
== 0 ){
|
|
- LOG(L_ERR, "ERROR: get_hfblock: send_sock"
|
|
|
|
|
|
+ LOG(L_ERR, "ERROR: get_hfblock: send_sock"
|
|
" failed\n");
|
|
" failed\n");
|
|
- goto error;
|
|
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+ si_get_signaling_data(di.send_sock, &sock_name, &portname);
|
|
}
|
|
}
|
|
- si_get_signaling_data(di.send_sock, &sock_name, &portname);
|
|
|
|
- }
|
|
|
|
- if (!append_str_list(sock_name->s, sock_name->len, &last,
|
|
|
|
|
|
+ if (!append_str_list(sock_name->s, sock_name->len, &last,
|
|
&total_len))
|
|
&total_len))
|
|
- goto error;
|
|
|
|
- /* inefficient - FIXME --andrei*/
|
|
|
|
- if (!append_str_list(":", 1, &last, &total_len)) goto error;
|
|
|
|
- if (!append_str_list(portname->s, portname->len, &last,
|
|
|
|
- &total_len)) goto error;
|
|
|
|
- /* keep going ... */
|
|
|
|
- begin = needle = d + 1;
|
|
|
|
- p -= frag_len + 2;
|
|
|
|
- continue;
|
|
|
|
- default:
|
|
|
|
- /* no valid substitution char -- keep going */
|
|
|
|
- p -= frag_len + 1;
|
|
|
|
- needle = d;
|
|
|
|
|
|
+ goto error;
|
|
|
|
+ /* inefficient - FIXME --andrei*/
|
|
|
|
+ if (!append_str_list(":", 1, &last, &total_len)) goto error;
|
|
|
|
+ if (!append_str_list(portname->s, portname->len, &last,
|
|
|
|
+ &total_len)) goto error;
|
|
|
|
+ /* keep going ... */
|
|
|
|
+ begin = needle = d + 1;
|
|
|
|
+ p -= frag_len + 2;
|
|
|
|
+ continue;
|
|
|
|
+ default:
|
|
|
|
+ /* no valid substitution char -- keep going */
|
|
|
|
+ p -= frag_len + 1;
|
|
|
|
+ needle = d;
|
|
}
|
|
}
|
|
} /* possible substitute */
|
|
} /* possible substitute */
|
|
} /* substitution loop */
|
|
} /* substitution loop */
|
|
DBG("get_hfblock: one more hf processed\n");
|
|
DBG("get_hfblock: one more hf processed\n");
|
|
} /* header loop */
|
|
} /* header loop */
|
|
-
|
|
|
|
|
|
+
|
|
if(total_len==0) {
|
|
if(total_len==0) {
|
|
LM_DBG("empty result for headers block\n");
|
|
LM_DBG("empty result for headers block\n");
|
|
goto error;
|
|
goto error;
|
|
@@ -233,8 +233,8 @@ static char *get_hfblock(str *uri, struct hdr_field *hf, int proto,
|
|
}
|
|
}
|
|
*l = total_len;
|
|
*l = total_len;
|
|
return ret;
|
|
return ret;
|
|
-
|
|
|
|
- error:
|
|
|
|
|
|
+
|
|
|
|
+error:
|
|
i = sl.next;
|
|
i = sl.next;
|
|
while(i) {
|
|
while(i) {
|
|
foo = i;
|
|
foo = i;
|
|
@@ -260,14 +260,13 @@ static char *get_hfblock(str *uri, struct hdr_field *hf, int proto,
|
|
* @param reply - sip reply
|
|
* @param reply - sip reply
|
|
*/
|
|
*/
|
|
static void rpc_print_routes(rpc_t* rpc, void* c,
|
|
static void rpc_print_routes(rpc_t* rpc, void* c,
|
|
- dlg_t* d)
|
|
|
|
|
|
+ dlg_t* d)
|
|
{
|
|
{
|
|
rr_t* ptr;
|
|
rr_t* ptr;
|
|
int size;
|
|
int size;
|
|
char* buf;
|
|
char* buf;
|
|
char* p;
|
|
char* p;
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+
|
|
if (d->hooks.first_route == 0){
|
|
if (d->hooks.first_route == 0){
|
|
rpc->add(c, "s", "");
|
|
rpc->add(c, "s", "");
|
|
return;
|
|
return;
|
|
@@ -276,8 +275,8 @@ static void rpc_print_routes(rpc_t* rpc, void* c,
|
|
for (ptr=d->hooks.first_route; ptr; ptr=ptr->next)
|
|
for (ptr=d->hooks.first_route; ptr; ptr=ptr->next)
|
|
size+=ptr->len+(ptr->next!=0)*RPC_ROUTE_SEPARATOR_LEN;
|
|
size+=ptr->len+(ptr->next!=0)*RPC_ROUTE_SEPARATOR_LEN;
|
|
if (d->hooks.last_route)
|
|
if (d->hooks.last_route)
|
|
- size+=RPC_ROUTE_SEPARATOR_LEN + 1 /* '<' */ +
|
|
|
|
- d->hooks.last_route->len +1 /* '>' */;
|
|
|
|
|
|
+ size+=RPC_ROUTE_SEPARATOR_LEN + 1 /* '<' */ +
|
|
|
|
+ d->hooks.last_route->len +1 /* '>' */;
|
|
|
|
|
|
buf=pkg_malloc(size+1);
|
|
buf=pkg_malloc(size+1);
|
|
if (buf==0){
|
|
if (buf==0){
|
|
@@ -364,7 +363,7 @@ static void rpc_uac_callback(struct cell* t, int type, struct tmcb_params* ps)
|
|
void* c;
|
|
void* c;
|
|
int code;
|
|
int code;
|
|
str* preason;
|
|
str* preason;
|
|
-
|
|
|
|
|
|
+
|
|
dctx=(rpc_delayed_ctx_t*)*ps->param;
|
|
dctx=(rpc_delayed_ctx_t*)*ps->param;
|
|
*ps->param=0;
|
|
*ps->param=0;
|
|
if (dctx==0){
|
|
if (dctx==0){
|
|
@@ -398,28 +397,28 @@ static void rpc_uac_callback(struct cell* t, int type, struct tmcb_params* ps)
|
|
|
|
|
|
|
|
|
|
/** rpc t_uac version-
|
|
/** rpc t_uac version-
|
|
- * It expects the following list of strings as parameters:
|
|
|
|
- * method
|
|
|
|
- * request_uri
|
|
|
|
- * dst_uri (next hop) -- can be empty (either "" or ".", which is still
|
|
|
|
- * supported for backwards compatibility with fifo)
|
|
|
|
- * send_socket (socket from which the message will be sent)
|
|
|
|
- * headers (message headers separated by CRLF, at least From and To
|
|
|
|
- * must be present)
|
|
|
|
- * body (optional, might be null or completely missing)
|
|
|
|
- *
|
|
|
|
- * If all the parameters are ok it will call t_uac() using them.
|
|
|
|
- * Note: this version will wait for the transaction final reply
|
|
|
|
- * only if reply_wait is set to 1. Otherwise the rpc reply will be sent
|
|
|
|
- * immediately and it will be success if the paremters were ok and t_uac did
|
|
|
|
- * not report any error.
|
|
|
|
- * Note: reply waiting (reply_wait==1) is not yet supported.
|
|
|
|
- * @param rpc - rpc handle
|
|
|
|
- * @param c - rpc current context
|
|
|
|
- * @param reply_wait - if 1 do not generate a rpc reply until final response
|
|
|
|
- * for the transaction arrives, if 0 immediately send
|
|
|
|
- * an rpc reply (see above).
|
|
|
|
- */
|
|
|
|
|
|
+ * It expects the following list of strings as parameters:
|
|
|
|
+ * method
|
|
|
|
+ * request_uri
|
|
|
|
+ * dst_uri (next hop) -- can be empty (either "" or ".", which is still
|
|
|
|
+ * supported for backwards compatibility with fifo)
|
|
|
|
+ * send_socket (socket from which the message will be sent)
|
|
|
|
+ * headers (message headers separated by CRLF, at least From and To
|
|
|
|
+ * must be present)
|
|
|
|
+ * body (optional, might be null or completely missing)
|
|
|
|
+ *
|
|
|
|
+ * If all the parameters are ok it will call t_uac() using them.
|
|
|
|
+ * Note: this version will wait for the transaction final reply
|
|
|
|
+ * only if reply_wait is set to 1. Otherwise the rpc reply will be sent
|
|
|
|
+ * immediately and it will be success if the paremters were ok and t_uac did
|
|
|
|
+ * not report any error.
|
|
|
|
+ * Note: reply waiting (reply_wait==1) is not yet supported.
|
|
|
|
+ * @param rpc - rpc handle
|
|
|
|
+ * @param c - rpc current context
|
|
|
|
+ * @param reply_wait - if 1 do not generate a rpc reply until final response
|
|
|
|
+ * for the transaction arrives, if 0 immediately send
|
|
|
|
+ * an rpc reply (see above).
|
|
|
|
+ */
|
|
static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait)
|
|
static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait)
|
|
{
|
|
{
|
|
/* rpc params */
|
|
/* rpc params */
|
|
@@ -436,18 +435,18 @@ static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait)
|
|
dlg_t dlg;
|
|
dlg_t dlg;
|
|
uac_req_t uac_req;
|
|
uac_req_t uac_req;
|
|
rpc_delayed_ctx_t* dctx;
|
|
rpc_delayed_ctx_t* dctx;
|
|
-
|
|
|
|
|
|
+
|
|
body.s=0;
|
|
body.s=0;
|
|
body.len=0;
|
|
body.len=0;
|
|
dctx=0;
|
|
dctx=0;
|
|
if (reply_wait && (rpc->capabilities == 0 ||
|
|
if (reply_wait && (rpc->capabilities == 0 ||
|
|
- !(rpc->capabilities(c) & RPC_DELAYED_REPLY))) {
|
|
|
|
|
|
+ !(rpc->capabilities(c) & RPC_DELAYED_REPLY))) {
|
|
rpc->fault(c, 600, "Reply wait/async mode not supported"
|
|
rpc->fault(c, 600, "Reply wait/async mode not supported"
|
|
- " by this rpc transport");
|
|
|
|
|
|
+ " by this rpc transport");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
ret=rpc->scan(c, "SSSSS*S",
|
|
ret=rpc->scan(c, "SSSSS*S",
|
|
- &method, &ruri, &nexthop, &send_socket, &headers, &body);
|
|
|
|
|
|
+ &method, &ruri, &nexthop, &send_socket, &headers, &body);
|
|
if (ret<5 && ! (-ret == 5)){
|
|
if (ret<5 && ! (-ret == 5)){
|
|
rpc->fault(c, 400, "too few parameters (%d/5)", ret?ret:-ret);
|
|
rpc->fault(c, 400, "too few parameters (%d/5)", ret?ret:-ret);
|
|
return;
|
|
return;
|
|
@@ -482,11 +481,11 @@ static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait)
|
|
/* empty send socket */
|
|
/* empty send socket */
|
|
send_socket.len=0;
|
|
send_socket.len=0;
|
|
}else if (send_socket.len &&
|
|
}else if (send_socket.len &&
|
|
- (parse_phostport(send_socket.s, &saddr.s, &saddr.len,
|
|
|
|
- &sport, &sproto)!=0 ||
|
|
|
|
- /* check also if it's not a MH addr. */
|
|
|
|
- saddr.len==0 || saddr.s[0]=='(')
|
|
|
|
- ){
|
|
|
|
|
|
+ (parse_phostport(send_socket.s, &saddr.s, &saddr.len,
|
|
|
|
+ &sport, &sproto)!=0 ||
|
|
|
|
+ /* check also if it's not a MH addr. */
|
|
|
|
+ saddr.len==0 || saddr.s[0]=='(')
|
|
|
|
+ ){
|
|
rpc->fault(c, 400, "Invalid send socket \"%s\"", send_socket.s);
|
|
rpc->fault(c, 400, "Invalid send socket \"%s\"", send_socket.s);
|
|
return;
|
|
return;
|
|
}else if (saddr.len && (ssock=grep_sock_info(&saddr, sport, sproto))==0){
|
|
}else if (saddr.len && (ssock=grep_sock_info(&saddr, sport, sproto))==0){
|
|
@@ -503,10 +502,10 @@ static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait)
|
|
}
|
|
}
|
|
/* at this moment all the parameters are parsed => more sanity checks */
|
|
/* at this moment all the parameters are parsed => more sanity checks */
|
|
if (rpc_uac_check_msg(rpc, c, &faked_msg, &method, &body, &fromtag,
|
|
if (rpc_uac_check_msg(rpc, c, &faked_msg, &method, &body, &fromtag,
|
|
- &cseq_is, &cseq, &callid)<0)
|
|
|
|
|
|
+ &cseq_is, &cseq, &callid)<0)
|
|
goto error;
|
|
goto error;
|
|
hfb.s=get_hfblock(nexthop.len? &nexthop: &ruri, faked_msg.headers,
|
|
hfb.s=get_hfblock(nexthop.len? &nexthop: &ruri, faked_msg.headers,
|
|
- PROTO_NONE, ssock, &hfb.len);
|
|
|
|
|
|
+ PROTO_NONE, ssock, &hfb.len);
|
|
if (hfb.s==0){
|
|
if (hfb.s==0){
|
|
rpc->fault(c, 500, "out of memory");
|
|
rpc->fault(c, 500, "out of memory");
|
|
goto error;
|
|
goto error;
|
|
@@ -516,27 +515,27 @@ static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait)
|
|
/* fill call-id if call-id present or else generate a callid */
|
|
/* fill call-id if call-id present or else generate a callid */
|
|
if (callid.s && callid.len) dlg.id.call_id=callid;
|
|
if (callid.s && callid.len) dlg.id.call_id=callid;
|
|
else generate_callid(&dlg.id.call_id);
|
|
else generate_callid(&dlg.id.call_id);
|
|
-
|
|
|
|
|
|
+
|
|
/* We will not fill in dlg->id.rem_tag because
|
|
/* We will not fill in dlg->id.rem_tag because
|
|
* if present it will be printed within To HF
|
|
* if present it will be printed within To HF
|
|
*/
|
|
*/
|
|
-
|
|
|
|
|
|
+
|
|
/* Generate fromtag if not present */
|
|
/* Generate fromtag if not present */
|
|
if (!fromtag) {
|
|
if (!fromtag) {
|
|
generate_fromtag(&dlg.id.loc_tag, &dlg.id.call_id);
|
|
generate_fromtag(&dlg.id.loc_tag, &dlg.id.call_id);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
/* Fill in CSeq */
|
|
/* Fill in CSeq */
|
|
if (cseq_is) dlg.loc_seq.value = cseq;
|
|
if (cseq_is) dlg.loc_seq.value = cseq;
|
|
else dlg.loc_seq.value = DEFAULT_CSEQ;
|
|
else dlg.loc_seq.value = DEFAULT_CSEQ;
|
|
dlg.loc_seq.is_set = 1;
|
|
dlg.loc_seq.is_set = 1;
|
|
-
|
|
|
|
|
|
+
|
|
dlg.loc_uri = faked_msg.from->body;
|
|
dlg.loc_uri = faked_msg.from->body;
|
|
dlg.rem_uri = faked_msg.to->body;
|
|
dlg.rem_uri = faked_msg.to->body;
|
|
dlg.rem_target = ruri;
|
|
dlg.rem_target = ruri;
|
|
dlg.dst_uri = nexthop;
|
|
dlg.dst_uri = nexthop;
|
|
dlg.send_sock=ssock;
|
|
dlg.send_sock=ssock;
|
|
-
|
|
|
|
|
|
+
|
|
memset(&uac_req, 0, sizeof(uac_req));
|
|
memset(&uac_req, 0, sizeof(uac_req));
|
|
uac_req.method=&method;
|
|
uac_req.method=&method;
|
|
uac_req.headers=&hfb;
|
|
uac_req.headers=&hfb;
|
|
@@ -557,10 +556,10 @@ static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait)
|
|
c=dctx->reply_ctx;
|
|
c=dctx->reply_ctx;
|
|
}
|
|
}
|
|
ret = t_uac(&uac_req);
|
|
ret = t_uac(&uac_req);
|
|
-
|
|
|
|
|
|
+
|
|
if (ret <= 0) {
|
|
if (ret <= 0) {
|
|
err_ret = err2reason_phrase(ret, &sip_error, err_buf,
|
|
err_ret = err2reason_phrase(ret, &sip_error, err_buf,
|
|
- sizeof(err_buf), "RPC/UAC") ;
|
|
|
|
|
|
+ sizeof(err_buf), "RPC/UAC") ;
|
|
if (err_ret > 0 )
|
|
if (err_ret > 0 )
|
|
{
|
|
{
|
|
rpc->fault(c, sip_error, "%s", err_buf);
|
|
rpc->fault(c, sip_error, "%s", err_buf);
|
|
@@ -580,16 +579,16 @@ error:
|
|
|
|
|
|
|
|
|
|
/** t_uac with no reply waiting.
|
|
/** t_uac with no reply waiting.
|
|
- * @see rpc_t_uac.
|
|
|
|
- */
|
|
|
|
|
|
+ * @see rpc_t_uac.
|
|
|
|
+ */
|
|
void rpc_t_uac_start(rpc_t* rpc, void* c)
|
|
void rpc_t_uac_start(rpc_t* rpc, void* c)
|
|
{
|
|
{
|
|
rpc_t_uac(rpc, c, 0);
|
|
rpc_t_uac(rpc, c, 0);
|
|
}
|
|
}
|
|
|
|
|
|
/** t_uac with reply waiting.
|
|
/** t_uac with reply waiting.
|
|
- * @see rpc_t_uac.
|
|
|
|
- */
|
|
|
|
|
|
+ * @see rpc_t_uac.
|
|
|
|
+ */
|
|
void rpc_t_uac_wait(rpc_t* rpc, void* c)
|
|
void rpc_t_uac_wait(rpc_t* rpc, void* c)
|
|
{
|
|
{
|
|
rpc_t_uac(rpc, c, 1);
|
|
rpc_t_uac(rpc, c, 1);
|