Skip to content

Commit

Permalink
b2b_logic: add ability to retry bridging from script
Browse files Browse the repository at this point in the history
  • Loading branch information
rvlad-patrascu committed Dec 21, 2022
1 parent 6e1ffc3 commit 3f6790e
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 21 deletions.
4 changes: 4 additions & 0 deletions modules/b2b_logic/b2b_logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ static cmd_export_t cmds[]=
{CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL,
fixup_bridge_flags, fixup_free_init_flags}, {0,0,0}},
REQUEST_ROUTE},
{"b2b_bridge_retry", (cmd_function)b2b_script_bridge_retry, {
{CMD_PARAM_STR,0,0},
{0,0,0}},
REQUEST_ROUTE},
{"b2b_trigger_scenario", (cmd_function)script_trigger_scenario, {
{CMD_PARAM_STR,fixup_init_id,0},
{CMD_PARAM_STR|CMD_PARAM_OPT,
Expand Down
119 changes: 116 additions & 3 deletions modules/b2b_logic/bridging.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "../../parser/parse_uri.h"
#include "../presence/utils_func.h"
#include "../../parser/sdp/sdp.h"
#include "../../parser/parse_methods.h"

#include "entity_storage.h"
#include "records.h"
Expand Down Expand Up @@ -62,6 +63,9 @@ static b2bl_entity_id_t *bridging_new_client(b2bl_tuple_t* tuple,
static int bridging_start_old_ent(b2bl_tuple_t* tuple, b2bl_entity_id_t *old_entity,
b2bl_entity_id_t *new_entity, str *provmedia_uri, str *body);

int retry_init_bridge(struct sip_msg *msg, b2bl_tuple_t* tuple,
b2bl_entity_id_t *entity, struct b2bl_new_entity *new_entity);

mi_response_t *mi_b2b_bridge(const mi_params_t *params,
int entity_no, str *prov_media)
{
Expand Down Expand Up @@ -1140,6 +1144,118 @@ int b2b_script_bridge(struct sip_msg *msg, str *br_ent1_str, str *br_ent2_str,
return rc;
}

int b2b_script_bridge_retry(struct sip_msg *msg, str *new_ent_str)
{
b2bl_tuple_t *tuple;
b2bl_entity_id_t *entity;
str method;
int statuscode;
unsigned int method_value;
b2bl_entity_id_t** entity_head = NULL;

if (!(cur_route_ctx.flags & B2BL_RT_RPL_CTX)) {
LM_ERR("The 'b2b_bridge_retry' function can only be used from the "
"b2b_logic dedicated reply route\n");
return -1;
}

lock_get(&b2bl_htable[cur_route_ctx.hash_index].lock);

tuple = b2bl_search_tuple_safe(cur_route_ctx.hash_index,
cur_route_ctx.local_index);
if(tuple == NULL)
{
LM_ERR("B2B logic record not found\n");
goto error;
}

entity = b2bl_search_entity(tuple, &cur_route_ctx.entity_key,
cur_route_ctx.entity_type, &entity_head);
if(entity == NULL)
{
LM_ERR("No b2b_key match found [%.*s], src=%d\n",
cur_route_ctx.entity_key.len, cur_route_ctx.entity_key.s,
cur_route_ctx.entity_type);
goto error;
}

LM_DBG("b2b_entity key = %.*s\n",
cur_route_ctx.entity_key.len, cur_route_ctx.entity_key.s);

method = get_cseq(msg)->method;
if(parse_method(method.s, method.s+method.len, &method_value) == NULL)
{
LM_ERR("Failed to parse method\n");
goto error;
}
if (method_value != METHOD_INVITE) {
LM_ERR("The 'b2b_bridge_retry' function can only be used for"
"replies to INVITES\n");
goto error;
}

statuscode = msg->first_line.u.reply.statuscode;
if (statuscode <= 300) {
LM_ERR("The 'b2b_bridge_retry' function can only be used for"
"negative replies\n");
goto error;
}

if (entity != tuple->bridge_entities[1]) {
LM_ERR("The 'b2b_bridge_retry' function can only be used for"
"negative replies from the second entity\n");
goto error;
}

if (new_entities[0] && str_strcmp(new_ent_str, &new_entities[0]->id)) {
LM_ERR("Unknown client entity %.*s\n", new_ent_str->len, new_ent_str->s);
goto error;
}

local_ctx_tuple = tuple;

if (IS_BRIDGING_STATE(tuple->state)) {
b2bl_delete_entity(entity, tuple, tuple->hash_index, 1);

entity = b2bl_create_new_entity( B2B_CLIENT, 0, &new_entities[0]->dest_uri,
&new_entities[0]->proxy, 0, &new_entities[0]->from_dname,
0,0,0,0);
if(entity == NULL)
{
LM_ERR("Failed to create new b2b entity\n");
goto error;
}
LM_DBG("Created new client entity [%.*s]\n",
new_entities[0]->dest_uri.len, new_entities[0]->dest_uri.s);

if (bridging_start_new_ent(tuple, tuple->bridge_entities[0], entity,
NULL, 0) < 0) {
LM_ERR("Failed to start bridging with new entity\n");
goto error;
}

tuple->state = B2B_BRIDGING_STATE;
} else if (tuple->state == B2B_INIT_BRIDGING_STATE) {
if (retry_init_bridge(msg, tuple, entity,
new_entities[0]) < 0) {
LM_ERR("Failed to retry initial bridge\n");
goto error;
}
} else {
LM_ERR("Unable to retry bridge for tuple in state: %d\n", tuple->state);
goto error;
}

lock_release(&b2bl_htable[cur_route_ctx.hash_index].lock);

return 1;

error:
local_ctx_tuple = NULL;
lock_release(&b2bl_htable[cur_route_ctx.hash_index].lock);
return -1;
}

static b2bl_entity_id_t *bridging_new_client(b2bl_tuple_t* tuple,
b2bl_entity_id_t *peer_ent, b2bl_entity_id_t *new_ent,
str *body, struct sip_msg *msg, int set_maxfwd)
Expand Down Expand Up @@ -1530,9 +1646,6 @@ int b2bl_bridge(struct sip_msg* msg, b2bl_tuple_t* tuple,
return -1;
}

int retry_init_bridge(struct sip_msg *msg, b2bl_tuple_t* tuple,
b2bl_entity_id_t *entity, struct b2bl_new_entity *new_entity);

int b2bl_api_bridge(str* key, str* new_dst, str *new_proxy, str* new_from_dname,
int entity_no)
{
Expand Down
1 change: 1 addition & 0 deletions modules/b2b_logic/bridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ mi_response_t *mi_b2b_bridge(const mi_params_t *params,
int entity_no, str *prov_media);
int b2b_script_bridge(struct sip_msg *msg, str *br_ent1_str, str *br_ent2_str,
str *provmedia_uri, struct b2b_bridge_params *params);
int b2b_script_bridge_retry(struct sip_msg *msg, str *new_ent_str);

int send_bridge_notify(b2bl_entity_id_t *entity, unsigned int hash_index,
struct sip_msg* msg);
Expand Down
22 changes: 4 additions & 18 deletions modules/b2b_logic/logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,18 +965,10 @@ int _b2b_handle_reply(struct sip_msg *msg, b2bl_tuple_t *tuple,
if (ret == -1) {
goto error;
} else if (ret == 0) {
if (new_entities[0]) {
if (retry_init_bridge(msg, tuple, entity,
new_entities[0]) < 0) {
LM_ERR("Failed to retry initial bridge\n");
goto error;
}
} else {
SEND_REPLY_TO_PEER_OR_GOTO_DONE;
LM_DBG("Negative reply [%d] - delete[%p]\n",
statuscode, tuple);
b2b_mark_todel(tuple);
}
SEND_REPLY_TO_PEER_OR_GOTO_DONE;
LM_DBG("Negative reply [%d] - delete[%p]\n",
statuscode, tuple);
b2b_mark_todel(tuple);
}
}
b2bl_print_tuple(tuple, L_DBG);
Expand Down Expand Up @@ -3621,12 +3613,6 @@ int b2bl_server_new(struct sip_msg *msg, str *id, str *adv_contact,
int b2bl_client_new(struct sip_msg *msg, str *id, str *dest_uri, str *proxy,
str *from_dname, str *adv_contact, pv_spec_t *hnames, pv_spec_t *hvals)
{
if (cur_route_ctx.flags & B2BL_RT_RPL_CTX) {
LM_ERR("The 'b2b_client_new' function cannot be used from the "
"b2b_logic dedicated reply routes\n");
return -1;
}

return b2bl_entity_new(msg, id, dest_uri, proxy, B2B_CLIENT,
hnames, hvals, from_dname, adv_contact);
}
Expand Down

0 comments on commit 3f6790e

Please sign in to comment.