/* * RPC command to perform dialplan translation */ static void dialplan_rpc_translate(rpc_t* rpc, void* ctx) { dpl_id_p idp; str input; int dpid; str attrs = {"", 0}; str output = {0, 0}; void* th; if (rpc->scan(ctx, "dS", &dpid, &input) < 2) { rpc->fault(ctx, 500, "Invalid parameters"); return; } if ((idp = select_dpid(dpid)) == 0 ){ LM_ERR("no information available for dpid %i\n", dpid); rpc->fault(ctx, 500, "Dialplan ID not matched"); return; } if(input.s == NULL || input.len== 0) { LM_ERR("empty input parameter\n"); rpc->fault(ctx, 500, "Empty input parameter"); return; } LM_DBG("trying to translate %.*s with dpid %i\n", input.len, input.s, idp->dp_id); 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); rpc->fault(ctx, 500, "No translation"); return; } LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, idp->dp_id, output.len, output.s); if (rpc->add(ctx, "{", &th) < 0) { rpc->fault(ctx, 500, "Internal error creating rpc"); return; } if(rpc->struct_add(th, "SS", "Output", &output, "Attributes", &attrs)<0) { rpc->fault(ctx, 500, "Internal error creating rpc"); return; } return; }
static int dp_translate_f(struct sip_msg* msg, char* str1, char* str2) { int dpid; str input, output; dpl_id_p idp; dp_param_p id_par, repl_par; str attrs, * attrs_par; if(!msg) return -1; /*verify first param's value*/ id_par = (dp_param_p) str1; if (dp_get_ivalue(msg, id_par, &dpid) != 0){ LM_ERR("no dpid value\n"); return -1; } if ((idp = select_dpid(dpid)) ==0 ){ LM_DBG("no information available for dpid %i\n", dpid); return -1; } repl_par = (str2!=NULL)? ((dp_param_p)str2):default_par2; if (dp_get_svalue(msg, repl_par->v.sp[0], &input)!=0){ LM_ERR("invalid param 2\n"); return -1; } LM_DBG("input is %.*s\n", input.len, input.s); attrs_par = (!attr_pvar)?NULL:&attrs; if (translate(msg, input, &output, idp, attrs_par)!=0){ LM_DBG("could not translate %.*s " "with dpid %i\n", input.len, input.s, idp->dp_id); return -1; } LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, idp->dp_id, output.len, output.s); /*set the output*/ if (dp_update(msg, &repl_par->v.sp[0], &repl_par->v.sp[1], &output, attrs_par) !=0){ LM_ERR("cannot set the output\n"); return -1; } return 1; }
static int dp_translate_f(struct sip_msg *msg, char *str1, char *str2, char *attr_spec) { int dpid; str input, output; dpl_id_p idp; dp_param_p id_par, repl_par; str attrs, *attrs_par; dp_connection_list_p connection; pv_value_t pval; str partition_name; if (!msg) return -1; /* verify first param's value */ id_par = (dp_param_p) str1; if (dp_get_ivalue(msg, id_par, &dpid) != 0){ LM_ERR("no dpid value\n"); return -1; } switch( id_par->type ) { case DP_VAL_INT : if (dp_get_svalue(msg, id_par->v.pv_id.partition, &partition_name)) { LM_ERR("invalid partition\n"); return -1; } goto GET_CONN; case DP_VAL_SPEC : if (dp_get_svalue(msg, id_par->v.sp[1], &partition_name)) { LM_ERR("invalid partition\n"); return -1; } GET_CONN: if (!(id_par->hash = dp_get_connection(&partition_name))) { LM_ERR("invalid partition\n"); return -1; } break; default : break; } LM_DBG("dpid is %i partition is %.*s\n", dpid, id_par->hash->partition.len, id_par->hash->partition.s); repl_par = (str2!=NULL) ? ((dp_param_p)str2) : default_par2; if (dp_get_svalue(msg, repl_par->v.sp[0], &input)!=0){ LM_ERR("invalid param 2\n"); return -1; } LM_DBG("input is %.*s\n", input.len, input.s); connection = id_par->hash; /* ref the data for reading */ lock_start_read( connection->ref_lock ); if ((idp = select_dpid(connection, dpid, connection->crt_index)) == 0) { LM_DBG("no information available for dpid %i\n", dpid); goto error; } LM_DBG("Checking with dpid %i\n", idp->dp_id); attrs_par = attr_spec ? &attrs : NULL; if (translate(msg, input, &output, idp, attrs_par) != 0) { LM_DBG("could not translate %.*s " "with dpid %i\n", input.len, input.s, idp->dp_id); goto error; } LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, idp->dp_id, output.len, output.s); /* set the output */ if (dp_update(msg, &repl_par->v.sp[0], &repl_par->v.sp[1], &output) != 0) { LM_ERR("cannot set the output\n"); goto error; } /* we are done reading -> unref the data */ lock_stop_read( connection->ref_lock ); if (attr_spec) { pval.flags = PV_VAL_STR; pval.rs = attrs; if (pv_set_value(msg, (pv_spec_p)attr_spec, 0, &pval) != 0) { LM_ERR("failed to set value '%.*s' for the attr pvar!\n", attrs.len, attrs.s); goto error; } } return 1; error: /* we are done reading -> unref the data */ lock_stop_read( connection->ref_lock ); return -1; }
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; }
static struct mi_root * mi_translate(struct mi_root *cmd, void *param) { struct mi_root* rpl= NULL; struct mi_node* root, *node; dpl_id_p idp; str dpid_str; str input; int dpid; str attrs; str output= {0, 0}; 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); } 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); } LM_DBG("input is %.*s\n", input.len, input.s); /* ref the data for reading */ lock_start_read( ref_lock ); if ((idp = select_dpid(dpid)) ==0 ){ LM_ERR("no information available for dpid %i\n", dpid); lock_stop_read( 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); goto error1; } /* we are done reading -> unref the data */ lock_stop_read( 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; error1: /* we are done reading -> unref the data */ lock_stop_read( ref_lock ); error: if(rpl) free_mi_tree(rpl); return 0; }
int add_rule2hash(dpl_node_t * rule, dp_connection_list_t *conn, int index) { dpl_id_p crt_idp; dpl_index_p indexp; int new_id, bucket = 0; if(!conn){ LM_ERR("data not allocated\n"); return -1; } new_id = 0; crt_idp = select_dpid(conn, rule->dpid, index); /*didn't find a dpl_id*/ if(!crt_idp){ crt_idp = shm_malloc(sizeof(dpl_id_t) + (DP_INDEX_HASH_SIZE+1) * sizeof(dpl_index_t)); if(!crt_idp){ LM_ERR("out of shm memory (crt_idp)\n"); return -1; } memset(crt_idp, 0, sizeof(dpl_id_t) + (DP_INDEX_HASH_SIZE+1) * sizeof(dpl_index_t)); crt_idp->dp_id = rule->dpid; crt_idp->rule_hash = (dpl_index_t*)(crt_idp + 1); new_id = 1; LM_DBG("new dpl_id %i\n", rule->dpid); } switch (rule->matchop) { case REGEX_OP: indexp = &crt_idp->rule_hash[DP_INDEX_HASH_SIZE]; break; case EQUAL_OP: if (rule->match_exp.s == NULL || rule->match_exp.len == 0) { LM_ERR("NULL matching expressions in database not accepted!!!\n"); return -1; } bucket = core_case_hash(&rule->match_exp, NULL, DP_INDEX_HASH_SIZE); indexp = &crt_idp->rule_hash[bucket]; break; default: LM_ERR("SKIPPED RULE. Unsupported match operator (%d).\n", rule->matchop); goto err; } /* Add the new rule to the corresponding bucket */ rule->next = 0; if(!indexp->first_rule) indexp->first_rule = rule; if(indexp->last_rule) indexp->last_rule->next = rule; indexp->last_rule = rule; if(new_id){ crt_idp->next = conn->hash[conn->next_index]; conn->hash[conn->next_index] = crt_idp; } LM_DBG("added the rule id %i pr %i next %p to the " " %i bucket\n", rule->dpid, rule->pr, rule->next, rule->matchop == REGEX_OP ? DP_INDEX_HASH_SIZE : bucket); return 0; err: if(new_id) shm_free(crt_idp); return -1; }