static mi_response_t *clusterer_set_status(const mi_params_t *params, struct mi_handler *async_hdl) { int cluster_id; int state; int rc; if (get_mi_int_param(params, "cluster_id", &cluster_id) < 0) return init_mi_param_error(); if (cluster_id < 1) return init_mi_error(400, MI_SSTR("Bad value for 'cluster_id'")); if (get_mi_int_param(params, "status", &state) < 0) return init_mi_param_error(); if (state != STATE_DISABLED && state != STATE_ENABLED) return init_mi_error(400, MI_SSTR("Bad value for 'status'")); rc = cl_set_state(cluster_id, state); if (rc == -1) return init_mi_error(404, MI_SSTR("Cluster id not found")); if (rc == 1) return init_mi_error(404, MI_SSTR("Node id not found")); return init_mi_result_ok(); }
/*parameters from MI: dialog ID of the requested dialog*/ mi_response_t *mi_terminate_dlg(const mi_params_t *params, str *extra_hdrs) { unsigned int h_entry, h_id; unsigned long long d_id; struct dlg_cell * dlg = NULL; str dialog_id; char *end; char bkp; int shtag_state = 1; if( d_table ==NULL) return init_mi_error(404, MI_SSTR(MI_DIALOG_NOT_FOUND)); h_entry = h_id = 0; if (get_mi_string_param(params, "dialog_id", &dialog_id.s, &dialog_id.len) < 0) return init_mi_param_error(); /* Get the dialog based of the dialog_id. This may be a * numerical DID or a string SIP Call-ID */ /* make value null terminated (in an ugly way) */ bkp = dialog_id.s[dialog_id.len]; dialog_id.s[dialog_id.len] = 0; /* conver to long long */ d_id = strtoll( dialog_id.s, &end, 10); dialog_id.s[dialog_id.len] = bkp; if (end-dialog_id.s==dialog_id.len) { /* the ID is numeric, so let's consider it DID */ h_entry = (unsigned int)(d_id>>(8*sizeof(int))); h_id = (unsigned int)(d_id & (((unsigned long long)1<<(8*sizeof(int)))-1) ); LM_DBG("ID: %llu (h_entry %u h_id %u)\n", d_id, h_entry, h_id); dlg = lookup_dlg(h_entry, h_id); } else {
/*! \brief Reload pcres by reading the file again */ mi_response_t *mi_pcres_reload(const mi_params_t *params, struct mi_handler *async_hdl) { /* Check if group matching feature is enabled */ if (file == NULL) { LM_NOTICE("'file' parameter is not set, group matching disabled\n"); return init_mi_error(403, MI_SSTR("Group matching not enabled")); } LM_NOTICE("reloading pcres...\n"); if (load_pcres(RELOAD)) { LM_ERR("failed to reload pcres\n"); return init_mi_error(500, MI_SSTR("Internal error")); } LM_NOTICE("reload success\n"); return init_mi_result_ok(); }
mi_response_t *refreshXcapDoc(const mi_params_t *params, struct mi_handler *async_hdl) { str doc_url; xcap_doc_sel_t doc_sel; char* serv_addr; str stream= {0, 0}; int type; int xcap_port; char* etag= NULL; if (get_mi_string_param(params, "doc_uri", &doc_url.s, &doc_url.len) < 0) return init_mi_param_error(); if(doc_url.s == NULL || doc_url.len== 0) { LM_ERR("empty uri\n"); return init_mi_error(404, MI_SSTR("Empty document URL")); } if (get_mi_int_param(params, "port", &xcap_port) < 0) return init_mi_param_error(); /* send GET HTTP request to the server */ stream.s = send_http_get(doc_url.s, xcap_port, NULL, 0, &etag, &stream.len); if(stream.s== NULL) { LM_ERR("in http get\n"); return 0; } /* call registered functions with document argument */ if(parse_doc_url(doc_url, &serv_addr, &doc_sel)< 0) { LM_ERR("parsing document url\n"); return 0; } type = xcap_doc_type(&doc_sel.auid); if (type < 0) { LM_ERR("incorect auid: %.*s\n", doc_sel.auid.len, doc_sel.auid.s); goto error; } run_xcap_update_cb(type, doc_sel.xid, stream.s); pkg_free(stream.s); return init_mi_result_ok(); error: if(stream.s) pkg_free(stream.s); return 0; }
mi_response_t *mi_get_hash(const mi_params_t *params, struct mi_handler *async_hdl) { if (!hash_file) { LM_INFO("no hash_file given, disable hash functionality\n"); return init_mi_error(404, MI_SSTR("Functionality disabled")); } else { return init_mi_result_string(config_hash, MD5_LEN); } }
mi_response_t *clusterer_reload(const mi_params_t *params, struct mi_handler *async_hdl) { cluster_info_t *new_info; cluster_info_t *old_info; if (!db_mode) { LM_ERR("Running in non-DB mode\n"); return init_mi_error(400, MI_SSTR("Non-DB mode")); } if (load_db_info(&dr_dbf, db_hdl, &db_table, &new_info) != 0) { LM_ERR("Failed to load info from DB\n"); return init_mi_error(500, MI_SSTR("Failed to reload")); } lock_start_write(cl_list_lock); if (preserve_reg_caps(new_info) < 0) { lock_stop_write(cl_list_lock); LM_ERR("Failed to preserve registered capabilities\n"); if (new_info) free_info(new_info); return init_mi_error(500, "Failed to reload", 16); } old_info = *cluster_list; *cluster_list = new_info; lock_stop_write(cl_list_lock); if (old_info) free_info(old_info); LM_INFO("Reloaded DB info\n"); /* check if the cluster IDs in the the sharing tag list are valid */ shtag_validate_list(); return init_mi_result_ok(); }
mi_response_t *mi_check_hash(const mi_params_t *params, struct mi_handler *async_hdl) { char tmp[MD5_LEN]; memset(tmp, 0, MD5_LEN); if (!hash_file) { LM_INFO("no hash_file given, disable hash functionality\n"); return init_mi_error(404, MI_SSTR("Functionality disabled")); } else { if (MD5File(tmp, hash_file) != 0) { LM_ERR("could not hash the config file"); return init_mi_error(500, MI_SSTR("Internal error")); } if (strncmp(config_hash, tmp, MD5_LEN) == 0) return init_mi_result_string(MI_SSTR("The actual config file hash " "is identical to the stored one.")); else return init_mi_error(400, MI_SSTR("The actual config file hash is not " "identical to the stored one.")); } }
mi_response_t *mi_set_prob(const mi_params_t *params, struct mi_handler *async_hdl) { int percent; if (get_mi_int_param(params, "prob_proc", &percent) < 0) return init_mi_param_error(); if (percent > 100) { LM_ERR("incorrect probability <%u>\n", percent); return init_mi_error(400, MI_SSTR("Bad parameter value")); } *probability = percent; return init_mi_result_ok(); }
static mi_response_t *cluster_send_mi(const mi_params_t *params, struct mi_handler *async_hdl) { int cluster_id, node_id; int rc; str cmd_name; mi_item_t *cmd_params_arr = NULL; int no_params = 0; if (get_mi_int_param(params, "cluster_id", &cluster_id) < 0) return init_mi_param_error(); if (cluster_id < 1) return init_mi_error(400, MI_SSTR("Bad value for 'cluster_id'")); if (get_mi_int_param(params, "destination", &node_id) < 0) return init_mi_param_error(); if (node_id < 1) return init_mi_error(400, MI_SSTR("Bad value for 'destination'")); if (node_id == current_id) return init_mi_error(400, MI_SSTR("Local node specified as destination")); if (get_mi_string_param(params, "cmd_name", &cmd_name.s, &cmd_name.len) < 0) return init_mi_param_error(); rc = try_get_mi_array_param(params, "cmd_params", &cmd_params_arr, &no_params); if (rc < 0) { cmd_params_arr = NULL; if (rc == -2) return init_mi_param_error(); } rc = send_mi_cmd(cluster_id, node_id, cmd_name, cmd_params_arr, no_params); switch (rc) { case CLUSTERER_SEND_SUCCES: LM_DBG("MI command <%.*s> sent\n", cmd_name.len, cmd_name.s); return init_mi_result_ok(); case CLUSTERER_CURR_DISABLED: LM_INFO("Local node disabled, MI command <%.*s> not sent\n", cmd_name.len, cmd_name.s); return init_mi_result_string(MI_SSTR("Local node disabled")); case CLUSTERER_DEST_DOWN: LM_ERR("Destination down, MI command <%.*s> not sent\n", cmd_name.len, cmd_name.s); return init_mi_error(400, MI_SSTR("Destination down")); case CLUSTERER_SEND_ERR: LM_ERR("Error sending MI command <%.*s>+\n", cmd_name.len, cmd_name.s); return init_mi_error(400, MI_SSTR("Send error")); default: LM_BUG("Bad send error code\n"); return init_mi_error(400, MI_SSTR("Internal error")); } }
static mi_response_t *cluster_bcast_mi(const mi_params_t *params, struct mi_handler *async_hdl) { int cluster_id; int rc; str cmd_name; mi_item_t *cmd_params_arr = NULL; int no_params = 0; if (get_mi_int_param(params, "cluster_id", &cluster_id) < 0) return init_mi_param_error(); if (cluster_id < 1) return init_mi_error(400, MI_SSTR("Bad value for 'cluster_id'")); if (get_mi_string_param(params, "cmd_name", &cmd_name.s, &cmd_name.len) < 0) return init_mi_param_error(); rc = try_get_mi_array_param(params, "cmd_params", &cmd_params_arr, &no_params); if (rc < 0) { cmd_params_arr = NULL; if (rc == -2) return init_mi_param_error(); } rc = send_mi_cmd(cluster_id, 0, cmd_name, cmd_params_arr, no_params); switch (rc) { case CLUSTERER_SEND_SUCCES: LM_DBG("MI command <%.*s> sent\n", cmd_name.len, cmd_name.s); break; case CLUSTERER_CURR_DISABLED: LM_INFO("Local node disabled, MI command <%.*s> not sent\n", cmd_name.len, cmd_name.s); break; case CLUSTERER_DEST_DOWN: LM_ERR("All nodes down, MI command <%.*s> not sent\n", cmd_name.len, cmd_name.s); break; case CLUSTERER_SEND_ERR: LM_ERR("Error sending MI command <%.*s>+\n", cmd_name.len, cmd_name.s); break; } return run_mi_cmd_local(&cmd_name, cmd_params_arr, no_params); }
static mi_response_t *cl_run_mi_cmd(str *cmd_name, mi_item_t *item_params_arr, str *str_params_arr, int no_params) { struct mi_cmd *cmd = NULL; mi_response_t *resp = NULL; mi_request_t req_item; mi_item_t *param_item; int i; str val; memset(&req_item, 0, sizeof req_item); req_item.req_obj = cJSON_CreateObject(); if (!req_item.req_obj) { LM_ERR("Failed to build temporary json request\n"); return NULL; } cmd = lookup_mi_cmd(cmd_name->s, cmd_name->len); if (!cmd) { resp = init_mi_error(400, MI_SSTR("Command to be run not found")); goto out; } if (cmd->flags & MI_ASYNC_RPL_FLAG) { resp = init_mi_error(400, MI_SSTR("Async commands not supported")); goto out; } if (cmd->flags & MI_NAMED_PARAMS_ONLY) { resp = init_mi_error(400, MI_SSTR("Commands requiring named params not supported")); goto out; } if (no_params) { req_item.params = cJSON_CreateArray(); if (!req_item.params) { LM_ERR("Failed to add 'params' to temporary json request\n"); goto out; } cJSON_AddItemToObject(req_item.req_obj, JSONRPC_PARAMS_S, req_item.params); } for (i = 0; i < no_params; i++) { if (item_params_arr) { if (get_mi_arr_param_string(item_params_arr, i, &val.s, &val.len) < 0) { resp = init_mi_param_error(); goto out; } } else { val.s = str_params_arr[i].s; val.len = str_params_arr[i].len; } param_item = cJSON_CreateStr(val.s, val.len); if (!param_item) { LM_ERR("Failed to create string item in temporary json request\n"); goto out; } cJSON_AddItemToArray(req_item.params, param_item); } resp = handle_mi_request(&req_item, cmd, NULL); LM_DBG("got mi response = [%p]\n", resp); out: cJSON_Delete(req_item.req_obj); return resp; }
static mi_response_t *mi_b2b_bridge(const mi_params_t *params, int entity_no, str *prov_media) { str key; b2bl_tuple_t* tuple; str new_dest; b2bl_entity_id_t* entity, *old_entity, *bridging_entity, *prov_entity = 0; struct sip_uri uri; str meth_inv = {INVITE, INVITE_LEN}; str meth_bye = {BYE, BYE_LEN}; unsigned int hash_index, local_index; str ok= str_init("ok"); b2b_req_data_t req_data; b2b_rpl_data_t rpl_data; int ret; if (get_mi_string_param(params, "dialog_id", &key.s, &key.len) < 0) return init_mi_param_error(); if (get_mi_string_param(params, "new_uri", &new_dest.s, &new_dest.len) < 0) return init_mi_param_error(); if(parse_uri(new_dest.s, new_dest.len, &uri)< 0) { LM_ERR("Bad argument. Not a valid uri [%.*s]\n", new_dest.len, new_dest.s); return init_mi_error(404, MI_SSTR("Invalid uri for the new destination")); } /* if 'flag' parameter is 1 - > * means that destination from the current call must be * bridged to the new destination */ if (entity_no != 0 && entity_no != 1) return init_mi_error(404, MI_SSTR("Invalid 'flag' parameter")); if (prov_media) { /* parse new uri */ if(parse_uri(prov_media->s, prov_media->len, &uri)< 0) { LM_ERR("Bad argument. Not a valid provisional media uri [%.*s]\n", new_dest.len, new_dest.s); return init_mi_error(404, MI_SSTR("Bad 'prov_media_uri' parameter")); } prov_entity = b2bl_create_new_entity(B2B_CLIENT, 0, prov_media, 0, 0, 0, 0, 0); if (!prov_entity) { LM_ERR("Failed to create new b2b entity\n"); goto free; } } ret = b2bl_get_tuple_key(&key, &hash_index, &local_index); if(ret < 0) { if (ret == -1) LM_ERR("Failed to parse key or find an entity [%.*s]\n", key.len, key.s); else LM_ERR("Could not find entity [%.*s]\n", key.len, key.s); goto free; } entity = b2bl_create_new_entity(B2B_CLIENT, 0, &new_dest, 0, 0, 0, 0, 0); if(entity == NULL) { LM_ERR("Failed to create new b2b entity\n"); goto free; } lock_get(&b2bl_htable[hash_index].lock); tuple = b2bl_search_tuple_safe(hash_index, local_index); if(tuple == NULL) { LM_ERR("No entity found\n"); goto error; } if (!tuple->bridge_entities[entity_no] || tuple->bridge_entities[entity_no]->disconnected) { LM_ERR("Can not bridge requested entity [%p]\n", tuple->bridge_entities[entity_no]); goto error; } bridging_entity = tuple->bridge_entities[entity_no]; old_entity = tuple->bridge_entities[(entity_no?0:1)]; if(old_entity == NULL || bridging_entity == NULL) { LM_ERR("Wrong dialog id\n"); goto error; } if(old_entity->next || old_entity->prev) { LM_ERR("Can not disconnect entity [%p]\n", old_entity); b2bl_print_tuple(tuple, L_ERR); goto error; } if(bridging_entity->state != B2BL_ENT_CONFIRMED) { LM_ERR("Wrong state for entity ek= [%.*s], tk=[%.*s]\n", bridging_entity->key.len,bridging_entity->key.s, tuple->key->len, tuple->key->s); goto error; } b2bl_print_tuple(tuple, L_DBG); /* send BYE to old client */ if(old_entity->disconnected) { memset(&rpl_data, 0, sizeof(b2b_rpl_data_t)); PREP_RPL_DATA(old_entity); rpl_data.method =METHOD_BYE; rpl_data.code =200; rpl_data.text =&ok; b2b_api.send_reply(&rpl_data); } else { old_entity->disconnected = 1; memset(&req_data, 0, sizeof(b2b_req_data_t)); PREP_REQ_DATA(old_entity); req_data.method =&meth_bye; b2b_api.send_request(&req_data); } if (0 == b2bl_drop_entity(old_entity, tuple)) { LM_ERR("Inconsistent tuple [%p]\n", tuple); b2bl_print_tuple(tuple, L_ERR); goto error; } if (old_entity->peer->peer == old_entity) old_entity->peer->peer = NULL; else { LM_ERR("Unexpected chain: old_entity=[%p] and old_entity->peer->peer=[%p]\n", old_entity, old_entity->peer->peer); goto error; } old_entity->peer = NULL; tuple->bridge_entities[0]= bridging_entity; if (prov_entity) { tuple->bridge_entities[1]= prov_entity; tuple->bridge_entities[2]= entity; /* we don't have to free it anymore */ prov_entity = 0; } else { tuple->bridge_entities[1]= entity; bridging_entity->peer = entity; entity->peer = bridging_entity; } tuple->scenario_state = B2B_BRIDGING_STATE; bridging_entity->state = 0; bridging_entity->sdp_type = B2BL_SDP_LATE; memset(&req_data, 0, sizeof(b2b_req_data_t)); PREP_REQ_DATA(bridging_entity); req_data.method =&meth_inv; b2b_api.send_request(&req_data); lock_release(&b2bl_htable[hash_index].lock); return init_mi_result_ok(); error: if(tuple) b2b_mark_todel(tuple); lock_release(&b2bl_htable[hash_index].lock); free: if (prov_entity) shm_free(prov_entity); return 0; }