static struct mi_root* mi_reg_list(struct mi_root* cmd, void* param) { struct mi_root *rpl_tree; struct mi_node *rpl=NULL, *node, *node1; struct mi_attr* attr; reg_record_t *rec; int i, len; char* p; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==NULL) return NULL; rpl = &rpl_tree->node; for(i = 0; i< reg_hsize; i++) { lock_get(®_htable[i].lock); rec = reg_htable[i].first; while (rec) { node = add_mi_node_child(rpl, MI_DUP_VALUE, "AOR", 3, rec->td.rem_uri.s, rec->td.rem_uri.len); if(node == NULL) goto error; p = int2str(rec->state, &len); attr = add_mi_attr(node, MI_DUP_VALUE, "state", 5, p, len); if(attr == NULL) goto error; p = int2str(rec->expires, &len); attr = add_mi_attr(node, MI_DUP_VALUE, "expires", 7, p, len); if(attr == NULL) goto error; p = int2str((unsigned int)rec->last_register_sent, &len); attr = add_mi_attr(node, MI_DUP_VALUE, "last_register_sent", 18, p, len); if(attr == NULL) goto error; p = int2str((unsigned int)rec->registration_timeout, &len); attr = add_mi_attr(node, MI_DUP_VALUE, "registration_timeout", 20, p, len); if(attr == NULL) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "registrar", 9, rec->td.rem_target.s, rec->td.rem_target.len); if(node1 == NULL) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "binding", 7, rec->contact_uri.s, rec->contact_uri.len); if(node1 == NULL) goto error; if(rec->td.loc_uri.s != rec->td.rem_uri.s) { node1 = add_mi_node_child(node, MI_DUP_VALUE, "third_party_registrant", 12, rec->td.loc_uri.s, rec->td.loc_uri.len); if(node1 == NULL) goto error; } if (rec->td.obp.s && rec->td.obp.len) { node1 = add_mi_node_child(node, MI_DUP_VALUE, "proxy", 5, rec->td.obp.s, rec->td.obp.len); if(node1 == NULL) goto error; } rec = rec->next; } lock_release(®_htable[i].lock); } return rpl_tree; error: lock_release(®_htable[i].lock); LM_ERR("Unable to create reply\n"); free_mi_tree(rpl_tree); return NULL; }
struct mi_root *siplua_mi_bla(struct mi_root *cmd_tree, void *param) { return init_mi_tree(200, MI_OK_S, MI_OK_LEN); }
struct mi_root *ws_mi_enable(struct mi_root *cmd, void *param) { cfg_get(websocket, ws_cfg, enabled) = 1; LM_WARN("enabling websockets\n"); return init_mi_tree(200, MI_OK_S, MI_OK_LEN); }
struct mi_root* mi_get_pipes(struct mi_root* cmd_tree, void* param) { struct mi_root *rpl_tree; struct mi_node *node=NULL, *rpl=NULL; struct mi_attr* attr; str algo; char* p; int i, len; pl_pipe_t *it; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; for(i=0; i<_pl_pipes_ht->htsize; i++) { lock_get(&_pl_pipes_ht->slots[i].lock); it = _pl_pipes_ht->slots[i].first; while(it) { if (it->algo != PIPE_ALGO_NOP) { node = add_mi_node_child(rpl, 0, "PIPE", 4, 0, 0); if(node == NULL) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } attr = add_mi_attr(node, MI_DUP_VALUE, "id" , 2, it->name.s, it->name.len); if(attr == NULL) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } if (str_map_int(algo_names, it->algo, &algo)) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } attr = add_mi_attr(node, 0, "algorithm", 9, algo.s, algo.len); if(attr == NULL) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } p = int2str((unsigned long)(it->limit), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "limit", 5, p, len); if(attr == NULL) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } p = int2str((unsigned long)(it->counter), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "counter", 7, p, len); if(attr == NULL) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } } it = it->next; } lock_release(&_pl_pipes_ht->slots[i].lock); } return rpl_tree; error: LM_ERR("Unable to create reply\n"); free_mi_tree(rpl_tree); return 0; }
struct mi_root *ws_mi_dump(struct mi_root *cmd, void *param) { int h, connections = 0, truncated = 0, order = 0, found = 0; ws_connection_t *wsc; struct mi_node *node = NULL; struct mi_root *rpl_tree; node = cmd->node.kids; if (node != NULL) { if (node->value.s == NULL || node->value.len == 0) { LM_WARN("empty display order parameter\n"); return init_mi_tree(400, str_status_empty_param.s, str_status_empty_param.len); } strlower(&node->value); if (strncmp(node->value.s, "id_hash", 7) == 0) order = 0; else if (strncmp(node->value.s, "used_desc", 9) == 0) order = 1; else if (strncmp(node->value.s, "used_asc", 8) == 0) order = 2; else { LM_WARN("bad display order parameter\n"); return init_mi_tree(400, str_status_bad_param.s, str_status_bad_param.len); } if (node->next != NULL) { LM_WARN("too many parameters\n"); return init_mi_tree(400, str_status_too_many_params.s, str_status_too_many_params.len); } } rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if (rpl_tree == NULL) return 0; WSCONN_LOCK; if (order == 0) { for (h = 0; h < TCP_ID_HASH_SIZE; h++) { wsc = wsconn_id_hash[h]; while(wsc) { if ((found = add_node(rpl_tree, wsc)) < 0) { free_mi_tree(rpl_tree); return 0; } connections += found; if (connections >= MAX_WS_CONNS_DUMP) { truncated = 1; break; } wsc = wsc->id_next; } if (truncated == 1) break; } } else if (order == 1) { wsc = wsconn_used_list->head; while (wsc) { if ((found = add_node(rpl_tree, wsc)) < 0) { free_mi_tree(rpl_tree); return 0; } connections += found; if (connections >= MAX_WS_CONNS_DUMP) { truncated = 1; break; } wsc = wsc->used_next; } } else { wsc = wsconn_used_list->tail; while (wsc) { if ((found = add_node(rpl_tree, wsc)) < 0) { free_mi_tree(rpl_tree); return 0; } connections += found; if (connections >= MAX_WS_CONNS_DUMP) { truncated = 1; break; } wsc = wsc->used_prev; } } WSCONN_UNLOCK; if (addf_mi_node_child(&rpl_tree->node, 0, 0, 0, "%d WebSocket connection%s found%s", connections, connections == 1 ? "" : "s", truncated == 1 ? "(truncated)" : "") == 0) { free_mi_tree(rpl_tree); return 0; } return rpl_tree; }
/*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); }
static struct mi_root* mi_sca_list(struct mi_root* cmd, void* param) { int i, index; struct mi_root *rpl_tree; struct mi_node *node=NULL, *node1=NULL, *rpl=NULL; struct mi_attr* attr; b2b_sca_record_t *rec; b2b_sca_call_t *call; str_lst_t *watcher; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==NULL) return NULL; rpl = &rpl_tree->node; rpl->flags |= MI_IS_ARRAY; for(index = 0; index<b2b_sca_hsize; index++) { lock_get(&b2b_sca_htable[index].lock); rec = b2b_sca_htable[index].first; while(rec) { node = add_mi_node_child(rpl, MI_IS_ARRAY|MI_DUP_VALUE, "shared_line", 11,rec->shared_line.s, rec->shared_line.len); if(node == NULL) goto error; watcher = rec->watchers; while (watcher) { attr = add_mi_attr(node, MI_DUP_VALUE, "watcher", 7, watcher->watcher.s, watcher->watcher.len); if(attr == NULL) goto error; watcher = watcher->next; } for (i=0; i<MAX_APPEARANCE_INDEX; i++) { if (rec->call[i]) { call = rec->call[i]; node1 = add_mi_node_child(node, MI_DUP_VALUE, "appearance", 10, call->appearance_index_str.s, call->appearance_index_str.len); if(node1 == NULL) goto error; attr = add_mi_attr(node1, MI_DUP_VALUE, "state", 5, app_state[call->call_state].s, app_state[call->call_state].len); if(attr == NULL) goto error; attr = add_mi_attr(node1, MI_DUP_VALUE, "b2b_key", 7, call->b2bl_key.s, call->b2bl_key.len); if(attr == NULL) goto error; attr = add_mi_attr(node1, MI_DUP_VALUE, "app_uri", 7, call->call_info_apperance_uri.s, call->call_info_apperance_uri.len); if(attr == NULL) goto error; } } rec = rec->next; } lock_release(&b2b_sca_htable[index].lock); } return rpl_tree; error: lock_release(&b2b_sca_htable[index].lock); LM_ERR("Unable to create reply\n"); free_mi_tree(rpl_tree); return NULL; }
struct mi_root* mi_pua_subscribe(struct mi_root* cmd, void* param) { int exp= 0; str pres_uri, watcher_uri, expires; struct mi_node* node= NULL; struct mi_root* rpl= NULL; struct sip_uri uri; subs_info_t subs; int sign= 1; str event; node = cmd->node.kids; if(node == NULL) return 0; pres_uri= node->value; if(pres_uri.s == NULL || pres_uri.len== 0) { return init_mi_tree(400, "Bad uri", 7); } if(parse_uri(pres_uri.s, pres_uri.len, &uri)<0 ) { LM_ERR("bad uri\n"); return init_mi_tree(400, "Bad uri", 7); } node = node->next; if(node == NULL) return 0; watcher_uri= node->value; if(watcher_uri.s == NULL || watcher_uri.len== 0) { return init_mi_tree(400, "Bad uri", 7); } if(parse_uri(watcher_uri.s, watcher_uri.len, &uri)<0 ) { LM_ERR("bad uri\n"); return init_mi_tree(400, "Bad uri", 7); } /* Get event */ node = node->next; if(node == NULL) return 0; event= node->value; if(event.s== NULL || event.len== 0) { LM_ERR("empty event parameter\n"); return init_mi_tree(400, "Empty event parameter", 21); } LM_DBG("event '%.*s'\n", event.len, event.s); node = node->next; if(node == NULL || node->next!=NULL) { LM_ERR("Too much or too many parameters\n"); return 0; } expires= node->value; if(expires.s== NULL || expires.len== 0) { LM_ERR("Bad expires parameter\n"); return init_mi_tree(400, "Bad expires", 11); } if(expires.s[0]== '-') { sign= -1; expires.s++; expires.len--; } if( str2int(&expires, (unsigned int*) &exp)< 0) { LM_ERR("invalid expires parameter\n" ); goto error; } exp= exp* sign; LM_DBG("expires '%d'\n", exp); memset(&subs, 0, sizeof(subs_info_t)); subs.pres_uri= &pres_uri; subs.watcher_uri= &watcher_uri; subs.contact= &watcher_uri; subs.expires= exp; subs.source_flag |= MI_SUBSCRIBE; subs.event= get_event_flag(&event); if(subs.event< 0) { LM_ERR("unknown event\n"); return init_mi_tree(400, "Unknown event", 13); } if(pua_send_subscribe(&subs)< 0) { LM_ERR("while sending subscribe\n"); goto error; } rpl= init_mi_tree(202, "accepted", 8); if(rpl == NULL) return 0; return rpl; error: return 0; }
struct mi_root* mi_pua_publish(struct mi_root* cmd, void* param) { int exp; struct mi_node* node= NULL; str pres_uri, expires; str body= {0, 0}; struct sip_uri uri; publ_info_t publ; str event; str content_type; str id; str etag; str outbound_proxy; str extra_headers; int result; int sign= 1; LM_DBG("start\n"); node = cmd->node.kids; if(node == NULL) return 0; /* Get presentity URI */ pres_uri = node->value; if(pres_uri.s == NULL || pres_uri.s== 0) { LM_ERR("empty uri\n"); return init_mi_tree(404, "Empty presentity URI", 20); } if(parse_uri(pres_uri.s, pres_uri.len, &uri)<0 ) { LM_ERR("bad uri\n"); return init_mi_tree(404, "Bad presentity URI", 18); } LM_DBG("pres_uri '%.*s'\n", pres_uri.len, pres_uri.s); node = node->next; if(node == NULL) return 0; /* Get expires */ expires= node->value; if(expires.s== NULL || expires.len== 0) { LM_ERR("empty expires parameter\n"); return init_mi_tree(400, "Empty expires parameter", 23); } if(expires.s[0]== '-') { sign= -1; expires.s++; expires.len--; } if( str2int(&expires, (unsigned int*) &exp)< 0) { LM_ERR("invalid expires parameter\n" ); goto error; } exp= exp* sign; LM_DBG("expires '%d'\n", exp); node = node->next; if(node == NULL) return 0; /* Get event */ event= node->value; if(event.s== NULL || event.len== 0) { LM_ERR("empty event parameter\n"); return init_mi_tree(400, "Empty event parameter", 21); } LM_DBG("event '%.*s'\n", event.len, event.s); node = node->next; if(node == NULL) return 0; /* Get content type */ content_type= node->value; if(content_type.s== NULL || content_type.len== 0) { LM_ERR("empty content type\n"); return init_mi_tree(400, "Empty content type parameter", 28); } LM_DBG("content type '%.*s'\n", content_type.len, content_type.s); node = node->next; if(node == NULL) return 0; /* Get id */ id= node->value; if(id.s== NULL || id.len== 0) { LM_ERR("empty id parameter\n"); return init_mi_tree(400, "Empty id parameter", 20); } LM_DBG("id '%.*s'\n", id.len, id.s); node = node->next; if(node == NULL) return 0; /* Get etag */ etag= node->value; if(etag.s== NULL || etag.len== 0) { LM_ERR("empty etag parameter\n"); return init_mi_tree(400, "Empty etag parameter", 20); } LM_DBG("etag '%.*s'\n", etag.len, etag.s); node = node->next; if(node == NULL) return 0; /* Get outbound_proxy */ if (publish_with_ob_proxy) { outbound_proxy = node->value; if(outbound_proxy.s== NULL || outbound_proxy.len== 0) { LM_ERR("empty outbound proxy parameter\n"); return init_mi_tree(400, "Empty outbound proxy", 20); } LM_DBG("outbound_proxy '%.*s'\n", outbound_proxy.len, outbound_proxy.s); node = node->next; if(node == NULL) return 0; } /* Get extra_headers */ extra_headers = node->value; if(extra_headers.s== NULL || extra_headers.len== 0) { LM_ERR("empty extra_headers parameter\n"); return init_mi_tree(400, "Empty extra_headers", 19); } LM_DBG("extra_headers '%.*s'\n", extra_headers.len, extra_headers.s); node = node->next; /* Get body */ if(node == NULL ) { body.s= NULL; body.len= 0; } else { if(node->next!=NULL) return init_mi_tree(400, "Too many parameters", 19); body= node->value; if(body.s == NULL || body.s== 0) { LM_ERR("empty body parameter\n"); return init_mi_tree(400, "Empty body parameter", 20); } } LM_DBG("body '%.*s'\n", body.len, body.s); /* Check that body is NULL if content type is . */ if(body.s== NULL && (content_type.len!= 1 || content_type.s[0]!= '.')) { LM_ERR("body is missing, but content type is not .\n"); return init_mi_tree(400, "Body parameter is missing", 25); } /* Create the publ_info_t structure */ memset(&publ, 0, sizeof(publ_info_t)); publ.pres_uri= &pres_uri; if(body.s) { publ.body= &body; } publ.event= get_event_flag(&event); if(publ.event< 0) { LM_ERR("unknown event\n"); return init_mi_tree(400, "Unknown event", 13); } if(content_type.len!= 1) { publ.content_type= content_type; } if(! (id.len== 1 && id.s[0]== '.')) { publ.id= id; } if(! (etag.len== 1 && etag.s[0]== '.')) { publ.etag= &etag; } publ.expires= exp; if (publish_with_ob_proxy) { if (!((outbound_proxy.len == 1) && (outbound_proxy.s[0] == '.'))) publ.outbound_proxy = &outbound_proxy; } if (!(extra_headers.len == 1 && extra_headers.s[0] == '.')) { publ.extra_headers = &extra_headers; } if (!(etag.len== 1 && etag.s[0]== '.')) { publ.etag= &etag; } publ.expires= exp; if (cmd->async_hdl!=NULL) { publ.source_flag= MI_ASYN_PUBLISH; publ.cb_param= (void*)cmd->async_hdl; } else publ.source_flag|= MI_PUBLISH; LM_DBG("send publish\n"); result= pua_send_publish(&publ); if(result< 0) { LM_ERR("sending publish failed\n"); return init_mi_tree(500, "MI/PUBLISH failed", 17); } if(result== 418) return init_mi_tree(418, "Wrong ETag", 10); if (cmd->async_hdl==NULL) return init_mi_tree( 202, "Accepted", 8); else return MI_ROOT_ASYNC_RPL; error: return 0; }
struct mi_root* mi_cpl_load(struct mi_root *cmd_tree, void *param) { struct mi_root *rpl_tree; struct mi_node *cmd; struct sip_uri uri; str xml = {0,0}; str bin = {0,0}; str enc_log = {0,0}; str val; char *file; LM_DBG("\"LOAD_CPL\" MI command received!\n"); cmd = &cmd_tree->node; /* check user+host */ if((cmd->kids==NULL) ||(cmd->kids->next==NULL) || (cmd->kids->next->next)) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); val = cmd->kids->value; if (parse_uri( val.s, val.len, &uri)!=0){ LM_ERR("invalid sip URI [%.*s]\n", val.len, val.s); return init_mi_tree( 400, USRHOST_ERR_S, USRHOST_ERR_LEN ); } LM_DBG("user@host=%.*s@%.*s\n", uri.user.len,uri.user.s,uri.host.len,uri.host.s); /* second argument is the cpl file */ val = cmd->kids->next->value; file = pkg_malloc(val.len+1); if (file==NULL) { LM_ERR("no more pkg mem\n"); return 0; } memcpy( file, val.s, val.len); file[val.len]= '\0'; /* load the xml file - this function will allocated a buff for the loading * the cpl file and attach it to xml.s -> don't forget to free it! */ if (load_file( file, &xml)!=1) { pkg_free(file); return init_mi_tree( 500, FILE_LOAD_ERR_S, FILE_LOAD_ERR_LEN ); } LM_DBG("cpl file=%s loaded\n",file); pkg_free(file); /* get the binary coding for the XML file */ if (encodeCPL( &xml, &bin, &enc_log)!=1) { rpl_tree = init_mi_tree( 500, CPLFILE_ERR_S, CPLFILE_ERR_LEN ); goto error; } /* write both the XML and binary formats into database */ if (write_to_db( &uri.user,cpl_env.use_domain?&uri.host:0, &xml, &bin)!=1){ rpl_tree = init_mi_tree( 500, DB_SAVE_ERR_S, DB_SAVE_ERR_LEN ); goto error; } /* everything was OK */ rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); error: if (rpl_tree && enc_log.len) add_mi_node_child(&rpl_tree->node,MI_DUP_VALUE,"Log",3,enc_log.s,enc_log.len); if (enc_log.s) pkg_free ( enc_log.s ); if (xml.s) pkg_free ( xml.s ); return rpl_tree; }
int mi_publ_rpl_cback( ua_pres_t* hentity, struct sip_msg* reply) { struct mi_root *rpl_tree= NULL; struct mi_handler* mi_hdl= NULL; struct hdr_field* hdr= NULL; int statuscode; int lexpire; int found; str etag; str reason= {0, 0}; if(reply== NULL || hentity== NULL || hentity->cb_param== NULL) { LM_ERR("NULL parameter\n"); return -1; } if(reply== FAKED_REPLY) { statuscode= 408; reason.s= "Request Timeout"; reason.len= strlen(reason.s); } else { statuscode= reply->first_line.u.reply.statuscode; reason= reply->first_line.u.reply.reason; } mi_hdl = (struct mi_handler *)(hentity->cb_param); rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) goto done; addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "%d %.*s", statuscode, reason.len, reason.s); if(statuscode== 200) { /* extract ETag and expires */ lexpire = ((exp_body_t*)reply->expires->parsed)->val; LM_DBG("lexpire= %d\n", lexpire); hdr = reply->headers; found = 0; while (hdr!= NULL) { if(cmp_hdrname_strzn(&hdr->name, "SIP-ETag",8)==0) { found = 1; break; } hdr = hdr->next; } if(found== 0) /* must find SIP-Etag header field in 200 OK msg*/ { LM_ERR("SIP-ETag header field not found\n"); goto error; } etag= hdr->body; addf_mi_node_child( &rpl_tree->node, 0, "ETag", 4, "%.*s", etag.len, etag.s); addf_mi_node_child( &rpl_tree->node, 0, "Expires", 7, "%d", lexpire); } done: if ( statuscode >= 200) { mi_hdl->handler_f( rpl_tree, mi_hdl, 1); } else { mi_hdl->handler_f( rpl_tree, mi_hdl, 0 ); } return 0; error: return -1; }
struct mi_root* pdt_mi_list(struct mi_root* cmd_tree, void* param) { str sd, sp, sdomain; pdt_tree_t *pt; struct mi_node* node = NULL; unsigned int i= 0; struct mi_root* rpl_tree = NULL; struct mi_node* rpl = NULL; static char code_buf[PDT_MAX_DEPTH+1]; int len; if(_ptree==NULL) { LM_ERR("empty domain list\n"); return init_mi_tree( 500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN); } /* read sdomain */ sdomain.s = 0; sdomain.len = 0; sp.s = 0; sp.len = 0; sd.s = 0; sd.len = 0; node = cmd_tree->node.kids; if(node != NULL) { sdomain = node->value; if(sdomain.s == NULL || sdomain.len== 0) return init_mi_tree( 404, "domain not found", 16); if(*sdomain.s=='.') sdomain.s = 0; /* read prefix */ node = node->next; if(node != NULL) { sp= node->value; if(sp.s== NULL || sp.len==0 || *sp.s=='.') sp.s = NULL; else { while(sp.s!=NULL && i!=sp.len) { if(strpos(pdt_char_list.s,sp.s[i]) < 0) { LM_ERR("bad prefix [%.*s]\n", sp.len, sp.s); return init_mi_tree( 400, "bad prefix", 10); } i++; } } /* read domain */ node= node->next; if(node != NULL) { sd= node->value; if(sd.s== NULL || sd.len==0 || *sd.s=='.') sd.s = NULL; } } } rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) return 0; rpl = &rpl_tree->node; rpl->flags |= MI_IS_ARRAY; if(*_ptree==0) return rpl_tree; pt = *_ptree; while(pt!=NULL) { if(sdomain.s==NULL || (sdomain.s!=NULL && pt->sdomain.len>=sdomain.len && strncmp(pt->sdomain.s, sdomain.s, sdomain.len)==0)) { len = 0; if(pdt_print_mi_node(pt->head, rpl, code_buf, len, &pt->sdomain, &sd, &sp)<0) goto error; } pt = pt->next; } return rpl_tree; error: free_mi_tree(rpl_tree); return 0; }
/** * "pdt_delete" syntax: * sdomain * domain */ struct mi_root* pdt_mi_delete(struct mi_root* cmd_tree, void* param) { str sd, sdomain; struct mi_node* node= NULL; db_key_t db_keys[2] = {&sdomain_column, &domain_column}; db_val_t db_vals[2]; db_op_t db_ops[2] = {OP_EQ, OP_EQ}; /* read sdomain */ node = cmd_tree->node.kids; if(node == NULL) goto error; sdomain = node->value; if(sdomain.s == NULL || sdomain.len== 0) return init_mi_tree( 404, "domain not found", 16); if( *sdomain.s=='.' ) return init_mi_tree( 400, "400 empty param",11); /* read domain */ node= node->next; if(node == NULL || node->next!=NULL) goto error; sd= node->value; if(sd.s== NULL || sd.len==0) { LM_ERR("could not read domain\n"); return init_mi_tree(404, "domain not found", 16); } if(*sd.s=='.') return init_mi_tree( 400, "empty param", 11); db_vals[0].type = DB_STR; db_vals[0].nul = 0; db_vals[0].val.str_val.s = sdomain.s; db_vals[0].val.str_val.len = sdomain.len; db_vals[1].type = DB_STR; db_vals[1].nul = 0; db_vals[1].val.str_val.s = sd.s; db_vals[1].val.str_val.len = sd.len; if(pdt_dbf.delete(db_con, db_keys, db_ops, db_vals, 2)<0) { LM_ERR("database/cache are inconsistent\n"); return init_mi_tree( 500, "database/cache are inconsistent", 31 ); } /* re-loading all information from database */ if(pdt_load_db()!=0) { LM_ERR("cannot re-load info from database\n"); return init_mi_tree( 500, "cannot reload", 13 ); } LM_DBG("prefix for sdomain [%.*s] domain [%.*s] " "removed\n", sdomain.len, sdomain.s, sd.len, sd.s); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); error: return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); }
/** * "pdt_add" syntax : * sdomain * prefix * domain */ struct mi_root* pdt_mi_add(struct mi_root* cmd_tree, void* param) { db_key_t db_keys[NR_KEYS] = {&sdomain_column, &prefix_column, &domain_column}; db_val_t db_vals[NR_KEYS]; db_op_t db_ops[NR_KEYS] = {OP_EQ, OP_EQ}; int i= 0; str sd, sp, sdomain; struct mi_node* node= NULL; if(_ptree==NULL) { LM_ERR("strange situation\n"); return init_mi_tree( 500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN); } /* read sdomain */ node = cmd_tree->node.kids; if(node == NULL) goto error1; sdomain = node->value; if(sdomain.s == NULL || sdomain.len== 0) return init_mi_tree( 404, "domain not found", 16); if(*sdomain.s=='.' ) return init_mi_tree( 400, "empty param",11); /* read prefix */ node = node->next; if(node == NULL) goto error1; sp= node->value; if(sp.s== NULL || sp.len==0) { LM_ERR("could not read prefix\n"); return init_mi_tree( 404, "prefix not found", 16); } if(*sp.s=='.') return init_mi_tree(400, "empty param", 11); while(i< sp.len) { if(strpos(pdt_char_list.s,sp.s[i]) < 0) return init_mi_tree(400, "bad prefix", 10); i++; } /* read domain */ node= node->next; if(node == NULL || node->next!=NULL) goto error1; sd= node->value; if(sd.s== NULL || sd.len==0) { LM_ERR("could not read domain\n"); return init_mi_tree( 400, "domain not found", 16); } if(*sd.s=='.') return init_mi_tree(400, "empty param", 11); if(pdt_check_domain!=0 && *_ptree!=NULL && pdt_check_pd(*_ptree, &sdomain, &sp, &sd)==1) { LM_ERR("(sdomain,prefix,domain) exists\n"); return init_mi_tree(400, "(sdomain,prefix,domain) exists already", 38); } db_vals[0].type = DB_STR; db_vals[0].nul = 0; db_vals[0].val.str_val.s = sdomain.s; db_vals[0].val.str_val.len = sdomain.len; db_vals[1].type = DB_STR; db_vals[1].nul = 0; db_vals[1].val.str_val.s = sp.s; db_vals[1].val.str_val.len = sp.len; db_vals[2].type = DB_STR; db_vals[2].nul = 0; db_vals[2].val.str_val.s = sd.s; db_vals[2].val.str_val.len = sd.len; /* insert a new domain into database */ if(pdt_dbf.insert(db_con, db_keys, db_vals, NR_KEYS)<0) { LM_ERR("failed to store new prefix/domain\n"); return init_mi_tree( 500,"Cannot store prefix/domain", 26); } /* re-loading all information from database */ if(pdt_load_db()!=0) { LM_ERR("cannot re-load info from database\n"); goto error; } LM_DBG("new prefix added %.*s-%.*s => %.*s\n", sdomain.len, sdomain.s, sp.len, sp.s, sd.len, sd.s); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); error: if(pdt_dbf.delete(db_con, db_keys, db_ops, db_vals, NR_KEYS)<0) LM_ERR("database/cache are inconsistent\n"); return init_mi_tree( 500, "could not add to cache", 23 ); error1: return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); }
/* * Expects 7 nodes: * table name, * AOR * contact * expires * Q * useless - backward compat. * flags * cflags * methods */ struct mi_root* mi_usrloc_add(struct mi_root *cmd, void *param) { ucontact_info_t ci; urecord_t* r; ucontact_t* c; struct mi_node *node; udomain_t *dom; str *aor; str *contact; unsigned int ui_val; int n; for( n=0,node = cmd->node.kids; n<9 && node ; n++,node=node->next ); if (n!=9 || node!=0) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); node = cmd->node.kids; /* look for table (param 1) */ dom = mi_find_domain( &node->value ); if (dom==NULL) return init_mi_tree( 404, "Table not found", 15); /* process the aor (param 2) */ node = node->next; aor = &node->value; if ( mi_fix_aor(aor)!=0 ) return init_mi_tree( 400, "Domain missing in AOR", 21); /* contact (param 3) */ node = node->next; contact = &node->value; memset( &ci, 0, sizeof(ucontact_info_t)); /* expire (param 4) */ node = node->next; if (str2int( &node->value, &ui_val) < 0) goto bad_syntax; ci.expires = ui_val; /* q value (param 5) */ node = node->next; if (str2q( &ci.q, node->value.s, node->value.len) < 0) goto bad_syntax; /* unused value (param 6) FIXME */ node = node->next; /* flags value (param 7) */ node = node->next; if (str2int( &node->value, (unsigned int*)&ci.flags) < 0) goto bad_syntax; /* branch flags value (param 8) */ node = node->next; if (str2int( &node->value, (unsigned int*)&ci.cflags) < 0) goto bad_syntax; /* methods value (param 9) */ node = node->next; if (str2int( &node->value, (unsigned int*)&ci.methods) < 0) goto bad_syntax; lock_udomain( dom, aor); n = get_urecord( dom, aor, &r); if ( n==1) { if (insert_urecord( dom, aor, &r) < 0) goto lock_error; c = 0; } else { if (get_ucontact( r, contact, &mi_ul_cid, MI_UL_CSEQ+1, &c) < 0) goto lock_error; } get_act_time(); ci.callid = &mi_ul_cid; ci.user_agent = &mi_ul_ua; ci.cseq = MI_UL_CSEQ; /* 0 expires means permanent contact */ if (ci.expires!=0) ci.expires += act_time; if (c) { if (update_ucontact( r, c, &ci) < 0) goto release_error; } else { if ( insert_ucontact( r, contact, &ci, &c) < 0 ) goto release_error; } release_urecord(r); unlock_udomain( dom, aor); 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); release_error: release_urecord(r); lock_error: unlock_udomain( dom, aor); return init_mi_tree( 500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN); }
static struct mi_root *mq_mi_get_size(struct mi_root *cmd_tree, void *param) { static struct mi_node *node = NULL, *rpl = NULL; static struct mi_root *rpl_tree = NULL; static struct mi_attr *attr = NULL; str mqueue_name; int mqueue_sz = 0; char *p = NULL; int len = 0; if((node = cmd_tree->node.kids) == NULL) { return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); } mqueue_name = node->value; if(mqueue_name.len <= 0 || mqueue_name.s == NULL) { LM_ERR("bad mqueue name\n"); return init_mi_tree(500, MI_SSTR("bad mqueue name")); } mqueue_sz = _mq_get_csize(&mqueue_name); if(mqueue_sz < 0) { LM_ERR("no such mqueue\n"); return init_mi_tree(404, MI_SSTR("no such mqueue")); } rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) return 0; rpl = &rpl_tree->node; node = add_mi_node_child(rpl, MI_DUP_VALUE, "mqueue", strlen("mqueue"), NULL, 0); if(node == NULL) { free_mi_tree(rpl_tree); return NULL; } attr = add_mi_attr(node, MI_DUP_VALUE, "name", strlen("name"), mqueue_name.s, mqueue_name.len); if(attr == NULL) goto error; p = int2str((unsigned long) mqueue_sz, &len); attr = add_mi_attr(node, MI_DUP_VALUE, "size", strlen("size"), p, len); if(attr == NULL) goto error; return rpl_tree; error: free_mi_tree(rpl_tree); return NULL; }
/* * Expects 2 nodes: the table name and the AOR */ struct mi_root* mi_usrloc_show_contact(struct mi_root *cmd, void *param) { struct mi_root *rpl_tree; struct mi_node *rpl; struct mi_node *node; udomain_t *dom; urecord_t *rec; ucontact_t* con; str *aor; int ret; node = cmd->node.kids; if (node==NULL || node->next==NULL || node->next->next!=NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); /* look for table */ dom = mi_find_domain( &node->value ); if (dom==NULL) return init_mi_tree( 404, "Table not found", 15); /* process the aor */ aor = &node->next->value; if ( mi_fix_aor(aor)!=0 ) return init_mi_tree( 400, "Domain missing in AOR", 21); lock_udomain( dom, aor); ret = get_urecord( dom, aor, &rec); if (ret == 1) { unlock_udomain( dom, aor); return init_mi_tree( 404, "AOR not found", 13); } get_act_time(); rpl_tree = 0; rpl = 0; for( con=rec->contacts ; con ; con=con->next) { if (VALID_CONTACT( con, act_time)) { if (rpl_tree==0) { rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) goto error; rpl = &rpl_tree->node; } node = addf_mi_node_child( rpl, 0, "Contact", 7, "<%.*s>;q=%s;expires=%d;flags=0x%X;cflags=0x%X;socket=<%.*s>;" "methods=0x%X" "%s%.*s%s" /*received*/ "%s%.*s%s" /*user-agent*/ "%s%.*s%s", /*path*/ con->c.len, ZSW(con->c.s), q2str(con->q, 0), (int)(con->expires - act_time), con->flags, con->cflags, con->sock?con->sock->sock_str.len:3, con->sock?con->sock->sock_str.s:"NULL", con->methods, con->received.len?";received=<":"",con->received.len, ZSW(con->received.s), con->received.len?">":"", con->user_agent.len?";user_agent=<":"",con->user_agent.len, ZSW(con->user_agent.s), con->user_agent.len?">":"", con->path.len?";path=<":"", con->path.len, ZSW(con->path.s), con->path.len?">":"" ); if (node==0) goto error; } } unlock_udomain( dom, aor); if (rpl_tree==0) return init_mi_tree( 404 , "AOR has no contacts", 18); return rpl_tree; error: if (rpl_tree) free_mi_tree( rpl_tree ); unlock_udomain( dom, aor); return 0; }
/*! * \brief List the profiles via MI interface * \param cmd_tree MI command tree * \param param unused * \return MI root output on success, NULL on failure */ struct mi_root * mi_profile_list(struct mi_root *cmd_tree, void *param ) { struct mi_node* node; struct mi_root* rpl_tree= NULL; struct mi_node* rpl = NULL; struct dlg_profile_table *profile; struct dlg_profile_hash *ph; str *profile_name; str *value; unsigned int i; node = cmd_tree->node.kids; if (node==NULL || !node->value.s || !node->value.len) return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM)); profile_name = &node->value; if (node->next) { node = node->next; if (!node->value.s || !node->value.len) return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM)); if (node->next) return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM)); value = &node->value; } else { value = NULL; } /* search for the profile */ profile = search_dlg_profile( profile_name ); if (profile==NULL) return init_mi_tree( 404, MI_SSTR("Profile not found")); rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; /* go through the hash and print the dialogs */ if (profile->has_value==0 || value==NULL) { /* no value */ lock_get( &profile->lock ); for ( i=0 ; i< profile->size ; i++ ) { ph = profile->entries[i].first; if(ph) { do { /* print dialog */ if ( mi_print_dlg( rpl, ph->dlg, 0)!=0 ) goto error; /* next */ ph=ph->next; }while( ph!=profile->entries[i].first ); } } lock_release( &profile->lock ); } else { /* check for value also */ lock_get( &profile->lock ); for ( i=0 ; i< profile->size ; i++ ) { ph = profile->entries[i].first; if(ph) { do { if ( value->len==ph->value.len && memcmp(value->s,ph->value.s,value->len)==0 ) { /* print dialog */ if ( mi_print_dlg( rpl, ph->dlg, 0)!=0 ) goto error; } /* next */ ph=ph->next; }while( ph!=profile->entries[i].first ); } } lock_release( &profile->lock ); } return rpl_tree; error: free_mi_tree(rpl_tree); return NULL; }
/* TODO: add reason parameter to mi interface */ struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param) { struct mi_node* node; struct dlg_cell * dlg = NULL; str mi_extra_hdrs = {NULL, 0}; int status, msg_len; char *msg; str callid = {NULL, 0}; str ftag = {NULL, 0}; str ttag = {NULL, 0}; if (d_table == NULL) goto end; node = cmd_tree->node.kids; if (node == NULL || node->next == NULL || node->next->next == NULL) return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if (!node->value.s || !node->value.len) { goto error; } else { callid = node->value; } node = node->next; if (!node->value.s || !node->value.len) { goto error; } else { ftag = node->value; } node = node->next; if (!node->value.s || !node->value.len) { goto error; } else { ttag = node->value; } if (node->next) { node = node->next; if (node->value.len && node->value.s) mi_extra_hdrs = node->value; } unsigned int dir = DLG_DIR_NONE; LM_DBG("Looking for callid [%.*s]\n", callid.len, callid.s); dlg = get_dlg(&callid, &ftag, &ttag, &dir); //increments ref count! if (dlg) { LM_DBG("Found dialog to terminate and it is in state [%i]\n", dlg->state); if (dlg_terminate(dlg, 0, NULL/*reson*/, /* all sides of a dialog*/ 2, &mi_extra_hdrs) < 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; } 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); }
/*! * \brief Output a profile via MI interface * \param cmd_tree MI command tree * \param param unused * \return MI root output on success, NULL on failure */ struct mi_root * mi_get_profile(struct mi_root *cmd_tree, void *param) { struct mi_node* node; struct mi_root* rpl_tree= NULL; struct mi_node* rpl = NULL; struct mi_attr* attr; struct dlg_profile_table *profile; str *value; str *profile_name; unsigned int size; int len; char *p; node = cmd_tree->node.kids; if (node==NULL || !node->value.s || !node->value.len) return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM)); profile_name = &node->value; if (node->next) { node = node->next; if (!node->value.s || !node->value.len) return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM)); if (node->next) return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM)); value = &node->value; } else { value = NULL; } /* search for the profile */ profile = search_dlg_profile( profile_name ); if (profile==NULL) return init_mi_tree( 404, MI_SSTR("Profile not found")); size = get_profile_size( profile , value ); rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; node = add_mi_node_child(rpl, MI_DUP_VALUE, "profile", 7, NULL, 0); if (node==0) { free_mi_tree(rpl_tree); return NULL; } attr = add_mi_attr(node, MI_DUP_VALUE, "name", 4, profile->name.s, profile->name.len); if(attr == NULL) { goto error; } if (value) { attr = add_mi_attr(node, MI_DUP_VALUE, "value", 5, value->s, value->len); } else { attr = add_mi_attr(node, MI_DUP_VALUE, "value", 5, NULL, 0); } if(attr == NULL) { goto error; } p= int2str((unsigned long)size, &len); attr = add_mi_attr(node, MI_DUP_VALUE, "count", 5, p, len); if(attr == NULL) { goto error; } return rpl_tree; error: free_mi_tree(rpl_tree); return NULL; }
/* mi function implementations */ struct mi_root* mi_stats(struct mi_root* cmd_tree, void* param) { struct mi_root *rpl_tree; struct mi_node *node=NULL, *rpl=NULL; struct mi_attr* attr; char* p; int i, len; pl_pipe_t *it; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; for(i=0; i<_pl_pipes_ht->htsize; i++) { lock_get(&_pl_pipes_ht->slots[i].lock); it = _pl_pipes_ht->slots[i].first; while(it) { if (it->algo != PIPE_ALGO_NOP) { node = add_mi_node_child(rpl, 0, "PIPE", 4, 0, 0); if(node == NULL) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } attr = add_mi_attr(node, MI_DUP_VALUE, "id", 2, it->name.s, it->name.len); if(attr == NULL) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } p = int2str((unsigned long)(it->load), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "load", 4, p, len); if(attr == NULL) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } p = int2str((unsigned long)(it->last_counter), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "counter", 7, p, len); if(attr == NULL) { lock_release(&_pl_pipes_ht->slots[i].lock); goto error; } } it = it->next; } lock_release(&_pl_pipes_ht->slots[i].lock); } #if 0 p = int2str((unsigned long)(*drop_rate), &len); node = add_mi_node_child(rpl, MI_DUP_VALUE, "DROP_RATE", 9, p, len); #endif return rpl_tree; error: LM_ERR("Unable to create reply\n"); free_mi_tree(rpl_tree); return 0; }
static struct mi_root *mi_cachestore(struct mi_root *cmd, void *param) { str mc_system; str attr; str value; unsigned int expires = 0; struct mi_node* node= NULL; str expires_str; if(cmd == NULL) { LM_ERR("NULL command\n"); return init_mi_tree(404, "NULL command", 12); } node = cmd->node.kids; if(node == NULL) return init_mi_tree(404, "Too few arguments", 17); mc_system = node->value; if(mc_system.s == NULL || mc_system.len== 0) { LM_ERR( "empty memory cache system parameter\n"); return init_mi_tree(404, "Empty memory cache id", 21); } node = node->next; if(node == NULL) return init_mi_tree(404, "Too few arguments", 17); attr = node->value; if(attr.s == NULL || attr.len== 0) { LM_ERR( "empty attribute name parameter\n"); return init_mi_tree(404, "Empty attribute name", 20); } node = node->next; if(node == NULL) return init_mi_tree(404, "Too few arguments", 17); value = node->value; if(value.s == NULL || value.len== 0) { LM_ERR( "empty value parameter\n"); return init_mi_tree(404, "Empty value argument", 20); } /* expires parameter is not compulsory */ node = node->next; if(node!= NULL) { expires_str = node->value; if(expires_str.s == NULL || expires_str.len == 0) { LM_ERR( "empty expires parameter\n"); return init_mi_tree(404, "Empty expires argument", 22); } if(str2int(&expires_str, &expires)< 0) { LM_ERR("wrong format for expires argument- needed int\n"); return init_mi_tree(404, "Bad format for expires argument", 31); } node = node->next; if(node!= NULL) return init_mi_tree(404, "Too many parameters", 19); } if(cache_store(&mc_system, &attr, &value, expires)< 0) { LM_ERR("cache_store command failed\n"); return init_mi_tree(500, "Cache store command failed", 26); } return init_mi_tree(200, "OK", 2); }
/* * IMPORTANT: if a dialog reference is returned, the dialog hash entry will be kept locked when this function returns NOTE: if a reply tree is returned, no dialog reference is returned. */ static inline struct mi_root* process_mi_params(struct mi_root *cmd_tree, struct dlg_cell **dlg_p, unsigned int *idx, unsigned int *cnt) { struct mi_node* node; struct dlg_entry *d_entry; struct dlg_cell *dlg; str *p1; str *p2; unsigned int h_entry; node = cmd_tree->node.kids; if (node == NULL) { /* no parameters at all */ *dlg_p = NULL; *idx = *cnt = 0; return NULL; } /* we have params -> get p1 and p2 */ p1 = &node->value; LM_DBG("p1='%.*s'\n", p1->len, p1->s); node = node->next; if ( !node || !node->value.s || !node->value.len) { p2 = NULL; } else { p2 = &node->value; LM_DBG("p2='%.*s'\n", p2->len, p2->s); if ( node->next!=NULL ) return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM)); } /* check the params */ if (p2 && str2int(p1,idx)==0 && str2int(p2,cnt)==0) { /* 2 numerical params -> index and counter */ *dlg_p = NULL; return NULL; } *idx = *cnt = 0; if (!p1->s) return init_mi_tree( 400, "Invalid Call-ID specified", 25); h_entry = dlg_hash( p1/*callid*/ ); d_entry = &(d_table->entries[h_entry]); dlg_lock( d_table, d_entry); for( dlg = d_entry->first ; dlg ; dlg = dlg->next ) { if (match_downstream_dialog( dlg, p1/*callid*/, p2/*from_tag*/)==1) { if (dlg->state==DLG_STATE_DELETED) { *dlg_p = NULL; break; } else { *dlg_p = dlg; return 0; } } } dlg_unlock( d_table, d_entry); return init_mi_tree( 404, MI_SSTR("No such dialog")); }
static struct mi_root *mi_cachefetch(struct mi_root *cmd, void *param) { str mc_system; str attr; str value; struct mi_node* node= NULL; struct mi_root *rpl_tree= NULL; int ret; if(cmd == NULL) { LM_ERR("NULL command\n"); return init_mi_tree(404, "NULL command", 12); } node = cmd->node.kids; if(node == NULL) return init_mi_tree(404, "Too few arguments", 17); mc_system = node->value; if(mc_system.s == NULL || mc_system.len== 0) { LM_ERR( "empty memory cache system parameter\n"); return init_mi_tree(404, "Empty memory cache id", 21); } node = node->next; if(node == NULL) return init_mi_tree(404, "Too few arguments", 17); attr = node->value; if(attr.s == NULL || attr.len== 0) { LM_ERR( "empty attribute name parameter\n"); return init_mi_tree(404, "Empty attribute name", 20); } node = node->next; if(node != NULL) return init_mi_tree(404, "Too many arguments", 18); ret = cache_fetch(&mc_system, &attr, &value); if(ret== -1) { LM_ERR("cache_fetch command failed\n"); return init_mi_tree(500, "Cache fetch command failed", 26); } rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) { if(value.s) pkg_free(value.s); return 0; } if(ret == -2 || value.s == 0 || value.len == 0) { addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Value not found"); goto done; } addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "%.*s = [%.*s]", attr.len, attr.s, value.len, value.s); pkg_free(value.s); done: return rpl_tree; }
static struct mi_root* mi_print_blacklists(struct mi_root *cmd, void *param) { struct mi_root *rpl_tree; struct mi_node *rpl; struct mi_node *node; struct mi_node *node1; struct mi_node *node2; struct mi_attr *attr; unsigned int i; struct bl_rule *blr; char *p; int len; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==NULL) return 0; rpl = &rpl_tree->node; for ( i=0 ; i<used_heads ; i++ ) { if( !(blst_heads[i].flags&BL_READONLY_LIST) ) { /* get list for read */ lock_get( blst_heads[i].lock ); while(blst_heads[i].count_write) { lock_release( blst_heads[i].lock ); sleep_us(5); lock_get( blst_heads[i].lock ); } blst_heads[i].count_read++; lock_release(blst_heads[i].lock); } /* add a list node */ node = add_mi_node_child( rpl, 0, "List", 4, blst_heads[i].name.s, blst_heads[i].name.len ); if (node==0) goto error; /* add some attributes to the list node */ p= int2str((unsigned long)blst_heads[i].owner, &len); attr = add_mi_attr( node, MI_DUP_VALUE, "owner", 5, p, len); if (attr==0) goto error; p= int2str((unsigned long)blst_heads[i].flags, &len); attr = add_mi_attr( node, MI_DUP_VALUE, "flags", 5, p, len); if (attr==0) goto error; for( blr = blst_heads[i].first ; blr ; blr = blr->next) { /* add a rule node */ node1 = add_mi_node_child( node, 0, "Rule", 4, 0, 0 ); if (node1==0) goto error; /* add attributes to the rule node */ p= int2str((unsigned long)blr->flags, &len); attr = add_mi_attr( node1, MI_DUP_VALUE, "flags", 5, p, len); if (attr==0) goto error; /* add to rule node */ p = ip_addr2a(&blr->ip_net.ip); len = p?strlen(p):0; node2 = add_mi_node_child( node1, MI_DUP_VALUE, "IP", 2, p, len); if (node2==0) goto error; p = ip_addr2a(&blr->ip_net.mask); len = p?strlen(p):0; node2 = add_mi_node_child( node1, MI_DUP_VALUE, "Mask", 4, p, len); if (node2==0) goto error; p= int2str((unsigned long)blr->proto, &len); node2 = add_mi_node_child( node1, MI_DUP_VALUE, "Proto", 5, p,len); if (node2==0) goto error; p= int2str((unsigned long)blr->port, &len); node2 = add_mi_node_child( node1, MI_DUP_VALUE, "Port", 4, p,len); if (node2==0) goto error; if (blr->body.s) { node2 = add_mi_node_child( node1, MI_DUP_VALUE, "Match", 5, blr->body.s, blr->body.len); if (node2==0) goto error; } if (blst_heads[i].flags&BL_DO_EXPIRE) { p= int2str((unsigned long)blr->expire_end, &len); node2 = add_mi_node_child( node1, MI_DUP_VALUE, "Expire", 6, p, len); if (node2==0) goto error; } } if( !(blst_heads[i].flags&BL_READONLY_LIST) ) { lock_get( blst_heads[i].lock ); blst_heads[i].count_read--; lock_release(blst_heads[i].lock); } } return rpl_tree; error: if( !(blst_heads[i].flags&BL_READONLY_LIST) ) { lock_get( blst_heads[i].lock ); blst_heads[i].count_read--; lock_release(blst_heads[i].lock); } free_mi_tree(rpl_tree); return 0; }
static struct mi_root * mi_translate(struct mi_root *cmd, void *param) { struct mi_root* rpl= NULL; struct mi_node* root, *node; char *p; dpl_id_p idp; str dpid_str, partition_str; str input; int dpid; str attrs; str output= {0, 0}; dp_connection_list_p connection = NULL; node = cmd->node.kids; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); /* Get the id parameter */ dpid_str = node->value; if(dpid_str.s == NULL || dpid_str.len== 0) { LM_ERR( "empty idp parameter\n"); return init_mi_tree(404, "Empty id parameter", 18); } p = parse_dp_command(dpid_str.s, dpid_str.len, &partition_str); if (p == NULL) { LM_ERR("Invalid dp command\n"); return init_mi_tree(404, "Invalid dp command", 18); } if (partition_str.s == NULL || partition_str.len == 0) { partition_str.s = DEFAULT_PARTITION; partition_str.len = sizeof(DEFAULT_PARTITION) - 1; } connection = dp_get_connection(&partition_str); dpid_str.len -= (p - dpid_str.s); dpid_str.s = p; if (!connection) { LM_ERR("Unable to get connection\n"); return init_mi_tree(400, "Wrong db connection parameter", 24); } if(str2sint(&dpid_str, &dpid) != 0) { LM_ERR("Wrong id parameter - should be an integer\n"); return init_mi_tree(404, "Wrong id parameter", 18); } node = node->next; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if(node->next!= NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); input = node->value; if(input.s == NULL || input.len== 0) { LM_ERR( "empty input parameter\n"); return init_mi_tree(404, "Empty input parameter", 21); } /* ref the data for reading */ lock_start_read( connection->ref_lock ); if ((idp = select_dpid(connection, dpid, connection->crt_index)) ==0 ){ LM_ERR("no information available for dpid %i\n", dpid); lock_stop_read( connection->ref_lock ); return init_mi_tree(404, "No information available for dpid", 33); } if (translate(NULL, input, &output, idp, &attrs)!=0){ LM_DBG("could not translate %.*s with dpid %i\n", input.len, input.s, idp->dp_id); lock_stop_read( connection->ref_lock ); return init_mi_tree(404, "No translation", 14); } /* we are done reading -> unref the data */ lock_stop_read( connection->ref_lock ); LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, idp->dp_id, output.len, output.s); rpl = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl==0) goto error; root= &rpl->node; node = add_mi_node_child(root, 0, "Output", 6, output.s, output.len ); if( node == NULL) goto error; node = add_mi_node_child(root, 0, "ATTRIBUTES", 10, attrs.s, attrs.len); if( node == NULL) goto error; return rpl; error: if(rpl) free_mi_tree(rpl); return 0; }
struct mi_root *ws_mi_disable(struct mi_root *cmd, void *param) { cfg_get(websocket, ws_cfg, enabled) = 0; LM_WARN("disabling websockets - new connections will be dropped\n"); return init_mi_tree(200, MI_OK_S, MI_OK_LEN); }
struct mi_root* mi_usrloc_dump(struct mi_root *cmd, void *param) { struct mi_root *rpl_tree; struct mi_node *rpl; struct mi_node *node; struct mi_attr *attr; struct urecord* r; dlist_t* dl; udomain_t* dom; time_t t; char *p; int max; int len; int n; int i; int short_dump; node = cmd->node.kids; if (node && node->next) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if (node && node->value.len==5 && !strncasecmp(node->value.s, "brief", 5)){ /* short version */ short_dump = 1; } else { short_dump = 0; } rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==NULL) return 0; rpl = &rpl_tree->node; t = time(0); for( dl=root ; dl ; dl=dl->next ) { /* add a domain node */ node = add_mi_node_child( rpl, 0, "Domain", 6, dl->name.s, dl->name.len); if (node==0) goto error; dom = dl->d; /* add some attributes to the domain node */ p= int2str((unsigned long)dom->size, &len); attr = add_mi_attr( node, MI_DUP_VALUE, "table", 5, p, len); if (attr==0) goto error; /* add the entries per hash */ for(i=0,n=0,max=0; i<dom->size; i++) { lock_ulslot( dom, i); n += dom->table[i].n; if(max<dom->table[i].n) max= dom->table[i].n; for( r = dom->table[i].first ; r ; r=r->next ) { /* add entry */ if (mi_add_aor_node( node, r, t, short_dump)!=0) { unlock_ulslot( dom, i); goto error; } } unlock_ulslot( dom, i); } /* add more attributes to the domain node */ p= int2str((unsigned long)n, &len); attr = add_mi_attr( node, MI_DUP_VALUE, "records", 7, p, len); if (attr==0) goto error; p= int2str((unsigned long)max, &len); attr = add_mi_attr( node, MI_DUP_VALUE, "max_slot", 8, p, len); if (attr==0) goto error; } return rpl_tree; error: free_mi_tree(rpl_tree); return 0; }
struct mi_root* refreshXcapDoc(struct mi_root* cmd, void* param) { struct mi_node* node= NULL; str doc_url; xcap_doc_sel_t doc_sel; char* serv_addr; str stream= {0, 0}; int type; unsigned int xcap_port; char* etag= NULL; node = cmd->node.kids; if(node == NULL) return 0; doc_url = node->value; if(doc_url.s == NULL || doc_url.len== 0) { LM_ERR("empty uri\n"); return init_mi_tree(404, "Empty document URL", 20); } node= node->next; if(node== NULL) return 0; if(node->value.s== NULL || node->value.len== 0) { LM_ERR("port number\n"); return init_mi_tree(404, "Empty document URL", 20); } if(str2int(&node->value, &xcap_port)< 0) { LM_ERR("while converting string to int\n"); goto error; } if(node->next!= NULL) return 0; /* 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= get_auid_flag(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_tree(200, "OK", 2); error: if(stream.s) pkg_free(stream.s); return 0; }
/** * interpret the fifo errors, creates a mi tree * @todo this is currently not evaluated for errors during update_route_data */ struct mi_root* print_fifo_err(void) { struct mi_root* rpl_tree; switch (fifo_err) { case E_MISC: rpl_tree = init_mi_tree( 400, "An error occurred", 18); if(rpl_tree == NULL) return 0; break; case E_NOOPT: rpl_tree = init_mi_tree( 400, "No option given", 16); if(rpl_tree == NULL) return 0; break; case E_WRONGOPT: rpl_tree = init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); if(rpl_tree == NULL) return 0; break; case E_NOMEM: rpl_tree = init_mi_tree( 500, "Out of memory", 14); if(rpl_tree == NULL) return 0; break; case E_RESET: rpl_tree = init_mi_tree( 500, "Could not reset backup routes", 30); if(rpl_tree == NULL) return 0; break; case E_NOAUTOBACKUP: rpl_tree = init_mi_tree( 400, "No auto backup route found", 27); if(rpl_tree == NULL) return 0; break; case E_NOHASHBACKUP: rpl_tree = init_mi_tree( 400, "No backup route for given hash found", 37); if(rpl_tree == NULL) return 0; break; case E_NOHOSTBACKUP: rpl_tree = init_mi_tree( 400, "No backup route for given host found", 37); if(rpl_tree == NULL) return 0; break; case E_ADDBACKUP: rpl_tree = init_mi_tree( 500, "Could not set backup route", 27); if(rpl_tree == NULL) return 0; break; case E_DELBACKUP: rpl_tree = init_mi_tree( 400, "Could not delete or deactivate route, it is backup for other routes", 68); if(rpl_tree == NULL) return 0; break; case E_LOADCONF: rpl_tree = init_mi_tree( 500, "Could not load config from file", 32); if(rpl_tree == NULL) return 0; break; case E_SAVECONF: rpl_tree = init_mi_tree( 500, "Could not save config", 22); if(rpl_tree == NULL) return 0; break; case E_INVALIDOPT: rpl_tree = init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); if(rpl_tree == NULL) return 0; break; case E_MISSOPT: rpl_tree = init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if(rpl_tree == NULL) return 0; break; case E_RULEFIXUP: rpl_tree = init_mi_tree( 500, "Could not fixup rules", 22); if(rpl_tree == NULL) return 0; break; case E_NOUPDATE: rpl_tree = init_mi_tree( 500, "No match for update found", 26); if(rpl_tree == NULL) return 0; break; case E_HELP: return print_replace_help(); break; default: rpl_tree = init_mi_tree( 500, "An error occurred", 17); if(rpl_tree == NULL) return 0; break; } return rpl_tree; }