diff options
author | Mark Spencer <markster@digium.com> | 2004-05-12 00:17:31 +0000 |
---|---|---|
committer | Mark Spencer <markster@digium.com> | 2004-05-12 00:17:31 +0000 |
commit | 10c25aa6d983f67c1c04f389d10679459b4edf8d (patch) | |
tree | 7f238412a5e029b65c8a187d2408e9134306407d | |
parent | 34e400fe2bffb5cc22e4017590247a1fc1712e38 (diff) |
Put sip history stuff in (for real) and provide voicemail context (when not default) in some critical places (bug #1609)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2950 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rwxr-xr-x | apps/app_voicemail.c | 21 | ||||
-rwxr-xr-x | channels/chan_sip.c | 161 |
2 files changed, 171 insertions, 11 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index fb36366d1..44b49f244 100755 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -1498,6 +1498,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int char dir[256]; char fn[256]; char prefile[256]=""; + char ext_context[256] = ""; char fmt[80]; char *context; char *ecodes = "#"; @@ -1517,6 +1518,10 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int if ((vmu = find_user(&svm, context, ext))) { /* Setup pre-file if appropriate */ + if (strcmp(vmu->context, "default")) + snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); + else + strncpy(ext_context, vmu->context, sizeof(ext_context) - 1); if (busy) snprintf(prefile, sizeof(prefile), "voicemail/%s/%s/busy", vmu->context, ext); else if (unavail) @@ -1690,10 +1695,10 @@ leave_vm_out: chan->priority+=100; } /* Leave voicemail for someone */ - manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext, ast_app_has_voicemail(ext)); + manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, ast_app_has_voicemail(ext_context)); /* If an external program is specified to be run after leaving a voicemail */ - run_externnotify(chan->context, ext, ast_app_has_voicemail(ext)); + run_externnotify(chan->context, ext_context, ast_app_has_voicemail(ext_context)); return res; } @@ -2391,6 +2396,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i char miffile[256]; char fn[256]; char callerid[512]; + char ext_context[256]=""; int res = 0, cmd = 0; struct ast_vm_user *receiver, *extensions = NULL, *vmtmp = NULL, *vmfree; char tmp[256]; @@ -2444,6 +2450,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i */ snprintf(todir, sizeof(todir), "%s/voicemail/%s/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, vmtmp->context, vmtmp->mailbox); snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir); + snprintf(ext_context, sizeof(ext_context), "%s@%s", vmtmp->mailbox, vmtmp->context); ast_log(LOG_DEBUG, sys); ast_safe_system(sys); @@ -2494,8 +2501,8 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i ast_destroy(mif); /* or here */ } /* Leave voicemail for someone */ - manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", vmtmp->mailbox, ast_app_has_voicemail(vmtmp->mailbox)); - run_externnotify(chan->context, vmtmp->mailbox, ast_app_has_voicemail(vmtmp->mailbox)); + manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, ast_app_has_voicemail(ext_context)); + run_externnotify(chan->context, ext_context, ast_app_has_voicemail(ext_context)); saved_messages++; vmfree = vmtmp; @@ -2943,6 +2950,7 @@ static int vm_execmain(struct ast_channel *chan, void *data) struct localuser *u; char prefixstr[80] =""; char empty[80] = ""; + char ext_context[256]=""; int box; int useadsi = 0; int skipuser = 0; @@ -3319,8 +3327,9 @@ out: if (vmu) free_user(vmu); if (valid) { - manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", vms.username, ast_app_has_voicemail(vms.username)); - run_externnotify(chan->context, vms.username, ast_app_has_voicemail(vms.username)); + snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); + manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, ast_app_has_voicemail(ext_context)); + run_externnotify(chan->context, ext_context, ast_app_has_voicemail(ext_context)); } LOCAL_USER_REMOVE(u); diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 79f46149d..c38a3697d 100755 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -174,6 +174,8 @@ static int tos = 0; static int videosupport = 0; +static int recordhistory = 0; + static int globaldtmfmode = SIP_DTMF_RFC2833; static char globalmusicclass[MAX_LANGUAGE] = ""; /* Global music on hold class */ static char global_realm[AST_MAX_EXTENSION] = "asterisk"; /* Default realm */ @@ -217,6 +219,11 @@ struct sip_route { char hop[0]; }; +struct sip_history { + char event[80]; + struct sip_history *next; +}; + static struct sip_pvt { ast_mutex_t lock; /* Channel private lock */ char callid[80]; /* Global CallID */ @@ -307,6 +314,7 @@ static struct sip_pvt { struct ast_rtp *rtp; /* RTP Session */ struct ast_rtp *vrtp; /* Video RTP session */ struct sip_pkt *packets; /* Packets scheduled for re-transmission */ + struct sip_history *history; /* History of this SIP dialog */ struct sip_pvt *next; /* Next call in chain */ } *iflist = NULL; @@ -523,6 +531,38 @@ static int ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us) return 0; } +static int append_history(struct sip_pvt *p, char *event, char *data) +{ + struct sip_history *hist, *prev; + char *c; + if (!recordhistory) + return 0; + hist = malloc(sizeof(struct sip_history)); + if (hist) { + memset(hist, 0, sizeof(struct sip_history)); + snprintf(hist->event, sizeof(hist->event), "%-15s %s", event, data); + /* Trim up nicely */ + c = hist->event; + while(*c) { + if ((*c == '\r') || (*c == '\n')) { + *c = '\0'; + break; + } + c++; + } + /* Enqueue into history */ + prev = p->history; + if (prev) { + while(prev->next) + prev = prev->next; + prev->next = hist; + } else { + p->history = hist; + } + } + return 0; +} + static int retrans_pkt(void *data) { struct sip_pkt *pkt=data; @@ -536,10 +576,12 @@ static int retrans_pkt(void *data) else ast_verbose("Retransmitting #%d (no NAT):\n%s\n to %s:%d\n", pkt->retrans, pkt->data, inet_ntoa(pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port)); } + append_history(pkt->owner, "ReTx", pkt->data); __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); res = 1; } else { ast_log(LOG_WARNING, "Maximum retries exceeded on call %s for seqno %d (%s %s)\n", pkt->owner->callid, pkt->seqno, (pkt->flags & FLAG_FATAL) ? "Critical" : "Non-critical", (pkt->flags & FLAG_RESPONSE) ? "Response" : "Request"); + append_history(pkt->owner, "MaxRetries", pkt->flags & FLAG_FATAL ? "(Critical)" : "(Non-critical)"); pkt->retransid = -1; if (pkt->flags & FLAG_FATAL) { while(pkt->owner->owner && ast_mutex_trylock(&pkt->owner->owner->lock)) { @@ -597,6 +639,7 @@ static int __sip_autodestruct(void *data) struct sip_pvt *p = data; p->autokillid = -1; ast_log(LOG_DEBUG, "Auto destroying call '%s'\n", p->callid); + append_history(p, "AutoDestroy", ""); if (p->owner) { ast_log(LOG_WARNING, "Autodestruct on call '%s' with owner in place\n", p->callid); ast_queue_hangup(p->owner); @@ -608,8 +651,13 @@ static int __sip_autodestruct(void *data) static int sip_scheddestroy(struct sip_pvt *p, int ms) { + char tmp[80]; if (sip_debug_test_pvt(p)) ast_verbose("Scheduling destruction of call '%s' in %d ms\n", p->callid, ms); + if (recordhistory) { + snprintf(tmp, sizeof(tmp), "%d ms", ms); + append_history(p, "SchedDestroy", tmp); + } if (p->autokillid > -1) ast_sched_del(sched, p->autokillid); p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); @@ -620,6 +668,7 @@ static int sip_cancel_destroy(struct sip_pvt *p) { if (p->autokillid > -1) ast_sched_del(sched, p->autokillid); + append_history(p, "CancelDestroy", ""); p->autokillid = -1; return 0; } @@ -684,10 +733,13 @@ static int send_response(struct sip_pvt *p, struct sip_request *req, int reliabl else ast_verbose("%sTransmitting (no NAT):\n%s\n to %s:%d\n", reliable ? "Reliably " : "", req->data, inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); } - if (reliable) + if (reliable) { + append_history(p, "TxRespRel", req->data); res = __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable > 1)); - else + } else { + append_history(p, "TxResp", req->data); res = __sip_xmit(p, req->data, req->len); + } if (res > 0) res = 0; return res; @@ -702,10 +754,13 @@ static int send_request(struct sip_pvt *p, struct sip_request *req, int reliable else ast_verbose("%sTransmitting:\n%s (no NAT) to %s:%d\n", reliable ? "Reliably " : "", req->data, inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); } - if (reliable) + if (reliable) { + append_history(p, "TxReqRel", req->data); res = __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1)); - else + } else { + append_history(p, "TxReq", req->data); res = __sip_xmit(p, req->data, req->len); + } return res; } @@ -1170,6 +1225,7 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner) { struct sip_pvt *cur, *prev = NULL; struct sip_pkt *cp; + struct sip_history *hist; if (sip_debug_test_pvt(p)) ast_verbose("Destroying call '%s'\n", p->callid); if (p->stateid > -1) @@ -1210,6 +1266,12 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner) if (lockowner) ast_mutex_unlock(&p->owner->lock); } + /* Clear history */ + while(p->history) { + hist = p->history; + p->history = p->history->next; + free(hist); + } cur = iflist; while(cur) { if (cur == p) { @@ -4993,6 +5055,7 @@ static int sip_show_channel(int fd, int argc, char *argv[]) struct sip_pvt *cur; char tmp[256]; size_t len; + int found = 0; if (argc != 4) return RESULT_SHOWUSAGE; len = strlen(argv[3]); @@ -5036,11 +5099,53 @@ static int sip_show_channel(int fd, int argc, char *argv[]) if (cur->dtmfmode & SIP_DTMF_INBAND) strcat(tmp, "inband "); ast_cli(fd, " DTMF Mode: %s\n\n", tmp); + found++; } cur = cur->next; } ast_mutex_unlock(&iflock); - if (!cur) + if (!found) + ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); + return RESULT_SUCCESS; +} + +/*--- sip_show_channel: Show details of one call ---*/ +static int sip_show_history(int fd, int argc, char *argv[]) +{ + struct sip_pvt *cur; + struct sip_history *hist; + size_t len; + int x; + int found = 0; + if (argc != 4) + return RESULT_SHOWUSAGE; + if (!recordhistory) + ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); + len = strlen(argv[3]); + ast_mutex_lock(&iflock); + cur = iflist; + while(cur) { + if (!strncasecmp(cur->callid, argv[3],len)) { + ast_cli(fd,"\n"); + if (cur->subscribed) + ast_cli(fd, " * Subscription\n"); + else + ast_cli(fd, " * SIP Call\n"); + x = 0; + hist = cur->history; + while(hist) { + x++; + ast_cli(fd, "%d. %s\n", x, hist->event); + hist = hist->next; + } + if (!x) + ast_cli(fd, "Call '%s' has no history\n", cur->callid); + found++; + } + cur = cur->next; + } + ast_mutex_unlock(&iflock); + if (!found) ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); return RESULT_SUCCESS; } @@ -5186,6 +5291,26 @@ static int sip_do_debug(int fd, int argc, char *argv[]) return RESULT_SUCCESS; } +static int sip_do_history(int fd, int argc, char *argv[]) +{ + if (argc != 2) { + return RESULT_SHOWUSAGE; + } + recordhistory = 1; + ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); + return RESULT_SUCCESS; +} + +static int sip_no_history(int fd, int argc, char *argv[]) +{ + if (argc != 3) { + return RESULT_SHOWUSAGE; + } + recordhistory = 0; + ast_cli(fd, "SIP History Recording Disabled\n"); + return RESULT_SUCCESS; +} + static int sip_no_debug(int fd, int argc, char *argv[]) { if (argc != 3) @@ -5374,6 +5499,10 @@ static char show_channel_usage[] = "Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n"; +static char show_history_usage[] = +"Usage: sip show history <channel>\n" +" Provides detailed dialog history on a given SIP channel.\n"; + static char show_peers_usage[] = "Usage: sip show peers\n" " Lists all known SIP peers.\n"; @@ -5399,6 +5528,15 @@ static char no_debug_usage[] = "Usage: sip no debug\n" " Disables dumping of SIP packets for debugging purposes\n"; +static char no_history_usage[] = +"Usage: sip no history\n" +" Disables recording of SIP dialog history for debugging purposes\n"; + +static char history_usage[] = +"Usage: sip history\n" +" Enables recording of SIP dialog history for debugging purposes.\n" +"Use 'sip show hitory' to view the history of a call number.\n"; + static char sip_reload_usage[] = "Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"; @@ -5416,6 +5554,8 @@ static struct ast_cli_entry cli_show_channels = { { "sip", "show", "channels", NULL }, sip_show_channels, "Show active SIP channels", show_channels_usage}; static struct ast_cli_entry cli_show_channel = { { "sip", "show", "channel", NULL }, sip_show_channel, "Show detailed SIP channel info", show_channel_usage, complete_sipch }; +static struct ast_cli_entry cli_show_history = + { { "sip", "show", "history", NULL }, sip_show_history, "Show SIP dialog history", show_history_usage, complete_sipch }; static struct ast_cli_entry cli_debug_ip = { { "sip", "debug", "ip", NULL }, sip_do_debug, "Enable SIP debugging on IP", debug_usage }; static struct ast_cli_entry cli_debug_peer = @@ -5436,6 +5576,10 @@ static struct ast_cli_entry cli_show_registry = { { "sip", "show", "registry", NULL }, sip_show_registry, "Show SIP registration status", show_reg_usage }; static struct ast_cli_entry cli_debug = { { "sip", "debug", NULL }, sip_do_debug, "Enable SIP debugging", debug_usage }; +static struct ast_cli_entry cli_history = + { { "sip", "history", NULL }, sip_do_history, "Enable SIP history", history_usage }; +static struct ast_cli_entry cli_no_history = + { { "sip", "no", "history", NULL }, sip_no_history, "Disable SIP history", no_history_usage }; static struct ast_cli_entry cli_no_debug = { { "sip", "no", "debug", NULL }, sip_no_debug, "Disable SIP debugging", no_debug_usage }; @@ -6338,6 +6482,7 @@ retrylock: goto retrylock; } memcpy(&p->recv, &sin, sizeof(p->recv)); + append_history(p, "Rx", req.data); handle_request(p, &req, &sin, &recount); if (p->owner) ast_mutex_unlock(&p->owner->lock); @@ -7531,6 +7676,7 @@ int load_module() ast_cli_register(&cli_show_subscriptions); ast_cli_register(&cli_show_channels); ast_cli_register(&cli_show_channel); + ast_cli_register(&cli_show_history); ast_cli_register(&cli_show_peer); ast_cli_register(&cli_show_peers); ast_cli_register(&cli_show_peers_begin); @@ -7541,6 +7687,8 @@ int load_module() ast_cli_register(&cli_debug_ip); ast_cli_register(&cli_debug_peer); ast_cli_register(&cli_no_debug); + ast_cli_register(&cli_history); + ast_cli_register(&cli_no_history); ast_cli_register(&cli_sip_reload); ast_cli_register(&cli_inuse_show); sip_rtp.type = type; @@ -7571,6 +7719,7 @@ int unload_module() ast_cli_unregister(&cli_show_users); ast_cli_unregister(&cli_show_channels); ast_cli_unregister(&cli_show_channel); + ast_cli_unregister(&cli_show_history); ast_cli_unregister(&cli_show_peer); ast_cli_unregister(&cli_show_peers); ast_cli_unregister(&cli_show_peers_include); @@ -7582,6 +7731,8 @@ int unload_module() ast_cli_unregister(&cli_debug_ip); ast_cli_unregister(&cli_debug_peer); ast_cli_unregister(&cli_no_debug); + ast_cli_unregister(&cli_history); + ast_cli_unregister(&cli_no_history); ast_cli_unregister(&cli_sip_reload); ast_cli_unregister(&cli_inuse_show); ast_rtp_proto_unregister(&sip_rtp); |