Put sip history stuff in (for real) and provide voicemail context (when not default...
authorMark Spencer <markster@digium.com>
Wed, 12 May 2004 00:17:31 +0000 (00:17 +0000)
committerMark Spencer <markster@digium.com>
Wed, 12 May 2004 00:17:31 +0000 (00:17 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2950 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_voicemail.c
channels/chan_sip.c

index fb36366..44b49f2 100755 (executable)
@@ -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);
index 79f4614..c38a369 100755 (executable)
@@ -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);