📄 chan_misdn.c
字号:
{MISDN_RELEASED,"RELEASED"}, /* when connected */ {MISDN_BRIDGED,"BRIDGED"}, /* when bridged */ {MISDN_CLEANING,"CLEANING"}, /* when hangup from * but we were connected before */ {MISDN_HUNGUP_FROM_MISDN,"HUNGUP_FROM_MISDN"}, /* when DISCONNECT/RELEASE/REL_COMP came from misdn */ {MISDN_HOLDED,"HOLDED"}, /* when DISCONNECT/RELEASE/REL_COMP came from misdn */ {MISDN_HOLD_DISCONNECT,"HOLD_DISCONNECT"}, /* when DISCONNECT/RELEASE/REL_COMP came from misdn */ {MISDN_HUNGUP_FROM_AST,"HUNGUP_FROM_AST"} /* when DISCONNECT/RELEASE/REL_COMP came out of misdn_hangup */};static char *misdn_get_ch_state(struct chan_list *p) { int i; static char state[8]; if( !p) return NULL; for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) { if ( state_array[i].state == p->state) return state_array[i].txt; } sprintf(state,"%d",p->state) ; return state;}static void reload_config(void){ int i, cfg_debug; if (!g_config_initialized) { ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n"); return ; } free_robin_list(); misdn_cfg_reload(); misdn_cfg_update_ptp(); misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int)); for (i = 0; i <= max_ports; i++) { misdn_debug[i] = cfg_debug; misdn_debug_only[i] = 0; }}static int misdn_reload (int fd, int argc, char *argv[]){ ast_cli(fd, "Reloading mISDN Config\n"); reload_config(); return 0;}static void print_bc_info (int fd, struct chan_list* help, struct misdn_bchannel* bc){ struct ast_channel *ast=help->ast; ast_cli(fd, "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n", bc->pid, bc->port, bc->channel, bc->nt?"NT":"TE", help->originator == ORG_AST?"*":"I", ast?ast->exten:NULL, ast?ast->cid.cid_num:NULL, bc->rad, ast?ast->context:NULL, misdn_get_ch_state(help) ); if (misdn_debug[bc->port] > 0) ast_cli(fd, " --> astname: %s\n" " --> ch_l3id: %x\n" " --> ch_addr: %x\n" " --> bc_addr: %x\n" " --> bc_l3id: %x\n" " --> display: %s\n" " --> activated: %d\n" " --> state: %s\n" " --> capability: %s\n"#ifdef MISDN_1_2 " --> pipeline: %s\n"#else " --> echo_cancel: %d\n"#endif " --> notone : rx %d tx:%d\n" " --> bc_hold: %d\n", help->ast->name, help->l3id, help->addr, bc->addr, bc?bc->l3_id:-1, bc->display, bc->active, bc_state2str(bc->bc_state), bearer2str(bc->capability),#ifdef MISDN_1_2 bc->pipeline,#else bc->ec_enable,#endif help->norxtone,help->notxtone, bc->holded ); }static int misdn_show_cls (int fd, int argc, char *argv[]){ struct chan_list *help=cl_te; ast_cli(fd,"Chan List: %p\n",cl_te); for (;help; help=help->next) { struct misdn_bchannel *bc=help->bc; struct ast_channel *ast=help->ast; if (!ast) { if (!bc) { ast_cli(fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id); continue; } ast_cli(fd, "bc with pid:%d has no Ast Leg\n", bc->pid); continue; } if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast); if (bc) { print_bc_info(fd, help, bc); } else { if (help->state == MISDN_HOLDED) { ast_cli(fd, "ITS A HOLDED BC:\n"); ast_cli(fd, " --> l3_id: %x\n" " --> dad:%s oad:%s\n" " --> hold_port: %d\n" " --> hold_channel: %d\n" ,help->l3id ,ast->exten ,ast->cid.cid_num ,help->hold_info.port ,help->hold_info.channel ); } else { ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num); } } } misdn_dump_chanlist(); return 0;}static int misdn_show_cl (int fd, int argc, char *argv[]){ struct chan_list *help=cl_te; if (argc != 4) return RESULT_SHOWUSAGE; for (;help; help=help->next) { struct misdn_bchannel *bc=help->bc; struct ast_channel *ast=help->ast; if (bc && ast) { if (!strcasecmp(ast->name,argv[3])) { print_bc_info(fd, help, bc); break; } } } return 0;}ast_mutex_t lock;int MAXTICS=8;static int misdn_set_tics (int fd, int argc, char *argv[]){ if (argc != 4) return RESULT_SHOWUSAGE; MAXTICS=atoi(argv[3]); return 0;}static int misdn_show_stacks (int fd, int argc, char *argv[]){ int port; ast_cli(fd, "BEGIN STACK_LIST:\n"); for (port=misdn_cfg_get_next_port(0); port > 0; port=misdn_cfg_get_next_port(port)) { char buf[128]; get_show_stack_details(port,buf); ast_cli(fd," %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":""); } return 0;}static int misdn_show_ports_stats (int fd, int argc, char *argv[]){ int port; ast_cli(fd, "Port\tin_calls\tout_calls\n"); for (port=misdn_cfg_get_next_port(0); port > 0; port=misdn_cfg_get_next_port(port)) { ast_cli(fd,"%d\t%d\t\t%d\n",port,misdn_in_calls[port],misdn_out_calls[port]); } ast_cli(fd,"\n"); return 0;}static int misdn_show_port (int fd, int argc, char *argv[]){ int port; char buf[128]; if (argc != 4) return RESULT_SHOWUSAGE; port = atoi(argv[3]); ast_cli(fd, "BEGIN STACK_LIST:\n"); get_show_stack_details(port,buf); ast_cli(fd," %s Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":""); return 0;}static int misdn_send_cd (int fd, int argc, char *argv[]){ char *channame; char *nr; if (argc != 5) return RESULT_SHOWUSAGE; channame = argv[3]; nr = argv[4]; ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame); { struct chan_list *tmp=get_chan_by_ast_name(channame); if (!tmp) { ast_cli(fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame); return 0; } else { if (strlen(nr) >= 15) { ast_cli(fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame); return 0; } tmp->bc->fac_out.Function = Fac_CD; strncpy((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber)); misdn_lib_send_event(tmp->bc, EVENT_FACILITY); } } return 0; }static int misdn_send_restart(int fd, int argc, char *argv[]){ int port; int channel; if ( (argc < 4) || (argc > 5) ) return RESULT_SHOWUSAGE; port = atoi(argv[3]); if (argc==5) { channel = atoi(argv[4]); misdn_lib_send_restart(port, channel); } else misdn_lib_send_restart(port, -1 ); return 0;}static int misdn_send_digit (int fd, int argc, char *argv[]){ char *channame; char *msg; if (argc != 5) return RESULT_SHOWUSAGE; channame = argv[3]; msg = argv[4]; ast_cli(fd, "Sending %s to %s\n",msg, channame); { struct chan_list *tmp=get_chan_by_ast_name(channame); if (!tmp) { ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame); return 0; } else {#if 1 int i; int msglen = strlen(msg); for (i=0; i<msglen; i++) { ast_cli(fd, "Sending: %c\n",msg[i]); send_digit_to_chan(tmp, msg[i]); /* res = ast_safe_sleep(tmp->ast, 250); */ usleep(250000); /* res = ast_waitfor(tmp->ast,100); */ }#else int res; res = ast_dtmf_stream(tmp->ast,NULL,msg,250);#endif } } return 0; }static int misdn_toggle_echocancel (int fd, int argc, char *argv[]){ char *channame; if (argc != 4) return RESULT_SHOWUSAGE; channame = argv[3]; ast_cli(fd, "Toggling EchoCancel on %s\n", channame); { struct chan_list *tmp=get_chan_by_ast_name(channame); if (!tmp) { ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame); return 0; } else { tmp->toggle_ec=tmp->toggle_ec?0:1; if (tmp->toggle_ec) {#ifdef MISDN_1_2 update_pipeline_config(tmp->bc);#else update_ec_config(tmp->bc);#endif manager_ec_enable(tmp->bc); } else { manager_ec_disable(tmp->bc); } } } return 0; }static int misdn_send_display (int fd, int argc, char *argv[]){ char *channame; char *msg; if (argc != 5) return RESULT_SHOWUSAGE; channame = argv[3]; msg = argv[4]; ast_cli(fd, "Sending %s to %s\n",msg, channame); { struct chan_list *tmp; tmp=get_chan_by_ast_name(channame); if (tmp && tmp->bc) { ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display)); misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); } else { ast_cli(fd,"No such channel %s\n",channame); return RESULT_FAILURE; } } return RESULT_SUCCESS ;}static char *complete_ch_helper(const char *line, const char *word, int pos, int state, int rpos){ struct ast_channel *c; int which=0; char *ret; if (pos != rpos) return NULL; c = ast_channel_walk_locked(NULL); while(c) { if (!strncasecmp(word, c->name, strlen(word))) { if (++which > state) break; } ast_mutex_unlock(&c->lock); c = ast_channel_walk_locked(c); } if (c) { ret = strdup(c->name); ast_mutex_unlock(&c->lock); } else ret = NULL; return ret;}static char *complete_ch(const char *line, const char *word, int pos, int state){ return complete_ch_helper(line, word, pos, state, 3);}static char *complete_debug_port (const char *line, const char *word, int pos, int state){ if (state) return NULL; switch (pos) { case 4: if (*word == 'p') return strdup("port"); else if (*word == 'o') return strdup("only"); break; case 6: if (*word == 'o') return strdup("only"); break; } return NULL;}static char *complete_show_config (const char *line, const char *word, int pos, int state){ char buffer[BUFFERSIZE]; enum misdn_cfg_elements elem; int wordlen = strlen(word); int which = 0; int port = 0; switch (pos) { case 3: if ((!strncmp(word, "description", wordlen)) && (++which > state)) return strdup("description"); if ((!strncmp(word, "descriptions", wordlen)) && (++which > state)) return strdup("descriptions"); if ((!strncmp(word, "0", wordlen)) && (++which > state)) return strdup("0"); while ((port = misdn_cfg_get_next_port(port)) != -1) { snprintf(buffer, sizeof(buffer), "%d", port); if ((!strncmp(word, buffer, wordlen)) && (++which > state)) { return strdup(buffer); } } break; case 4: if (strstr(line, "description ")) { for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) continue; misdn_cfg_get_name(elem, buffer, BUFFERSIZE); if (!wordlen || !strncmp(word, buffer, wordlen)) { if (++which > state) return strdup(buffer); } } } else if (strstr(line, "descriptions ")) { if ((!wordlen || !strncmp(word, "general", wordlen)) && (++which > state)) return strdup("general"); if ((!wordlen || !strncmp(word, "ports", wordlen)) && (++which > state)) return strdup("ports"); } break; } return NULL;}static struct ast_cli_entry chan_misdn_clis[] = { { {"misdn","send","calldeflect", NULL}, misdn_send_cd, "Sends CallDeflection to mISDN Channel", "Usage: misdn send calldeflect <channel> \"<nr>\" \n", complete_ch }, { {"misdn","send","digit", NULL}, misdn_send_digit, "Sends DTMF Digit to mISDN Channel", "Usage: misdn send digit <channel> \"<msg>\" \n" " Send <digit> to <channel> as DTMF Tone\n" " when channel is a mISDN channel\n", complete_ch }, { {"misdn","toggle","echocancel", NULL}, misdn_toggle_echocancel, "Toggles EchoCancel on mISDN Channel", "Usage: misdn toggle echocancel <channel>\n", complete_ch }, { {"misdn","send","display", NULL}, misdn_send_display, "Sends Text to mISDN Channel", "Usage: misdn send display <channel> \"<msg>\" \n" " Send <msg> to <channel> as Display Message\n" " when channel is a mISDN channel\n", complete_ch }, { {"misdn","show","config", NULL}, misdn_show_config, "Shows internal mISDN config, read from cfg-file",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -