Cleanup formatting in bug 2741 patch
[asterisk/asterisk.git] / res / res_features.c
index 7cab65b..f79d2b4 100755 (executable)
@@ -27,6 +27,7 @@
 #include <asterisk/cli.h>
 #include <asterisk/manager.h>
 #include <asterisk/utils.h>
+#include <asterisk/adsi.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
@@ -59,6 +60,8 @@ static int parking_start = 701;
 /* Last available extension for parking */
 static int parking_stop = 750;
 
+static int adsipark = 0;
+
 static int transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
 
 /* Default courtesy tone played when party joins conference */
@@ -87,6 +90,9 @@ static char *descrip2 = "Park(exten):"
 "into the dialplan, although you should include the 'parkedcalls'\n"
 "context.\n";
 
+static struct ast_app *monitor_app=NULL;
+static int monitor_ok=1;
+
 struct parkeduser {
        struct ast_channel *chan;
        struct timeval start;
@@ -120,6 +126,22 @@ char *ast_pickup_ext(void)
        return pickup_ext;
 }
 
+static int adsi_announce_park(struct ast_channel *chan, int parkingnum)
+{
+       int res;
+       int justify[5] = {ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT, ADSI_JUST_CENT};
+       char tmp[256] = "";
+       char *message[5] = {NULL, NULL, NULL, NULL, NULL};
+
+       snprintf(tmp, sizeof(tmp), "Parked on %d", parkingnum);
+       message[0] = tmp;
+       res = adsi_load_session(chan, NULL, 0, 1);
+       if (res == -1) {
+               return res;
+       }
+       return adsi_print(chan, message, justify, 1);
+}
+
 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
 {
        /* We put the user in the parking list, then wake up the parking thread to be sure it looks
@@ -159,11 +181,11 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
                                *extout = x;
                        /* Remember what had been dialed, so that if the parking
                           expires, we try to come back to the same place */
-                       if (strlen(chan->macrocontext))
+                       if (!ast_strlen_zero(chan->macrocontext))
                                strncpy(pu->context, chan->macrocontext, sizeof(pu->context)-1);
                        else
                                strncpy(pu->context, chan->context, sizeof(pu->context)-1);
-                       if (strlen(chan->macroexten))
+                       if (!ast_strlen_zero(chan->macroexten))
                                strncpy(pu->exten, chan->macroexten, sizeof(pu->exten)-1);
                        else
                                strncpy(pu->exten, chan->exten, sizeof(pu->exten)-1);
@@ -180,7 +202,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
                        /* Wake up the (presumably select()ing) thread */
                        pthread_kill(parking_thread, SIGURG);
                        if (option_verbose > 1) 
-                               ast_verbose(VERBOSE_PREFIX_2 "Parked %s on %d\n", pu->chan->name, pu->parkingnum);
+                               ast_verbose(VERBOSE_PREFIX_2 "Parked %s on %d. Will timeout back to %s,%s,%d in %d seconds\n", pu->chan->name, pu->parkingnum, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
 
                        manager_event(EVENT_FLAG_CALL, "ParkedCall",
                                 "Exten: %d\r\n"
@@ -188,13 +210,21 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
                                 "From: %s\r\n"
                                 "Timeout: %ld\r\n"
                                 "CallerID: %s\r\n"
+                                "CallerIDName: %s\r\n\r\n"
                                 ,pu->parkingnum, pu->chan->name, peer->name
                                 ,(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL)
-                                ,(pu->chan->callerid ? pu->chan->callerid : "")
+                                ,(pu->chan->cid.cid_num ? pu->chan->cid.cid_num : "")
+                                ,(pu->chan->cid.cid_name ? pu->chan->cid.cid_name : "")
                                 );
 
                        if (peer) {
+                               if (adsipark && adsi_available(peer)) {
+                                       adsi_announce_park(peer, pu->parkingnum);
+                               }
                                ast_say_digits(peer, pu->parkingnum, "", peer->language);
+                               if (adsipark && adsi_available(peer)) {
+                                       adsi_unload_session(peer);
+                               }
                                if (pu->notquiteyet) {
                                        /* Wake up parking thread if we're really done */
                                        ast_moh_start(pu->chan, NULL);
@@ -211,7 +241,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
                        }
                        if (con) {
                                snprintf(exten, sizeof(exten), "%d", x);
-                               ast_add_extension2(con, 1, exten, 1, NULL, parkedcall, strdup(exten), free, registrar);
+                               ast_add_extension2(con, 1, exten, 1, NULL, NULL, parkedcall, strdup(exten), free, registrar);
                        }
                        return 0;
                } else {
@@ -272,7 +302,25 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
        struct timeval start, end;
        char *transferer_real_context;
        int allowdisconnect_in,allowdisconnect_out,allowredirect_in,allowredirect_out;
-
+       char *monitor_exec;
+
+       if (chan && peer) {
+               pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
+               pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
+       } else if (chan)
+               pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
+
+       if (monitor_ok) {
+               if (!monitor_app) { 
+                       if (!(monitor_app = pbx_findapp("Monitor")))
+                               monitor_ok=0;
+               }
+               if ((monitor_exec = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR"))) 
+                       pbx_exec(chan, monitor_app, monitor_exec, 1);
+               else if ((monitor_exec = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR")))
+                       pbx_exec(peer, monitor_app, monitor_exec, 1);
+       }
+       
        allowdisconnect_in = config->allowdisconnect_in;
        allowdisconnect_out = config->allowdisconnect_out;
        allowredirect_in = config->allowredirect_in;
@@ -285,9 +333,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
        peer->appl = "Bridged Call";
        peer->data = chan->name;
        /* copy the userfield from the B-leg to A-leg if applicable */
-       if (chan->cdr && peer->cdr && strlen(peer->cdr->userfield)) {
+       if (chan->cdr && peer->cdr && !ast_strlen_zero(peer->cdr->userfield)) {
                char tmp[256];
-               if (strlen(chan->cdr->userfield)) {
+               if (!ast_strlen_zero(chan->cdr->userfield)) {
                        snprintf(tmp, sizeof(tmp), "%s;%s",chan->cdr->userfield, peer->cdr->userfield);
                        ast_cdr_appenduserfield(chan, tmp);
                } else
@@ -360,21 +408,20 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
                if ((f->frametype == AST_FRAME_DTMF) &&
                        ((allowredirect_in && who == peer) || (allowredirect_out && who == chan)) &&
                        (f->subclass == '#')) {
-                               if(allowredirect_in &&  who == peer) {
+                               if (allowredirect_in &&  who == peer) {
                                        transferer = peer;
                                        transferee = chan;
-                               }
-                               else {
+                               } else {
                                        transferer = chan;
                                        transferee = peer;
                                }
-                               if(!(transferer_real_context=pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT")) &&
+                               if (!(transferer_real_context=pbx_builtin_getvar_helper(transferee, "TRANSFER_CONTEXT")) &&
                                   !(transferer_real_context=pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT"))) {
                                        /* Use the non-macro context to transfer the call */
-                                       if(strlen(transferer->macrocontext))
-                                               transferer_real_context=transferer->macrocontext;
+                                       if (!ast_strlen_zero(transferer->macrocontext))
+                                               transferer_real_context = transferer->macrocontext;
                                        else
-                                               transferer_real_context=transferer->context;
+                                               transferer_real_context = transferer->context;
                                }
                                /* Start autoservice on chan while we talk
                                   to the originator */
@@ -403,7 +450,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
                                        len --;
                                }
                                res = 0;
-                               while(strlen(newext) < sizeof(newext) - 1) {
+                               while (strlen(newext) < sizeof(newext) - 1) {
                                        res = ast_waitfordigit(transferer, transferdigittimeout);
                                        if (res < 1) 
                                                break;
@@ -411,7 +458,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
                                                break;
                                        *(ptr++) = res;
                                        if (!ast_matchmore_extension(transferer, transferer_real_context
-                                                               , newext, 1, transferer->callerid)) {
+                                                               , newext, 1, transferer->cid.cid_num)) {
                                                break;
                                        }
                                }
@@ -431,7 +478,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
                                                   the thread dies -- We have to be careful now though.  We are responsible for 
                                                   hanging up the channel, else it will never be hung up! */
 
-                                               if(transferer==peer)
+                                               if (transferer==peer)
                                                        res=AST_PBX_KEEPALIVE;
                                                else
                                                        res=AST_PBX_NO_HANGUP_PEER;
@@ -440,7 +487,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
                                                ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name);
                                        }
                                        /* XXX Maybe we should have another message here instead of invalid extension XXX */
-                               } else if (ast_exists_extension(transferee, transferer_real_context, newext, 1, transferer->callerid)) {
+                               } else if (ast_exists_extension(transferee, transferer_real_context, newext, 1, transferer->cid.cid_num)) {
+                                       pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name);
+                                       pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
                                        ast_moh_stop(transferee);
                                        res=ast_autoservice_stop(transferee);
                                        if (!transferee->pbx) {
@@ -535,6 +584,8 @@ static void *do_parking_thread(void *ignore)
                                strncpy(pu->chan->exten, pu->exten, sizeof(pu->chan->exten)-1);
                                strncpy(pu->chan->context, pu->context, sizeof(pu->chan->context)-1);
                                pu->chan->priority = pu->priority;
+                               if (option_verbose > 1) 
+                                       ast_verbose(VERBOSE_PREFIX_2 "Timeout for %s parked on %d. Returning to %s,%s,%d\n", pu->chan->name, pu->parkingnum, pu->chan->context, pu->chan->exten, pu->chan->priority);
                                /* Stop music on hold */
                                ast_moh_stop(pu->chan);
                                /* Start up the PBX, or hang them up */
@@ -795,19 +846,23 @@ static int manager_parking_status( struct mansession *s, struct message *m )
 
         cur=parkinglot;
         while(cur) {
+                       ast_mutex_lock(&s->lock);
                 ast_cli(s->fd, "Event: ParkedCall\r\n"
                        "Exten: %d\r\n"
                        "Channel: %s\r\n"
                        "Timeout: %ld\r\n"
                        "CallerID: %s\r\n"
+                       "CallerIDName: %s\r\n"
                        "%s"
                        "\r\n"
                         ,cur->parkingnum, cur->chan->name
                         ,(long)cur->start.tv_sec + (long)(cur->parkingtime/1000) - (long)time(NULL)
-                       ,(cur->chan->callerid ? cur->chan->callerid : "")
+                       ,(cur->chan->cid.cid_num ? cur->chan->cid.cid_num : "")
+                       ,(cur->chan->cid.cid_name ? cur->chan->cid.cid_name : "")
                        ,idText);
+                       ast_mutex_unlock(&s->lock);
 
-                cur = cur->next;
+            cur = cur->next;
         }
 
        ast_cli(s->fd,
@@ -858,14 +913,18 @@ int load_module(void)
                                        parking_start = start;
                                        parking_stop = end;
                                }
-                       } else if(!strcasecmp(var->name, "transferdigittimeout")) {
+                       } else if (!strcasecmp(var->name, "adsipark")) {
+                               adsipark = ast_true(var->value);
+                       } else if (!strcasecmp(var->name, "transferdigittimeout")) {
                                if ((sscanf(var->value, "%d", &transferdigittimeout) != 1) || (transferdigittimeout < 1)) {
                                        ast_log(LOG_WARNING, "%s is not a valid transferdigittimeout\n", var->value);
                                        transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
                                } else
                                        transferdigittimeout = transferdigittimeout * 1000;
-                       } else if  (!strcasecmp(var->name, "courtesytone")) {
+                       } else if (!strcasecmp(var->name, "courtesytone")) {
                                strncpy(courtesytone, var->value, sizeof(courtesytone) - 1);
+                       } else if (!strcasecmp(var->name, "pickupexten")) {
+                               strncpy(pickup_ext, var->value, sizeof(pickup_ext) - 1);
                        }
                        var = var->next;
                }
@@ -879,7 +938,7 @@ int load_module(void)
                        return -1;
                }
        }
-       ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, parkcall, strdup(""),free, registrar);
+       ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""),free, registrar);
        ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
        res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
        if (!res)