struct mi_root* mi_set_pipe(struct mi_root* cmd_tree, void* param) { struct mi_node *node; unsigned int pipe_no = MAX_PIPES, algo_id, limit = 0; //str algo; node = cmd_tree->node.kids; if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if ( !node->value.s || !node->value.len || strno2int(&node->value,&pipe_no)<0) goto bad_syntax; node = node->next; if ( !node->value.s || !node->value.len) goto bad_syntax; if (str_map_str(algo_names, &(node->value), (int*)&algo_id)) { LM_ERR("unknown algorithm: '%.*s'\n", node->value.len, node->value.s); goto bad_syntax; } node = node->next; if ( !node->value.s || !node->value.len || strno2int(&node->value,&limit)<0) goto bad_syntax; LM_DBG("set pipe: %d:%d:%d\n", pipe_no, algo_id, limit); if (pipe_no >= MAX_PIPES) { LM_ERR("wrong pipe_no: %d\n", pipe_no); goto bad_syntax; } LOCK_GET(rl_lock); *pipes[pipe_no].algo = algo_id; *pipes[pipe_no].limit = limit; if (check_feedback_setpoints(0)) { LM_ERR("feedback limits don't match\n"); goto error; } else { *pid_setpoint = 0.01 * (double)cfg_setpoint; } set_check_network_load(); LOCK_RELEASE(rl_lock); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); error: LOCK_RELEASE(rl_lock); bad_syntax: return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); }
struct mi_root* mi_set_queue(struct mi_root* cmd_tree, void* param) { struct mi_node *node; unsigned int queue_no = MAX_QUEUES, pipe_no = MAX_PIPES; str method; node = cmd_tree->node.kids; if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if ( !node->value.s || !node->value.len || strno2int(&node->value,&queue_no)<0) goto bad_syntax; node = node->next; if ( !node->value.s || !node->value.len ) goto bad_syntax; if (str_cpy(&method, &(node->value))) { LM_ERR("out of memory\n"); goto early_error; } node = node->next; if ( !node->value.s || !node->value.len || strno2int(&node->value,&pipe_no)<0) goto early_error; if (pipe_no >= MAX_PIPES) { LM_ERR("invalid pipe number: %d\n", pipe_no); goto early_error; } LOCK_GET(rl_lock); if (queue_no >= *nqueues) { LM_ERR("MAX_QUEUES reached for queue: %d\n", queue_no); goto error; } *queues[queue_no].pipe = pipe_no; if (!queues[queue_no].method->s) shm_free(queues[queue_no].method->s); queues[queue_no].method->s = method.s; queues[queue_no].method->len = method.len; LOCK_RELEASE(rl_lock); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); error: LOCK_RELEASE(rl_lock); early_error: shm_free(method.s); bad_syntax: return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); }
static struct mi_root* mi_reset_gflag(struct mi_root* cmd_tree, void* param ) { unsigned int flag; struct mi_node* node = NULL; node = cmd_tree->node.kids; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); flag = 0; if( strno2int( &node->value, &flag) <0) goto error; if (!flag) { LM_ERR("incorrect flag\n"); goto error; } lock_get(gflags_lock); (*gflags) &= ~ flag; lock_release(gflags_lock); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); error: return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); }
/*! \brief * Fixup for "save" function - both domain and flags */ static int save_fixup(void** param, int param_no) { unsigned int flags; str s; if (param_no == 1) { return domain_fixup(param,param_no); } else if (param_no == 2) { s.s = (char*)*param; s.len = strlen(s.s); flags = 0; if ( (strno2int(&s, &flags )<0) || (flags>REG_SAVE_ALL_FL) ) { LM_ERR("bad flags <%s>\n", (char *)(*param)); return E_CFG; } if (ul.db_mode==DB_ONLY && flags®_SAVE_MEM_FL) { LM_ERR("MEM flag set while using the DB_ONLY mode in USRLOC\n"); return E_CFG; } pkg_free(*param); *param = (void*)(unsigned long int)flags; } else if (param_no == 3) { return fixup_spve_null(param, 1); } return 0; }
unsigned int get_app_index(struct sip_msg* msg) { unsigned int appearance; struct hdr_field *call_info; struct call_info_body *callinfo_b; struct to_body *call_info_b; struct to_param *param; if (0 == parse_call_info_header(msg)) { call_info = msg->call_info; while (call_info) { //LM_DBG("BODY=[%p]->[%.*s] sibling=[%p]\n", call_info, // call_info->body.len, call_info->body.s, // call_info->sibling); callinfo_b = call_info->parsed; while (callinfo_b) { call_info_b = &(callinfo_b->call_info_body); //LM_DBG(". body=[%.*s] param_lst=[%p] " // "last_param=[%p]\n", // call_info_b->body.len, call_info_b->body.s, // call_info_b->param_lst, // call_info_b->last_param); param = call_info_b->param_lst; while (param) { //LM_DBG(".. [%p]->[%d] " // "[%.*s]=[%.*s]->[%p]\n", // param, param->type, // param->name.len, param->name.s, // param->value.len, param->value.s, // param->next); if (param->name.len==APPEARANCE_INDEX_LEN && strncmp(APPEARANCE_INDEX_STR, param->name.s, APPEARANCE_INDEX_LEN)==0) { if (strno2int(¶m->value, &appearance)<0) { LM_ERR("bad appearance-index" " [%.*s]\n", param->value.len, param->value.s); return 0; } LM_DBG("*** GOT APP-INDEX [%d]\n", appearance); return appearance; } param=param->next; } callinfo_b = callinfo_b->next; } call_info = call_info->sibling; } } else { LM_ERR("Unable to parse Call-Info header\n"); return 0; } LM_ERR("appearance index not found\n"); return 0; }
struct mi_root* mi_set_dbg(struct mi_root* cmd_tree, void* param) { struct mi_node *node; unsigned int dbg_mode = 0; node = cmd_tree->node.kids; if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if ( !node->value.s || !node->value.len || strno2int(&node->value,&dbg_mode)<0) goto bad_syntax; LOCK_GET(rl_lock); if (dbg_mode) { if (!rl_dbg_str->s) { rl_dbg_str->len = (MAX_PIPES * 5 * sizeof(char)); rl_dbg_str->s = (char *)shm_malloc(rl_dbg_str->len); if (!rl_dbg_str->s) { rl_dbg_str->len = 0; LM_ERR("oom: %d\n", rl_dbg_str->len); } } } else { if (rl_dbg_str->s) { shm_free(rl_dbg_str->s); rl_dbg_str->s = NULL; rl_dbg_str->len = 0; } } LOCK_RELEASE(rl_lock); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); bad_syntax: return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); }
struct mi_root* mi_set_pipe(struct mi_root* cmd_tree, void* param) { struct mi_node *node; unsigned int algo_id, limit = 0; pl_pipe_t *it; str pipeid; node = cmd_tree->node.kids; if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if ( !node->value.s || !node->value.len) goto error; pipeid = node->value; node = node->next; if ( !node->value.s || !node->value.len) goto error; if (str_map_str(algo_names, &(node->value), (int*)&algo_id)) { LM_ERR("unknown algorithm: '%.*s'\n", node->value.len, node->value.s); goto error; } node = node->next; if ( !node->value.s || !node->value.len || strno2int(&node->value,&limit)<0) goto error; LM_DBG("set_pipe: %.*s:%d:%d\n", pipeid.len, pipeid.s, algo_id, limit); it = pl_pipe_get(&pipeid, 1); if (it==NULL) { LM_ERR("no pipe: %.*s\n", pipeid.len, pipeid.s); goto error; } it->algo = algo_id; it->limit = limit; if (check_feedback_setpoints(0)) { pl_pipe_release(&pipeid); LM_ERR("feedback limits don't match\n"); goto error; } else { *_pl_pid_setpoint = 0.01 * (double)_pl_cfg_setpoint; } pl_pipe_release(&pipeid); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); error: return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); }
static int flag_fixup(void** param, int param_no) { unsigned int flags; str s; if (param_no == 1) { s.s = (char*)*param; s.len = strlen(s.s); flags = 0; if ( strno2int(&s, &flags )<0 ) { return -1; } pkg_free(*param); *param = (void*)(unsigned long int)(flags<<1); } return 0; }
static void rpc_reset_gflag(rpc_t* rpc, void* c) { str flag_str; unsigned int flag; if (rpc->scan(c, "S", &flag_str) != 1) { rpc->fault(c, 400, "flag parameter error"); return; } flag = 0; if ((strno2int(&flag_str, &flag) < 0) || !flag) { rpc->fault(c, 400, "incorrect flag parameter value"); return; } lock_get(gflags_lock); (*gflags) &= ~ flag; lock_release(gflags_lock); return; }
static struct mi_root* mi_is_gflag(struct mi_root* cmd_tree, void* param ) { unsigned int flag; struct mi_root* rpl_tree = NULL; struct mi_node* node = NULL; node = cmd_tree->node.kids; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); flag = 0; if( strno2int( &node->value, &flag) <0) goto error_param; if (!flag) { LM_ERR("incorrect flag\n"); goto error_param; } rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if(rpl_tree ==0) return 0; if( ((*gflags) & flag)== flag ) node = add_mi_node_child( &rpl_tree->node, 0, 0, 0, "TRUE", 4); else node = add_mi_node_child( &rpl_tree->node, 0, 0, 0, "FALSE", 5); if(node == NULL) { LM_ERR("failed to add node\n"); free_mi_tree(rpl_tree); return 0; } return rpl_tree; error_param: return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); }
static void rpc_is_gflag(rpc_t* rpc, void* c) { str flag_str; unsigned int flag; if (rpc->scan(c, "S", &flag_str) != 1) { rpc->fault(c, 400, "flag parameter error"); return; } flag = 0; if ((strno2int(&flag_str, &flag) < 0) || !flag) { rpc->fault(c, 400, "incorrect flag parameter value"); return; } if (((*gflags) & flag) == flag) rpc->add(c, "s", "TRUE"); else rpc->add(c, "s", "FALSE"); return; }
/*parameters from MI: h_entry, h_id of the requested dialog*/ struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param ){ struct mi_node* node; unsigned int h_entry, h_id; struct dlg_cell * dlg = NULL; str mi_extra_hdrs = {NULL,0}; int status, msg_len; char *msg; if( d_table ==NULL) goto end; node = cmd_tree->node.kids; h_entry = h_id = 0; if (node==NULL || node->next==NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if (!node->value.s|| !node->value.len|| strno2int(&node->value,&h_entry)<0) goto error; node = node->next; if ( !node->value.s || !node->value.len || strno2int(&node->value,&h_id)<0) goto error; if (node->next) { node = node->next; if (node->value.len && node->value.s) mi_extra_hdrs = node->value; } LM_DBG("h_entry %u h_id %u\n", h_entry, h_id); dlg = dlg_lookup(h_entry, h_id); // lookup_dlg has incremented the reference count if(dlg){ if(dlg_bye_all(dlg,(mi_extra_hdrs.len>0)?&mi_extra_hdrs:NULL)<0) { status = 500; msg = MI_DLG_OPERATION_ERR; msg_len = MI_DLG_OPERATION_ERR_LEN; } else { status = 200; msg = MI_OK_S; msg_len = MI_OK_LEN; } dlg_release(dlg); return init_mi_tree(status, msg, msg_len); } end: return init_mi_tree(404, MI_DIALOG_NOT_FOUND, MI_DIALOG_NOT_FOUND_LEN); error: return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); }
/*parameters from MI: h_entry, h_id of the requested dialog*/ struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param ){ struct mi_node* node; unsigned int h_entry, h_id; struct dlg_cell * dlg = NULL; str *mi_extra_hdrs = NULL; int status, msg_len; char *msg; if( d_table ==NULL) goto end; node = cmd_tree->node.kids; h_entry = h_id = 0; if (node==NULL || node->next==NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if (!node->value.s|| !node->value.len|| strno2int(&node->value,&h_entry)<0) goto error; node = node->next; if ( !node->value.s || !node->value.len || strno2int(&node->value,&h_id)<0) goto error; if (node->next) { node = node->next; if (node->value.len && node->value.s) mi_extra_hdrs = &node->value; } LM_DBG("h_entry %u h_id %u\n", h_entry, h_id); dlg = lookup_dlg(h_entry, h_id); /* lookup_dlg has incremented the reference count !! */ if(dlg){ init_dlg_term_reason(dlg,"MI Termination",sizeof("MI Termination")-1); if ( dlg_end_dlg( dlg, mi_extra_hdrs) ) { status = 500; msg = MI_DLG_OPERATION_ERR; msg_len = MI_DLG_OPERATION_ERR_LEN; } else { status = 200; msg = MI_OK_S; msg_len = MI_OK_LEN; } unref_dlg(dlg, 1); return init_mi_tree(status, msg, msg_len); } end: return init_mi_tree(404, MI_DIALOG_NOT_FOUND, MI_DIALOG_NOT_FOUND_LEN); error: return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); }
int sca_logic_notify(b2bl_cb_params_t *params, unsigned int b2b_event) { int on_hold = 0; int sdp_session_num = 0, sdp_stream_num; sdp_session_cell_t* sdp_session; sdp_stream_cell_t* sdp_stream; struct sip_msg *msg = params->msg; b2bl_cb_ctx_t *cb_params = params->param; str *shared_line; unsigned int hash_index, appearance; b2b_sca_record_t *record; b2b_sca_call_t *call = NULL; str publish_hdr; unsigned int call_info_appearance; unsigned int call_info_appearance_state = 0; struct hdr_field *call_info; struct call_info_body *callinfo_b; struct to_body *call_info_b; struct to_param *param; if (b2b_sca_shutdown_completed) return B2B_FOLLOW_SCENARIO_CB_RET; if (params == NULL) { LM_ERR("callback event [%d] without cb params\n", b2b_event); return B2B_DROP_MSG_CB_RET; } shared_line = &cb_params->shared_line; hash_index = cb_params->hash_index; appearance = cb_params->appearance; LM_DBG("*** GOT NOTIFICATION TYPE [%d] WITH cb_params [%p]->[%.*s] appearance [%d] on hash index [%d]" " for b2bl entity [%d]\n", b2b_event, cb_params, shared_line->len, shared_line->s, appearance, hash_index, params->entity); if (msg && msg->call_info) { if (0 == parse_call_info_header(msg)) { call_info = msg->call_info; if (call_info) { LM_DBG("BODY=[%p]->[%.*s] sibling=[%p]\n", call_info, call_info->body.len, call_info->body.s, call_info->sibling); callinfo_b = call_info->parsed; while (callinfo_b) { call_info_b = &(callinfo_b->call_info_body); LM_DBG(". body=[%.*s] param_lst=[%p] last_param=[%p]\n", call_info_b->body.len, call_info_b->body.s, call_info_b->param_lst, call_info_b->last_param); param = call_info_b->param_lst; while (param) { LM_DBG(".. [%p]->[%d] [%.*s]=[%.*s]->[%p]\n", param, param->type, param->name.len, param->name.s, param->value.len, param->value.s, param->next); if (param->name.len==APPEARANCE_INDEX_LEN && strncmp(APPEARANCE_INDEX_STR, param->name.s, APPEARANCE_INDEX_LEN)==0) { if (strno2int(¶m->value,&call_info_appearance)<0) { LM_ERR("bad appearance-index [%.*s]\n", param->value.len, param->value.s); return -1; } if (appearance != call_info_appearance) { LM_ERR("got appearance[%d] while expecting[%d]\n", call_info_appearance, appearance); goto next_callinfo_b; } else { LM_DBG("*** GOT APP-INDEX [%d]\n", call_info_appearance); } } else if (param->name.len==APPEARANCE_STATE_LEN && strncmp(APPEARANCE_STATE_STR, param->name.s, APPEARANCE_STATE_LEN)==0) { LM_DBG("*** GOT APP-STATE [%.*s]\n", param->value.len, param->value.s); if (param->value.len == strlen(APP_STATE_HELD_PRIVATE) && strncmp(param->value.s, app_state[HELD_PRIVATE_STATE].s, param->value.len)==0) { call_info_appearance_state = HELD_PRIVATE_STATE; } } param=param->next; } goto handle_appearance; next_callinfo_b: callinfo_b = callinfo_b->next; } call_info = call_info->sibling; } } else { LM_ERR("Unable to parse Call-Info header\n"); return B2B_DROP_MSG_CB_RET; } } handle_appearance: lock_get(&b2b_sca_htable[hash_index].lock); record = b2b_sca_search_record_safe(hash_index, shared_line); if (record == NULL) { lock_release(&b2b_sca_htable[hash_index].lock); LM_ERR("record not found for shared line [%.*s] on hash index [%d]\n", shared_line->len, shared_line->s, hash_index); return B2B_DROP_MSG_CB_RET; } b2b_sca_print_record(record); switch(b2b_event){ case B2B_DESTROY_CB: /* Destroy the sca index record */ shm_free(params->param); b2b_sca_delete_call_record(hash_index, record, appearance); break; case B2B_RE_INVITE_CB: case B2B_CONFIRMED_CB: call = b2b_sca_search_call_safe(record, appearance); if (call == NULL) { LM_ERR("call record not found for shared line [%.*s] with index [%d]\n", shared_line->len, shared_line->s, appearance); lock_release(&b2b_sca_htable[hash_index].lock); return B2B_DROP_MSG_CB_RET; } if (0 == parse_sdp(msg)) { sdp_session = get_sdp_session(msg, sdp_session_num); if(!sdp_session) break; sdp_stream_num = 0; for(;;) { sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num); if(!sdp_stream) break; if(sdp_stream->media.len==AUDIO_STR_LEN && strncmp(sdp_stream->media.s,AUDIO_STR,AUDIO_STR_LEN)==0 && sdp_stream->is_on_hold) { on_hold = 1; break; } sdp_stream_num++; } sdp_session_num++; } if (on_hold) { if (call_info_appearance_state) call->call_state = HELD_PRIVATE_STATE; else call->call_state = HELD_STATE; } else { call->call_state = ACTIVE_STATE; } break; default: LM_ERR("Unexpected event\n"); } /* Prepare PUBLISH Call-Info header. */ if (build_publish_call_info_header(record, &publish_hdr) != 0) { lock_release(&b2b_sca_htable[hash_index].lock); LM_ERR("Unable to build PUBLISH Call-Info header\n"); return B2B_FOLLOW_SCENARIO_CB_RET; } /* Save the record to db. */ if (push_sca_info_to_db(record, appearance, 1) != 0) LM_ERR("DB out of synch\n"); /* Notify the watchers. */ sca_publish(record, &publish_hdr); b2b_sca_delete_record_if_empty(record, hash_index); lock_release(&b2b_sca_htable[hash_index].lock); if (publish_hdr.s != publish_call_info_hdr_buf) pkg_free(publish_hdr.s); return B2B_FOLLOW_SCENARIO_CB_RET; }