Skip to content

Commit

Permalink
b2b_logic: provite delay for terminated bridge entity
Browse files Browse the repository at this point in the history
When a message is bridged in another call, a flag (`late_bye`) may be
used to the `b2b_bridge_request` command to delay the BYE message until
the new entity establishes the call.

Worked sponsored by NG-Voice/Carsten Bock
  • Loading branch information
razvancrainea committed Jan 23, 2024
1 parent ce9fccc commit 8ff603f
Show file tree
Hide file tree
Showing 8 changed files with 344 additions and 72 deletions.
3 changes: 2 additions & 1 deletion modules/b2b_logic/b2b_load.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ int b2bl_set_state(str* key, int state);
int b2bl_bridge_2calls(str* key1, str* key2);
typedef int (*b2bl_bridge_2calls_t)(str* key1, str* key2);

int b2bl_bridge_msg(struct sip_msg* msg, str* key, int entity_no, str *adv_ct);
int b2bl_bridge_msg(struct sip_msg* msg, str* key, int entity_no,
unsigned int flags, str *adv_ct);
int b2bl_get_tuple_key(str *key, unsigned int *hash_index,
unsigned int *local_index);
typedef int (*b2bl_bridge_msg_t)(struct sip_msg* msg, str* key, int entity_no);
Expand Down
95 changes: 90 additions & 5 deletions modules/b2b_logic/b2b_logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ static int child_init(int rank);
static int fixup_init_flags(void** param);
static int fixup_free_init_flags(void** param);
static int fixup_bridge_flags(void** param);
static int fixup_bridge_request_flags(void** param);
static int fixup_init_id(void** param);
static int fixup_check_avp(void** param);
static int fixup_route(void** param);
Expand All @@ -79,7 +80,9 @@ static mi_response_t *mi_b2b_list(const mi_params_t *params,
static mi_response_t *mi_b2b_terminate_call(const mi_params_t *params,
struct mi_handler *async_hdl);
static void b2bl_clean(unsigned int ticks, void* param);
void b2bl_term_entities_timer(unsigned int ticks, void* param);
static void b2bl_db_timer_update(unsigned int ticks, void* param);
static int init_entities_term_timer(void);

int b2bl_script_init_request(struct sip_msg *msg, str *id, struct b2b_params *init_params,
void *req_routeid, void *reply_routeid);
Expand All @@ -93,7 +96,7 @@ int b2b_delete_entity(struct sip_msg *msg);
int b2b_end_dlg_leg(struct sip_msg *msg);
int b2b_send_reply(struct sip_msg *msg, int *code, str *reason, str *headers, str *body);
int b2bl_script_bridge_msg(struct sip_msg* msg, str *key, int *entity_no,
str *adv_contact);
str *adv_contact, void *flags);
int script_trigger_scenario(struct sip_msg* msg, str *id, str * params,
str *ent1, pv_spec_t *ent1_hnames, pv_spec_t *ent1_hvals,
str *ent2, pv_spec_t *ent2_hnames, pv_spec_t *ent2_hvals);
Expand Down Expand Up @@ -191,6 +194,9 @@ b2bl_tuple_t *local_ctx_tuple;
* MI cmd, when the tuple is not created yet */
struct b2b_ctx_val *local_ctx_vals;

unsigned int ent_term_interval;
struct b2b_term_timer *ent_term_timer;

static const cmd_export_t cmds[]=
{
{"b2b_init_request", (cmd_function)b2bl_script_init_request, {
Expand Down Expand Up @@ -257,7 +263,9 @@ static const cmd_export_t cmds[]=
{"b2b_bridge_request", (cmd_function)b2bl_script_bridge_msg, {
{CMD_PARAM_STR,0,0},
{CMD_PARAM_INT,0,0},
{CMD_PARAM_STR|CMD_PARAM_OPT,0,0}, {0,0,0}},
{CMD_PARAM_STR|CMD_PARAM_OPT,0,0},
{CMD_PARAM_STR|CMD_PARAM_OPT, fixup_bridge_request_flags, 0},
{0,0,0}},
REQUEST_ROUTE},
{"b2b_logic_bind", (cmd_function)b2b_logic_bind, {{0,0,0}}, 0},
{0,0,{{0,0,0}},0}
Expand Down Expand Up @@ -288,6 +296,7 @@ static const param_export_t params[]=
{"db_mode", INT_PARAM, &b2bl_db_mode },
{"b2bl_th_init_timeout",INT_PARAM, &b2bl_th_init_timeout },
{"b2bl_early_update",INT_PARAM, &b2b_early_update },
{"old_entity_term_delay",INT_PARAM, &ent_term_interval },
{0, 0, 0 }
};

Expand Down Expand Up @@ -667,6 +676,16 @@ static int mod_init(void)
register_timer("b2bl-bridge-retry", b2bl_timer_bridge_retry, 0, 1,
TIMER_FLAG_SKIP_ON_DELAY);

if (ent_term_interval) {
register_timer("b2bl-term-entities", b2bl_term_entities_timer, 0, 1,
TIMER_FLAG_DELAY_ON_DELAY);

if (init_entities_term_timer() < 0) {
LM_ERR("Failed to init entities termination timer\n");
return -1;
}
}

if (b2b_api.register_cb(entity_event_trigger,
B2BCB_TRIGGER_EVENT, &b2bl_mod_name) < 0) {
LM_ERR("could not register entity event trigger callback!\n");
Expand All @@ -684,6 +703,29 @@ static int mod_init(void)
return 0;
}

static int init_entities_term_timer(void)
{
ent_term_timer = shm_malloc(sizeof *ent_term_timer);
if (!ent_term_timer) {
LM_ERR("no more shm memory\n");
return -1;
}
memset(ent_term_timer, 0, sizeof *ent_term_timer);

ent_term_timer->lock = lock_alloc();
if (ent_term_timer->lock==0) {
LM_ERR("failed to alloc lock\n");
return -1;
}

if (lock_init(ent_term_timer->lock)==0) {
LM_ERR("failed to init lock\n");
return -1;
}

return 0;
}

void b2bl_db_timer_update(unsigned int ticks, void* param)
{
b2b_logic_dump(0);
Expand Down Expand Up @@ -768,6 +810,18 @@ void b2bl_clean(unsigned int ticks, void* param)
}
}

void destroy_entities_term_timer(void)
{
if (ent_term_timer==0)
return;

lock_destroy(ent_term_timer->lock);
lock_dealloc(ent_term_timer->lock);

shm_free(ent_term_timer);
ent_term_timer = 0;
}

static void mod_destroy(void)
{
if (b2bl_db_mode==WRITE_BACK) {
Expand Down Expand Up @@ -795,6 +849,9 @@ static void mod_destroy(void)
if (server_address_pve)
pv_elem_free_all(server_address_pve);

if (ent_term_interval)
destroy_entities_term_timer();

destroy_b2bl_htable();
b2bl_free_bridge_retry();
}
Expand Down Expand Up @@ -945,6 +1002,29 @@ static int fixup_bridge_flags(void** param)
return 0;
}


static str bridge_req_kv_flags[] =
{
str_init("late_bye"),
STR_NULL
};

static int fixup_bridge_request_flags(void** param)
{
if (fixup_named_flags(param, bridge_req_kv_flags, NULL, NULL)<0) {
LM_ERR("Failed to parse flags\n");
return -1;
}

/* ugly hack to move the flag on its right position (as the
fixup_named_flags() will set it with index 0 (as in the def array))
WARNING: this works only because we have a single flag!!!! */
if (param)
*param = (void*)(unsigned long)B2BL_BR_FLAG_BR_MSG_LATE_BYE;

return 0;
}

static int fixup_init_id(void** param)
{
str *s = (str*)*param;
Expand Down Expand Up @@ -1180,20 +1260,25 @@ mi_response_t *mi_trigger_scenario(const mi_params_t *params,
}

int b2bl_script_bridge_msg(struct sip_msg* msg, str *key, int *entity_no,
str *adv_contact)
str *adv_contact, void *flags_p)
{
unsigned int flags = 0;

if (cur_route_ctx.flags & (B2BL_RT_REQ_CTX|B2BL_RT_RPL_CTX)) {
LM_ERR("The 'b2b_bridge_request' function cannot be used from the "
"b2b_logic dedicated routes\n");
return -1;
}

return b2bl_bridge_msg(msg, key, *entity_no, adv_contact);
if (flags_p)
flags = (unsigned int)(unsigned long)flags_p;

return b2bl_bridge_msg(msg, key, *entity_no, flags, adv_contact);
}

static int b2bl_api_bridge_msg(struct sip_msg* msg, str* key, int entity_no)
{
return b2bl_bridge_msg(msg, key, entity_no, NULL);
return b2bl_bridge_msg(msg, key, entity_no, 0, NULL);
}

static mi_response_t *mi_b2b_terminate_call(const mi_params_t *params,
Expand Down
4 changes: 4 additions & 0 deletions modules/b2b_logic/b2b_logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ enum b2b_tuple_state {
#define B2BL_BR_FLAG_PROV_MEDIA (1<<5)
#define B2BL_BR_FLAG_NO_OLD_ENT (1<<6)
#define B2BL_BR_FLAG_PENDING_SDP (1<<7)
#define B2BL_BR_FLAG_BR_MSG_LATE_BYE (1<<8)

/* modes to write in db */
#define NO_DB 0
Expand Down Expand Up @@ -147,6 +148,9 @@ extern unsigned int b2bl_th_init_timeout;
extern struct script_route_ref *global_req_rt_ref;
extern struct script_route_ref *global_reply_rt_ref;
extern int b2b_early_update;
extern unsigned int ent_term_interval;

extern struct b2b_term_timer *ent_term_timer;

extern str top_hiding_scen_s;
extern str internal_scen_s;
Expand Down
Loading

0 comments on commit 8ff603f

Please sign in to comment.