summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Spencer <markster@digium.com>2004-05-12 00:17:31 +0000
committerMark Spencer <markster@digium.com>2004-05-12 00:17:31 +0000
commit10c25aa6d983f67c1c04f389d10679459b4edf8d (patch)
tree7f238412a5e029b65c8a187d2408e9134306407d
parent34e400fe2bffb5cc22e4017590247a1fc1712e38 (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-xapps/app_voicemail.c21
-rwxr-xr-xchannels/chan_sip.c161
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);