struct mi_root* mi_get_pid(struct mi_root* cmd_tree, void* param) { struct mi_root *rpl_tree; struct mi_node *node=NULL, *rpl=NULL; struct mi_attr* attr; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; node = add_mi_node_child(rpl, 0, "PID", 3, 0, 0); if(node == NULL) goto error; rpl_pipe_lock(0); attr= addf_mi_attr(node, 0, "ki", 2, "%0.3f", *pid_ki); if(attr == NULL) goto error; attr= addf_mi_attr(node, 0, "kp", 2, "%0.3f", *pid_kp); if(attr == NULL) goto error; attr= addf_mi_attr(node, 0, "kd", 2, "%0.3f", *pid_kd); rpl_pipe_release(0); if(attr == NULL) goto error; return rpl_tree; error: rpl_pipe_release(0); LM_ERR("Unable to create reply\n"); free_mi_tree(rpl_tree); return 0; }
/* used to list all the registered events */ struct mi_root * mi_events_list(struct mi_root *cmd_tree, void *param) { struct mi_root *rpl_tree; struct mi_node *node=NULL, *rpl=NULL; unsigned i; 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 < events_no; i++) { node = add_mi_node_child(rpl, 0, "Event", 5, events[i].name.s, events[i].name.len); if(node == NULL) goto error; if (!addf_mi_attr(node, 0, "id", 2, "%d", events[i].id)) goto error; if ((i + 1) % 50 == 0) { flush_mi_tree(rpl_tree); } } return rpl_tree; error: free_mi_tree(rpl_tree); return 0; }
static int evi_print_subscriber(struct mi_node *rpl, evi_subs_p subs) { evi_reply_sock *sock = subs->reply_sock; struct mi_node *node = NULL; str socket; if (!subs || !subs->trans_mod || !subs->trans_mod->print) { LM_ERR("subscriber does not have a print method exported\n"); return -1; } node = add_mi_node_child(rpl, 0, "Subscriber", 10, 0, 0); if(node == NULL) return -1; if (!sock) { LM_DBG("no socket specified\n"); if (!add_mi_attr(node, 0, "protocol", 8, subs->trans_mod->proto.s, subs->trans_mod->proto.len)) return -1; return 0; } socket = subs->trans_mod->print(sock); LM_DBG("print subscriber socket <%.*s> %d\n", socket.len, socket.s, socket.len); if (!addf_mi_attr(node, MI_DUP_VALUE, "socket", 6, "%.*s:%.*s", subs->trans_mod->proto.len, subs->trans_mod->proto.s, socket.len, socket.s)) return -1; if (sock->flags & EVI_EXPIRE) { if (!addf_mi_attr(node, 0, "expire", 6, "%d", sock->expire)) return -1; } else { if (!add_mi_attr(node, 0, "expire", 6, "never", 5)) return -1; } /* XXX - does subscription time make sense? */ return 0; }
static int evi_print_event(struct evi_mi_param *param, evi_event_t *ev, evi_subs_p subs) { struct mi_node *node=NULL; struct mi_node *rpl = param->node; /* add event only if there are subscribers */ if (!subs && !ev->subscribers) return 0; node = add_mi_node_child(rpl, 0, "Event", 5, ev->name.s, ev->name.len); if(node == NULL) goto error; if (!addf_mi_attr(node, 0, "id", 2, "%d", ev->id)) goto error; if (subs) { if (evi_print_subscriber(node, subs) < 0) { LM_ERR("cannot print subscriber info\n"); goto error; } } else { for (subs = ev->subscribers; subs; subs = subs->next) { if (evi_print_subscriber(node, subs) < 0) { LM_ERR("cannot print subscriber info\n"); goto error; } if (++param->nr % 50 == 0) flush_mi_tree(param->root); } } return 0; error: return -1; }
/*! * \brief Helper method that output a dialog via the MI interface * \see mi_print_dlg * \param rpl MI node that should be filled * \param dlg printed dialog * \param with_context if 1 then the dialog context will be also printed * \return 0 on success, -1 on failure */ static inline int internal_mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context) { struct mi_node* node= NULL; struct mi_node* node1 = NULL; struct mi_attr* attr= NULL; int len; char* p; node = add_mi_node_child(rpl, 0, "dialog",6 , 0, 0 ); if (node==0) goto error; attr = addf_mi_attr( node, 0, "hash", 4, "%u:%u", dlg->h_entry, dlg->h_id ); if (attr==0) goto error; p= int2str((unsigned long)dlg->state, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "state", 5, p, len); if (node1==0) goto error; p= int2str((unsigned long)dlg->ref, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "ref_count", 9, p, len); if (node1==0) goto error; p= int2str((unsigned long)dlg->start_ts, &len); node1 = add_mi_node_child(node,MI_DUP_VALUE,"timestart",9, p, len); if (node1==0) goto error; p= int2str((unsigned long)dlg->tl.timeout, &len); node1 = add_mi_node_child(node,MI_DUP_VALUE, "timeout", 7, p, len); if (node1==0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callid", 6, dlg->callid.s, dlg->callid.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_uri", 8, dlg->from_uri.s, dlg->from_uri.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_tag", 8, dlg->tag[DLG_CALLER_LEG].s, dlg->tag[DLG_CALLER_LEG].len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_contact", 14, dlg->contact[DLG_CALLER_LEG].s, dlg->contact[DLG_CALLER_LEG].len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_cseq", 11, dlg->cseq[DLG_CALLER_LEG].s, dlg->cseq[DLG_CALLER_LEG].len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"caller_route_set",16, dlg->route_set[DLG_CALLER_LEG].s, dlg->route_set[DLG_CALLER_LEG].len); if(node1 == 0) goto error; if (dlg->bind_addr[DLG_CALLER_LEG]) { node1 = add_mi_node_child(node, 0, "caller_bind_addr",16, dlg->bind_addr[DLG_CALLER_LEG]->sock_str.s, dlg->bind_addr[DLG_CALLER_LEG]->sock_str.len); } else { node1 = add_mi_node_child(node, 0, "caller_bind_addr",16,0,0); } if (dlg->bind_addr[DLG_CALLEE_LEG]) { node1 = add_mi_node_child(node, 0, "callee_bind_addr",16, dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.s, dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.len); } else { node1 = add_mi_node_child(node, 0, "callee_bind_addr",16,0,0); } node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_uri", 6, dlg->to_uri.s, dlg->to_uri.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_tag", 6, dlg->tag[DLG_CALLEE_LEG].s, dlg->tag[DLG_CALLEE_LEG].len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_contact", 14, dlg->contact[DLG_CALLEE_LEG].s, dlg->contact[DLG_CALLEE_LEG].len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_cseq", 11, dlg->cseq[DLG_CALLEE_LEG].s, dlg->cseq[DLG_CALLEE_LEG].len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"callee_route_set",16, dlg->route_set[DLG_CALLEE_LEG].s, dlg->route_set[DLG_CALLEE_LEG].len); if(node1 == 0) goto error; if (with_context) { node1 = add_mi_node_child(node, 0, "context", 7, 0, 0); if(node1 == 0) goto error; run_dlg_callbacks( DLGCB_MI_CONTEXT, dlg, NULL, NULL, DLG_DIR_NONE, (void *)node1); } return 0; error: LM_ERR("failed to add node\n"); return -1; }
struct mi_root *mi_tcp_list_conns(struct mi_root *cmd, void *param) { struct mi_root *rpl_tree; struct mi_node* node; struct mi_attr *attr; struct tcp_connection *conn; time_t _ts; char date_buf[MI_DATE_BUF_LEN]; int date_buf_len; unsigned int i,n,part; char proto[PROTO_NAME_MAX_SIZE]; char *p; int len; rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); if (rpl_tree==NULL) return 0; if (tcp_disabled) return rpl_tree; for( part=0 ; part<TCP_PARTITION_SIZE ; part++) { TCPCONN_LOCK(part); for( i=0,n=0 ; i<TCP_ID_HASH_SIZE ; i++ ) { for(conn=TCP_PART(part).tcpconn_id_hash[i];conn;conn=conn->id_next){ /* add one node for each conn */ node = add_mi_node_child(&rpl_tree->node, 0, MI_SSTR("Connection"), 0, 0 ); if (node==0) goto error; /* add ID */ p = int2str((unsigned long)conn->id, &len); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("ID"), p, len); if (attr==0) goto error; /* add type/proto */ p = proto2str(conn->type, proto); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Type"), proto, (int)(long)(p-proto)); if (attr==0) goto error; /* add state */ p = int2str((unsigned long)conn->state, &len); attr = add_mi_attr( node, MI_DUP_VALUE,MI_SSTR("State"),p,len); if (attr==0) goto error; /* add Source */ attr = addf_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Source"), "%s:%d",ip_addr2a(&conn->rcv.src_ip), conn->rcv.src_port); if (attr==0) goto error; /* add Destination */ attr = addf_mi_attr( node, MI_DUP_VALUE,MI_SSTR("Destination"), "%s:%d",ip_addr2a(&conn->rcv.dst_ip), conn->rcv.dst_port); if (attr==0) goto error; /* add lifetime */ _ts = (time_t)conn->lifetime + startup_time; date_buf_len = strftime(date_buf, MI_DATE_BUF_LEN - 1, "%Y-%m-%d %H:%M:%S", localtime(&_ts)); if (date_buf_len != 0) { attr = add_mi_attr( node, MI_DUP_VALUE,MI_SSTR("Lifetime"), date_buf, date_buf_len); } else { p = int2str((unsigned long)_ts, &len); attr = add_mi_attr( node, MI_DUP_VALUE,MI_SSTR("Lifetime"), p,len); } if (attr==0) goto error; n++; /* at each 50 conns, flush the tree */ if ( (n % 50) == 0 ) flush_mi_tree(rpl_tree); } } TCPCONN_UNLOCK(part); } return rpl_tree; error: TCPCONN_UNLOCK(part); LM_ERR("failed to add node\n"); free_mi_tree(rpl_tree); return 0; }
static inline int internal_mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context) { struct mi_node* node= NULL; struct mi_node* node1 = NULL; struct mi_node* node2 = NULL; struct mi_node* node3 = NULL; struct mi_attr* attr= NULL; struct dlg_profile_link *dl; struct dlg_val* dv; int len; char* p; int i, j; time_t _ts; struct tm* t; char date_buf[MI_DATE_BUF_LEN]; int date_buf_len; node = add_mi_node_child(rpl, 0, "dialog",6 , 0, 0 ); if (node==0) goto error; attr = addf_mi_attr( node, 0, "ID", 2, "%llu", (((long long unsigned)dlg->h_entry)<<(8*sizeof(int)))+dlg->h_id ); if (attr==0) goto error; p= int2str((unsigned long)dlg->state, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "state", 5, p, len); if (node1==0) goto error; p= int2str((unsigned long)dlg->user_flags, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "user_flags", 10, p, len); if (node1==0) goto error; _ts = (time_t)dlg->start_ts; p= int2str((unsigned long)_ts, &len); node1 = add_mi_node_child(node,MI_DUP_VALUE,"timestart",9, p, len); if (node1==0) goto error; if (_ts) { t = localtime(&_ts); date_buf_len = strftime(date_buf, MI_DATE_BUF_LEN - 1, "%Y-%m-%d %H:%M:%S", t); if (date_buf_len != 0) { node1 = add_mi_node_child(node,MI_DUP_VALUE, "datestart", 9, date_buf, date_buf_len); if (node1==0) goto error; } } _ts = (time_t)(dlg->tl.timeout?((unsigned int)time(0) + dlg->tl.timeout - get_ticks()):0); p= int2str((unsigned long)_ts, &len); node1 = add_mi_node_child(node,MI_DUP_VALUE, "timeout", 7, p, len); if (node1==0) goto error; if (_ts) { t = localtime(&_ts); date_buf_len = strftime(date_buf, MI_DATE_BUF_LEN - 1, "%Y-%m-%d %H:%M:%S", t); if (date_buf_len != 0) { node1 = add_mi_node_child(node,MI_DUP_VALUE, "dateout", 7, date_buf, date_buf_len); if (node1==0) goto error; } } node1 = add_mi_node_child(node, MI_DUP_VALUE, "callid", 6, dlg->callid.s, dlg->callid.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_uri", 8, dlg->from_uri.s, dlg->from_uri.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_uri", 6, dlg->to_uri.s, dlg->to_uri.len); if(node1 == 0) goto error; if (dlg->legs_no[DLG_LEGS_USED]>0) { node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_tag", 10, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[DLG_CALLER_LEG].tag.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_contact", 14, dlg->legs[DLG_CALLER_LEG].contact.s, dlg->legs[DLG_CALLER_LEG].contact.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_cseq", 11, dlg->legs[DLG_CALLER_LEG].r_cseq.s, dlg->legs[DLG_CALLER_LEG].r_cseq.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"caller_route_set",16, dlg->legs[DLG_CALLER_LEG].route_set.s, dlg->legs[DLG_CALLER_LEG].route_set.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, 0,"caller_bind_addr",16, dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str.s, dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"caller_sdp",10, dlg->legs[DLG_CALLER_LEG].sdp.s, dlg->legs[DLG_CALLER_LEG].sdp.len); if(node1 == 0) goto error; } node1 = add_mi_node_child(node, MI_IS_ARRAY, "CALLEES", 7, NULL, 0); if(node1 == 0) goto error; for( i=1 ; i < dlg->legs_no[DLG_LEGS_USED] ; i++ ) { node2 = add_mi_node_child(node1, 0, "callee", 6, NULL, 0); if(node2 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE, "callee_tag", 10, dlg->legs[i].tag.s, dlg->legs[i].tag.len); if(node3 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE, "callee_contact", 14, dlg->legs[i].contact.s, dlg->legs[i].contact.len); if(node3 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE, "caller_cseq", 11, dlg->legs[i].r_cseq.s, dlg->legs[i].r_cseq.len); if(node3 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE,"callee_route_set",16, dlg->legs[i].route_set.s, dlg->legs[i].route_set.len); if(node3 == 0) goto error; if (dlg->legs[i].bind_addr) { node3 = add_mi_node_child(node2, 0, "callee_bind_addr",16, dlg->legs[i].bind_addr->sock_str.s, dlg->legs[i].bind_addr->sock_str.len); } else { node3 = add_mi_node_child(node2, 0, "callee_bind_addr",16,0,0); } if(node3 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE,"callee_sdp",10, dlg->legs[i].sdp.s, dlg->legs[i].sdp.len); if(node3 == 0) goto error; } if (with_context) { node1 = add_mi_node_child(node, 0, "context", 7, 0, 0); if(node1 == 0) goto error; if (dlg->vals) { node2 = add_mi_node_child(node1, 0, "values", 6, 0, 0); if(node2 == 0) goto error; /* print dlg values -> iterate the list */ for( dv=dlg->vals ; dv ; dv=dv->next) { /* escape non-printable chars */ p = pkg_realloc(dlg_val_buf, 4 * dv->val.len + 1); if (!p) { LM_ERR("not enough mem to allocate: %d\n", dv->val.len); continue; } for (i = 0, j = 0; i < dv->val.len; i++) { if (dv->val.s[i] < 0x20 || dv->val.s[i] >= 0x7F) { p[j++] = '\\'; switch ((unsigned char)dv->val.s[i]) { case 0x8: p[j++] = 'b'; break; case 0x9: p[j++] = 't'; break; case 0xA: p[j++] = 'n'; break; case 0xC: p[j++] = 'f'; break; case 0xD: p[j++] = 'r'; break; default: p[j++] = 'x'; j += snprintf(&p[j], 3, "%02x", (unsigned char)dv->val.s[i]); break; } } else { p[j++] = dv->val.s[i]; } } add_mi_node_child(node2, MI_DUP_NAME|MI_DUP_VALUE,dv->name.s,dv->name.len, p,j); dlg_val_buf = p; } } /* print dlg profiles */ if (dlg->profile_links) { node3 = add_mi_node_child(node1, MI_IS_ARRAY, "profiles", 8, 0, 0); if(node3 == 0) goto error; for( dl=dlg->profile_links ; dl ; dl=dl->next) { add_mi_node_child(node3, MI_DUP_NAME|MI_DUP_VALUE, dl->profile->name.s,dl->profile->name.len, ZSW(dl->value.s),dl->value.len); } } /* print external context info */ run_dlg_callbacks( DLGCB_MI_CONTEXT, dlg, NULL, DLG_DIR_NONE, (void *)node1, 0); } return 0; error: LM_ERR("failed to add node\n"); return -1; }
/**************************** MI functions ******************************/ static inline int internal_mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context) { struct mi_node* node= NULL; struct mi_node* node1 = NULL; struct mi_attr* attr= NULL; struct dlg_profile_link *dl; struct dlg_val* dv; int len; char* p; int i; node = add_mi_node_child(rpl, 0, "dialog",6 , 0, 0 ); if (node==0) goto error; attr = addf_mi_attr( node, 0, "hash", 4, "%u:%u", dlg->h_entry, dlg->h_id ); if (attr==0) goto error; p= int2str((unsigned long)dlg->state, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "state", 5, p, len); if (node1==0) goto error; p= int2str((unsigned long)dlg->user_flags, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "user_flags", 10, p, len); if (node1==0) goto error; p= int2str((unsigned long)dlg->start_ts, &len); node1 = add_mi_node_child(node,MI_DUP_VALUE,"timestart",9, p, len); if (node1==0) goto error; p= int2str((unsigned long)(dlg->tl.timeout?((unsigned int)time(0) + dlg->tl.timeout - get_ticks()):0), &len); node1 = add_mi_node_child(node,MI_DUP_VALUE, "timeout", 7, p, len); if (node1==0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callid", 6, dlg->callid.s, dlg->callid.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_uri", 8, dlg->from_uri.s, dlg->from_uri.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_uri", 6, dlg->to_uri.s, dlg->to_uri.len); if(node1 == 0) goto error; if (dlg->legs_no[DLG_LEGS_USED]>0) { node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_tag", 10, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[DLG_CALLER_LEG].tag.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_contact", 14, dlg->legs[DLG_CALLER_LEG].contact.s, dlg->legs[DLG_CALLER_LEG].contact.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_cseq", 11, dlg->legs[DLG_CALLER_LEG].r_cseq.s, dlg->legs[DLG_CALLER_LEG].r_cseq.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"caller_route_set",16, dlg->legs[DLG_CALLER_LEG].route_set.s, dlg->legs[DLG_CALLER_LEG].route_set.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, 0,"caller_bind_addr",16, dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str.s, dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str.len); if(node1 == 0) goto error; } for( i=1 ; i < dlg->legs_no[DLG_LEGS_USED] ; i++ ) { node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_tag", 10, dlg->legs[i].tag.s, dlg->legs[i].tag.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_contact", 14, dlg->legs[i].contact.s, dlg->legs[i].contact.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_cseq", 11, dlg->legs[i].r_cseq.s, dlg->legs[i].r_cseq.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"callee_route_set",16, dlg->legs[i].route_set.s, dlg->legs[i].route_set.len); if(node1 == 0) goto error; if (dlg->legs[i].bind_addr) { node1 = add_mi_node_child(node, 0, "callee_bind_addr",16, dlg->legs[i].bind_addr->sock_str.s, dlg->legs[i].bind_addr->sock_str.len); } else { node1 = add_mi_node_child(node, 0, "callee_bind_addr",16,0,0); } if(node1 == 0) goto error; } if (with_context) { node1 = add_mi_node_child(node, 0, "context", 7, 0, 0); if(node1 == 0) goto error; /* print dlg values -> iterate the list */ for( dv=dlg->vals ; dv ; dv=dv->next) { addf_mi_node_child(node1, MI_DUP_VALUE, MI_SSTR("value"), "%.*s = %.*s",dv->name.len,dv->name.s,dv->val.len,dv->val.s); } /* print dlg profiles */ for( dl=dlg->profile_links ; dl ; dl=dl->next) { addf_mi_node_child(node1, MI_DUP_VALUE, MI_SSTR("profile"), "%.*s = %.*s",dl->profile->name.len,dl->profile->name.s, dl->value.len,ZSW(dl->value.s)); } /* print external context info */ run_dlg_callbacks( DLGCB_MI_CONTEXT, dlg, NULL, DLG_DIR_NONE, (void *)node1); } return 0; error: LM_ERR("failed to add node\n"); return -1; }
static inline int internal_mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context) { struct mi_node* node= NULL; struct mi_node* node1 = NULL; struct mi_attr* attr= NULL; struct dlg_profile_link *dl; struct dlg_val* dv; int len; char* p; int i, j; node = add_mi_node_child(rpl, 0, "dialog",6 , 0, 0 ); if (node==0) goto error; attr = addf_mi_attr( node, 0, "hash", 4, "%u:%u", dlg->h_entry, dlg->h_id ); if (attr==0) goto error; p= int2str((unsigned long)dlg->state, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "state", 5, p, len); if (node1==0) goto error; p= int2str((unsigned long)dlg->user_flags, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "user_flags", 10, p, len); if (node1==0) goto error; p= int2str((unsigned long)dlg->start_ts, &len); node1 = add_mi_node_child(node,MI_DUP_VALUE,"timestart",9, p, len); if (node1==0) goto error; p= int2str((unsigned long)(dlg->tl.timeout?((unsigned int)time(0) + dlg->tl.timeout - get_ticks()):0), &len); node1 = add_mi_node_child(node,MI_DUP_VALUE, "timeout", 7, p, len); if (node1==0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callid", 6, dlg->callid.s, dlg->callid.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_uri", 8, dlg->from_uri.s, dlg->from_uri.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_uri", 6, dlg->to_uri.s, dlg->to_uri.len); if(node1 == 0) goto error; if (dlg->legs_no[DLG_LEGS_USED]>0) { node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_tag", 10, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[DLG_CALLER_LEG].tag.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_contact", 14, dlg->legs[DLG_CALLER_LEG].contact.s, dlg->legs[DLG_CALLER_LEG].contact.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_cseq", 11, dlg->legs[DLG_CALLER_LEG].r_cseq.s, dlg->legs[DLG_CALLER_LEG].r_cseq.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"caller_route_set",16, dlg->legs[DLG_CALLER_LEG].route_set.s, dlg->legs[DLG_CALLER_LEG].route_set.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, 0,"caller_bind_addr",16, dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str.s, dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str.len); if(node1 == 0) goto error; } for( i=1 ; i < dlg->legs_no[DLG_LEGS_USED] ; i++ ) { node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_tag", 10, dlg->legs[i].tag.s, dlg->legs[i].tag.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_contact", 14, dlg->legs[i].contact.s, dlg->legs[i].contact.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_cseq", 11, dlg->legs[i].r_cseq.s, dlg->legs[i].r_cseq.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"callee_route_set",16, dlg->legs[i].route_set.s, dlg->legs[i].route_set.len); if(node1 == 0) goto error; if (dlg->legs[i].bind_addr) { node1 = add_mi_node_child(node, 0, "callee_bind_addr",16, dlg->legs[i].bind_addr->sock_str.s, dlg->legs[i].bind_addr->sock_str.len); } else { node1 = add_mi_node_child(node, 0, "callee_bind_addr",16,0,0); } if(node1 == 0) goto error; } if (with_context) { node1 = add_mi_node_child(node, 0, "context", 7, 0, 0); if(node1 == 0) goto error; /* print dlg values -> iterate the list */ for( dv=dlg->vals ; dv ; dv=dv->next) { /* escape non-printable chars */ p = pkg_realloc(dlg_val_buf, 4 * dv->val.len + 1); if (!p) { LM_ERR("not enough mem to allocate: %d\n", dv->val.len); continue; } for (i = 0, j = 0; i < dv->val.len; i++) { if (dv->val.s[i] < 0x20) { p[j++] = '\\'; switch ((unsigned char)dv->val.s[i]) { case 0x9: p[j++] = 't'; break; case 0xA: p[j++] = 'n'; break; case 0xD: p[j++] = 'r'; break; default: p[j++] = 'x'; j += snprintf(&p[j], 3, "%02x", (unsigned char)dv->val.s[i]); break; } } else { p[j++] = dv->val.s[i]; } } addf_mi_node_child(node1, MI_DUP_VALUE, MI_SSTR("value"), "%.*s = %.*s",dv->name.len,dv->name.s,j,p); dlg_val_buf = p; } /* print dlg profiles */ for( dl=dlg->profile_links ; dl ; dl=dl->next) { addf_mi_node_child(node1, MI_DUP_VALUE, MI_SSTR("profile"), "%.*s = %.*s",dl->profile->name.len,dl->profile->name.s, dl->value.len,ZSW(dl->value.s)); } /* print external context info */ run_dlg_callbacks( DLGCB_MI_CONTEXT, dlg, NULL, DLG_DIR_NONE, (void *)node1); } return 0; error: LM_ERR("failed to add node\n"); return -1; }