Try this

Since www.bkw.org seems not to exist anymore (getting response from some hosting provider), does anyone happend to have a copy of app_valetparking.c from www.bkw.org - the one that should work with * stable 1.0.X ? If so please contact me.

One that can be downloaded from www.loligo.com dosn't compile with 1.0.X, and SuperValletParking (www.asterlink.com/svp/) seems to be for * HEAD (1.1.X), so it wont do me any good.


/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * Routines implementing call valetparking
 * 
 * Copyright (C) 1999, Mark Spencer
 *
 * Mark Spencer <[EMAIL PROTECTED]>
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 */

#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/options.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/say.h>
#include <asterisk/callerid.h>
#include <asterisk/channel_pvt.h>
#include <asterisk/parking.h>
#include <asterisk/musiconhold.h>
#include <asterisk/config.h>
#include <asterisk/cli.h>
#include <asterisk/app.h>
#include <asterisk/manager.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <netinet/in.h>

#include <pthread.h>

#define DEFAULT_VALETPARK_TIME 45000

static char *valetparking = "ValetParking";
static char *valetparkedcall = "ValetParkCall";
static char *valetunparkedcall = "ValetUnparkCall";
static char *valetparklist = "ValetParkList";

/* No more than 45 seconds valetparked before you do something with them */
static int valetparkingtime = DEFAULT_VALETPARK_TIME;

/* First available extension for valetparking */
static int valetparking_start = 1;

/* Last available extension for valetparking */
static int valetparking_stop = 10000;

static char *vpsynopsis = "Valet Parking";

static char *vpcsynopsis = "Valet Park Call";

static char *vupsynopsis = "Valet UnPark Call";

static char *vlsynopsis = "ValetParkList";

static char *vpdesc =
"ValetParking(<exten>|<lotname>|<timeout>[|<return_ext>][|<return_pri>][|<return_context>])\n"
"Auto-Sense Valet Parking: if <exten> is not occupied, park it, if it is 
already parked, bridge to it.\n\n";

static char *vpcdesc =
"ValetParkCall(<exten>|<lotname>|<timeout>[|<return_ext>][|<return_pri>][|<return_context>])\n"
"Park Call at <exten> in <lotname> until someone calls ValetUnparkCall on the 
same <exten> + <lotname>\n"
"set <exten> to 'auto' to auto-choose the slot.\n\n";

static char *vupdesc =
"ValetUnparkCall(<exten>|<lotname>)\n"
"Un-Park the call at <exten> in lot <lotname> use 'fifo' or 'filo' for 
auto-ordered Un-Park.\n\n";

static char *vldesc =
"ValetParkList(<lotname>)\n"
"Audibly list the slot number of all the calls in <lotname> press * to unpark 
it.\n\n";

struct valetparkeduser {
        struct ast_channel *chan;
        struct timeval start;
        int valetparkingnum;
        /* Where to go if our valetparking time expires */
        char context[AST_MAX_EXTENSION];
        char exten[AST_MAX_EXTENSION];
        char lotname[AST_MAX_EXTENSION];
        int priority;
        int valetparkingtime;
        struct valetparkeduser *next;
};

static struct valetparkeduser *valetparkinglot;

static ast_mutex_t valetparking_lock = AST_MUTEX_INITIALIZER;

static pthread_t valetparking_thread;

STANDARD_LOCAL_USER;

LOCAL_USER_DECL;

static int valetparking_count(void)
{
        struct valetparkeduser *cur;
        int x=0;
        ast_mutex_lock(&valetparking_lock);
        for(cur = valetparkinglot;cur;cur = cur->next)
                x++;
        ast_mutex_unlock(&valetparking_lock);
        return x;
}

static int valetparking_say(struct ast_channel *chan,char *lotname)
{
        struct valetparkeduser *cur;
        int x=0,y=0,res=0;
        int list[1024];
        if(!lotname)
                return 0;
        ast_mutex_lock(&valetparking_lock);
        for(cur = valetparkinglot;cur;cur = cur->next)
                if(cur->lotname && !strcmp(lotname,cur->lotname))
                        list[y++] = cur->valetparkingnum;
        ast_mutex_unlock(&valetparking_lock);
        for(x=0;x<y;x++) {
                ast_say_digits(chan,list[x], "", chan->language);
                res = ast_waitfordigit(chan,1500);
                if(res != 0) {
                        res = list[x];
                        break;
                }
        }
        return res;
}

static int ast_pop_valetparking_top(char *lotname)
{
        struct valetparkeduser *cur;

        ast_mutex_lock(&valetparking_lock);
        for(cur = valetparkinglot;cur;cur = cur->next)
                if(cur->lotname && !strcmp(lotname,cur->lotname))
                        break;

        ast_mutex_unlock(&valetparking_lock);
        return cur ? cur->valetparkingnum : 0;
}

static int ast_pop_valetparking_bot(char *lotname)
{
        struct valetparkeduser *cur,*last=NULL;
        ast_mutex_lock(&valetparking_lock);
        for(cur = valetparkinglot;cur;cur = cur->next) {
                if(cur->lotname && !strcmp(lotname,cur->lotname)) {
                        last = cur;
                }
        }
        ast_mutex_unlock(&valetparking_lock);
        return last ? last->valetparkingnum : 0;
}

static int ast_is_valetparked(char *exten,char *lotname)
{
        struct valetparkeduser *cur;
        int ext=0;
        int ret = 0;
        ext = atoi(exten);
        if(! ext > 0) {
                return ret;
        }
        ast_mutex_lock(&valetparking_lock);
        cur = valetparkinglot;
        while(cur) {
                if (cur->valetparkingnum == ext && lotname && cur->lotname && 
!strcmp(lotname,cur->lotname)) {
                        ret = 1;
                        break;
                }
                cur = cur->next;
        }
        ast_mutex_unlock(&valetparking_lock);
        return ret;
}

static int ast_valetpark_call(struct ast_channel *chan, int timeout, int 
*extout,char *lotname)
{
        /* We put the user in the valetparking list, then wake up the 
valetparking thread to be sure it looks
           after these channels too */
        struct valetparkeduser *pu, *cur;
        int x;

        x = *extout;
        pu = malloc(sizeof(struct valetparkeduser));
        if (pu) {
                memset(pu,0,sizeof(struct valetparkeduser));
                ast_mutex_lock(&valetparking_lock);
                if(lotname) {
                        strncpy(pu->lotname,lotname,sizeof(pu->lotname));
                        if(chan->exten) 
                                
strncpy(pu->exten,chan->exten,sizeof(pu->exten)-1);
                        if(chan->context)
                                
strncpy(pu->context,chan->context,sizeof(pu->context)-1);
                        
                        pu->priority = chan->priority;

                        x = *extout;
                        if(x == -1) {
                                for 
(x=valetparking_start;x<=valetparking_stop;x++) {
                                        for(cur = 
valetparkinglot;cur;cur=cur->next) {
                                                if (cur->valetparkingnum == x 
&& cur->lotname && !strcmp(cur->lotname,lotname))
                                                        break;
                                        }
                                        if (!cur)
                                                break;
                                }
                        }
                }
                if (x <= valetparking_stop) {
                        chan->appl = "Valet Parked Call";
                        chan->data = NULL; 

                        pu->chan = chan;
                        /* Start music on hold */
                        ast_moh_start(pu->chan, NULL);
                        gettimeofday(&pu->start, NULL);
                        pu->valetparkingnum = x;
                        if (timeout >= 0)
                                pu->valetparkingtime = timeout;
                        else
                                pu->valetparkingtime = valetparkingtime;

                        *extout = x;
                        /* Remember what had been dialed, so that if the 
valetparking
                           expires, we try to come back to the same place */
                        if (strlen(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))
                                strncpy(pu->exten, chan->macroexten, 
sizeof(pu->exten)-1);
                        else
                                strncpy(pu->exten, chan->exten, 
sizeof(pu->exten)-1);
                        if (chan->macropriority)
                                pu->priority = chan->macropriority;
                        else
                                pu->priority = chan->priority;
                        pu->next = valetparkinglot;
                        valetparkinglot = pu;
                        ast_mutex_unlock(&valetparking_lock);
                        /* Wake up the (presumably select()ing) thread */
                        pthread_kill(valetparking_thread, SIGURG);
                        if (option_verbose > 1) 
                                ast_verbose(VERBOSE_PREFIX_2 "Valet Parked %s 
on slot %d\n", pu->chan->name, pu->valetparkingnum);

                                manager_event(EVENT_FLAG_CALL, 
"VirtualValetparkedCall",
                                                          "Exten: %d\r\n"
                                                          "Channel: %s\r\n"
                                                          "LotName: %s\r\n"
                                                          "Timeout: %ld\r\n"
                                                          "CallerID: %s\r\n"
                                                          ,pu->valetparkingnum, 
pu->chan->name, lotname
                                                          
,(long)pu->start.tv_sec + (long)(pu->valetparkingtime/1000) - (long)time(NULL)
                                                          ,(pu->chan->callerid 
? pu->chan->callerid : "")
                                                          );
                                return 0;
                } else {
                        ast_log(LOG_WARNING, "No more valetparking spaces\n");
                        free(pu);
                        ast_mutex_unlock(&valetparking_lock);
                        return -1;
                }
        } else {
                ast_log(LOG_WARNING, "Out of memory\n");
                return -1;
        }
        return 0;
}

static int ast_masq_valetpark_call(struct ast_channel *rchan,int timeout, int 
*extout,char *lotname)
{
        struct ast_channel *chan;
        struct ast_frame *f;

        /* Make a new, fake channel that we'll use to masquerade in the real 
one */
        chan = ast_channel_alloc(0);
        if (chan) {
                /* Let us keep track of the channel name */
                snprintf(chan->name, sizeof (chan->name), 
"ValetParked/%s",rchan->name);
                /* Make formats okay */
                chan->readformat = rchan->readformat;
                chan->writeformat = rchan->writeformat;
                ast_channel_masquerade(chan, rchan);
                /* Setup the extensions and such */
                strncpy(chan->context, rchan->context, sizeof(chan->context) - 
1);
                strncpy(chan->exten, rchan->exten, sizeof(chan->exten) - 1);
                chan->priority = rchan->priority;
                /* Make the masq execute */
                f = ast_read(chan);
                if (f)
                        ast_frfree(f);
                ast_valetpark_call(chan, timeout, extout,lotname);
        } else {
                ast_log(LOG_WARNING, "Unable to create Valet Parked channel\n");
                return -1;
        }
        return 0;
}

static void *do_valetparking_thread(void *ignore)
{
        int ms, tms, max;
        struct valetparkeduser *pu, *pl, *pt = NULL;
        struct timeval tv;
        struct ast_frame *f;
        int x;
        int gc=0;
        fd_set rfds, efds;
        fd_set nrfds, nefds;
        FD_ZERO(&rfds);
        FD_ZERO(&efds);
        for (;;) {
                ms = -1;
                max = -1;
                ast_mutex_lock(&valetparking_lock);
                pl = NULL;
                pu = valetparkinglot;
                gettimeofday(&tv, NULL);
                FD_ZERO(&nrfds);
                FD_ZERO(&nefds);
                while(pu) {
                        tms = (tv.tv_sec - pu->start.tv_sec) * 1000 + 
(tv.tv_usec - pu->start.tv_usec) / 1000;

                        if(gc < 5 && !pu->chan->generator) {
                                gc++;
                                ast_moh_start(pu->chan,NULL);
                        }
                        if(pu->valetparkingtime > 0 && tms > 
pu->valetparkingtime) {
                                /* They've been waiting too long, send them 
back to where they came.  Theoretically they
                                   should have their original extensions and 
such, but we copy to be on the safe side */
                                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;
                                /* Stop music on hold */
                                ast_moh_stop(pu->chan);
                                /* Start up the PBX, or hang them up */
                                if (ast_pbx_start(pu->chan))  {
                                        ast_log(LOG_WARNING, "Unable to restart 
the PBX for user on '%s', hanging them up...\n", pu->chan->name);
                                        ast_hangup(pu->chan);
                                }
                                /* And take them out of the valetparking lot */
                                if (pl) 
                                        pl->next = pu->next;
                                else
                                        valetparkinglot = pu->next;
                                pt = pu;
                                pu = pu->next;
                                free(pt);
                        } else {
                                for (x=0;x<AST_MAX_FDS;x++) {
                                        if ((pu->chan->fds[x] > -1) && 
(FD_ISSET(pu->chan->fds[x], &rfds) || FD_ISSET(pu->chan->fds[x], &efds))) {
                                                if (FD_ISSET(pu->chan->fds[x], 
&efds))
                                                        pu->chan->exception = 1;
                                                pu->chan->fdno = x;
                                                /* See if they need servicing */
                                                f = ast_read(pu->chan);
                                                if (!f || ((f->frametype == 
AST_FRAME_CONTROL) && (f->subclass ==  AST_CONTROL_HANGUP))) {
                                                        /* There's a problem, 
hang them up*/
                                                        if (option_verbose > 1) 
                                                                
ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being Valet Parked\n", 
pu->chan->name);
                                                        ast_hangup(pu->chan);
                                                        /* And take them out of 
the valetparking lot */
                                                        if (pl) 
                                                                pl->next = 
pu->next;
                                                        else
                                                                valetparkinglot 
= pu->next;
                                                        pt = pu;
                                                        pu = pu->next;
                                                        free(pt);
                                                        break;
                                                } else {
                                                        /* XXX Maybe we could 
do something with packets, like dial "0" for operator or something XXX */
                                                        ast_frfree(f);
                                                        goto std;       /* XXX 
Ick: jumping into an else statement??? XXX */
                                                }
                                        }
                                }
                                if (x >= AST_MAX_FDS) {
std:                                    for (x=0;x<AST_MAX_FDS;x++) {
                                                /* Keep this one for next one */
                                                if (pu->chan->fds[x] > -1) {
                                                        
FD_SET(pu->chan->fds[x], &nrfds);
                                                        
FD_SET(pu->chan->fds[x], &nefds);
                                                        if (pu->chan->fds[x] > 
max)
                                                                max = 
pu->chan->fds[x];
                                                }
                                        }
                                        /* Keep track of our longest wait */
                                        if ((tms < ms) || (ms < 0))
                                                ms = tms;
                                        pl = pu;
                                        pu = pu->next;
                                }
                        }
                }
                ast_mutex_unlock(&valetparking_lock);
                rfds = nrfds;
                efds = nefds;
                tv.tv_sec = ms / 1000;
                tv.tv_usec = (ms % 1000) * 1000;
                /* Wait for something to happen */
                ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
                pthread_testcancel();
        }
        return NULL;    /* Never reached */
}

static int ast_valetparking(struct ast_channel *chan, void *data) 
{
        struct localuser *u;
        char *appname;  
        char buf[512],*exten,*lotname,*to;
        struct ast_app *app;
        int res=0;

        if (!data) {
                ast_log(LOG_WARNING, "ValetParking requires an argument 
(extension number)\n");
                return -1;
        }

        exten=lotname=to=NULL;
        strncpy(buf,data,512);
        exten = buf;
        if((lotname=strchr(exten,'|'))) {
                *lotname = '\0';
                *lotname++;
                if((to=strchr(lotname,'|'))) {
                        *to = '\0';
                        *to++;
                }
        }
        if(exten[0] >= 97) {
                ast_log(LOG_WARNING, "ValetParking requires a numeric 
extension.\n");
        return -1;
        }
        appname = ast_is_valetparked(exten,lotname) ? "ValetParkCall" : 
"ValetUnparkCall";
        app = pbx_findapp(appname);
        LOCAL_USER_ADD(u);
        if(app) {
                res = pbx_exec(chan,app,data,1);
        } else {
                ast_log(LOG_WARNING, "Error: Can't find app %s\n",appname);
                res = -1;
        }
        LOCAL_USER_REMOVE(u);
        return res;
}

static int valetpark_call(struct ast_channel *chan, void *data)
{
        struct localuser *u;
        int timeout = DEFAULT_VALETPARK_TIME;
        int ext = 0,res = 0;
        char 
buf[512],*exten,*lotname,*to,*findme,*context,*priority=NULL,tmp[80];
        if (!data) {
                ast_log(LOG_WARNING, "ValetParkCall requires an argument 
(extension number)\n");
                return -1;
        }
        exten=lotname=to=findme=context=NULL;
        strncpy(buf,data,512);
        exten = buf;
        if((lotname=strchr(exten,'|'))) {
        *lotname = '\0';
        *lotname++;
        if((to=strchr(lotname,'|'))) {
            *to = '\0';
            *to++;
                        timeout = atoi(to) * 1000;
                        if((findme=strchr(to,'|'))) {
                                *findme = '\0';
                                *findme++;
                                if((priority=strchr(findme,'|'))) {
                                        *priority = '\0';
                                        *priority++;
                                        if((context=strchr(priority,'|'))) {
                                                *context = '\0';
                                                *context++;
                                        }
                                }
                        }
                }
        }
        if(!lotname) {
                ast_log(LOG_WARNING,"Please specify a lotname in the 
dialplan.");
                return -1;
        }
        if(ast_is_valetparked(exten,lotname)) {
                ast_log(LOG_WARNING,"Call is already Valet Parked Here 
[%s]\n",exten);
                return -1;
        }
        LOCAL_USER_ADD(u);
        ast_answer(chan);
        if(exten && lotname) {
                if(!strcmp(exten,"auto"))
                        ext = -1;
                else if(!strcmp(exten,"query")) {
                        ast_waitfor(chan,-1);
                        memset(&tmp,0,80);
                        ast_streamfile(chan, "vm-extension", chan->language);
                        res = ast_waitstream(chan, AST_DIGIT_ANY);
                        if(res)
                                return -1;

                        ast_app_getdata(chan,"vm-then-pound",tmp,80,5000);
                        if(tmp[0])
                                ext = atoi(tmp);
                } else { 
                        ext = atoi(exten);
                }
                if(ext == 0)
                        ext = -1;
                if(findme)
                        strncpy(chan->exten,findme,sizeof(chan->exten)-1);
                if (context)
                        strncpy(chan->context, context, 
sizeof(chan->context)-1);
                if(priority) {
                        chan->priority = atoi(priority);
                        if(!chan->priority)
                                chan->priority = 1;
                }
                ast_masq_valetpark_call(chan,timeout,&ext,lotname);
        }
        LOCAL_USER_REMOVE(u);
        return 1;
}

static int valetpark_list(struct ast_channel *chan, void *data)
{
        struct localuser *u;
        int res=0;
        struct ast_app *app;
        char buf[512];
        if(!data) {
                ast_log(LOG_WARNING,"Parameter 'lotname' is required.\n");
                return -1;
        }
        LOCAL_USER_ADD(u);
        res = valetparking_say(chan,data);
        if(res > 0) {
                app = pbx_findapp("ValetUnparkCall");
                if(app) {
                        snprintf(buf,512,"%d|%s",res,(char *)data);
                        res = pbx_exec(chan,app,buf,1);
                }
        }
        LOCAL_USER_REMOVE(u);
        return 1;
}

static int valetunpark_call(struct ast_channel *chan, void *data)
{
        int res=0;
        struct localuser *u;
        struct ast_channel *peer=NULL;
        struct valetparkeduser *pu, *pl=NULL;
        int valetpark=-1;
        int dres;
        struct ast_bridge_config config;
        char buf[512],tmp[80],*exten,*lotname;
        if (!data) {
                ast_log(LOG_WARNING, "Valetpark requires an argument (extension 
number)\n");
                return -1;
        }
        exten=lotname=NULL;
        strncpy(buf,data,512);
        exten = buf;
        if((lotname=strchr(exten,'|'))) {
                *lotname = '\0';
                *lotname++;
        }
        if(!lotname) {
                ast_log(LOG_WARNING,"Please specify a lotname in the 
dialplan.");
                return -1;
        }
        LOCAL_USER_ADD(u);
        ast_answer(chan);
        if(exten) {
                if(!strcmp(exten,"fifo")) {
                        valetpark = ast_pop_valetparking_top(lotname);
                }
                else if(!strcmp(exten,"filo")) {
                        valetpark = ast_pop_valetparking_bot(lotname);
                }
                else if(!strcmp(exten,"query")) {
                        ast_waitfor(chan,-1);
                        memset(&tmp,0,80);
                        ast_streamfile(chan, "vm-extension", chan->language);
                        res = ast_waitstream(chan, AST_DIGIT_ANY);
                        if(res)
                                return -1;
                        ast_app_getdata(chan,"vm-then-pound",tmp,80,5000);
                        if(tmp[0])
                                valetpark = atoi(tmp);
                }
                else {
                        valetpark = atoi(exten);
                }

                if(valetpark == 0) {
                        ast_log(LOG_WARNING, "Nobody Valet Parked in 
%s",lotname);
                        LOCAL_USER_REMOVE(u);
                        return -1;
                }

        }
        else 
                valetpark = atoi((char *)data);
        ast_mutex_lock(&valetparking_lock);
        pu = valetparkinglot;
        while(pu) {
                if ((lotname && pu->valetparkingnum == valetpark && pu->lotname 
&& !strcmp(pu->lotname,lotname)) 
                        || (! lotname && pu->valetparkingnum == valetpark)) {
                        if (pl)
                                pl->next = pu->next;
                        else
                                valetparkinglot = pu->next;
                        break;
                }
                pl = pu;
                pu = pu->next;
        }
        ast_mutex_unlock(&valetparking_lock);
        if (pu) {
                peer = pu->chan;
                free(pu);
        }
        /* JK02: it helps to answer the channel if not already up */
        if (chan->_state != AST_STATE_UP) {
                ast_answer(chan);
        }

        if (peer) {
                ast_moh_stop(peer);
                res = ast_channel_make_compatible(chan, peer);
                if (res < 0) {
                        ast_log(LOG_WARNING, "Could not make channels %s and %s 
compatible for bridge\n", chan->name, peer->name);
                        ast_hangup(peer);
                        LOCAL_USER_REMOVE(u);
                        return -1;
                }
                /* This runs sorta backwards, since we give the incoming 
channel control, as if it
                   were the person called. */

                if (option_verbose > 2) 
                        ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to 
Valet Parked call %d in lot %s\n", chan->name, valetpark,lotname);

                memset(&config,0,sizeof(struct ast_bridge_config));
                config.allowredirect_in = 1;
                config.allowredirect_out = 1;
                config.allowdisconnect = 0;
                config.timelimit = 0;
                config.play_warning = 0;
                config.warning_freq = 0;
                config.warning_sound=NULL;
                res = ast_bridge_call(chan,peer,&config);

                /* Simulate the PBX hanging up */
                if (res != AST_PBX_NO_HANGUP_PEER)
                        ast_hangup(peer);
                LOCAL_USER_REMOVE(u);
                return res;
        } else {
                /* XXX Play a message XXX */
                dres = ast_streamfile(chan, "pbx-invalidpark", chan->language);
                if (!dres) {
                        dres = ast_waitstream(chan, "");
                } else {
                        ast_log(LOG_WARNING, "ast_streamfile of %s failed on 
%s\n", "pbx-invalidpark", chan->name);
                        res = 0;
                }
                if (option_verbose > 2) 
                        ast_verbose(VERBOSE_PREFIX_3 "Channel %s tried to talk 
to non-existant Valet Parked call %d\n", chan->name, valetpark);
                res = -1;
        }
        LOCAL_USER_REMOVE(u);
        return res;
}

static int handle_valetparkedcalls(int fd, int argc, char *argv[])
{
        struct valetparkeduser *cur;

        ast_cli(fd, "%4s %25s (%-15s %-12s %-4s) %-6s %-6s %-15s\n", "Num", 
"Channel"
                , "Context", "Extension", "Pri", "Elapsed","Timeout","LotName");

        ast_mutex_lock(&valetparking_lock);

        cur=valetparkinglot;
        while(cur) {
                ast_cli(fd, "%4d %25s (%-15s %-12s %-4d) %6lds %6lds %-15s\n"
                        ,cur->valetparkingnum, cur->chan->name, cur->context, 
cur->exten
                        ,cur->priority,(time(NULL) - 
cur->start.tv_sec),cur->valetparkingtime ? (cur->start.tv_sec +  
(cur->valetparkingtime/1000) - time(NULL)) : 0,cur->lotname);

                cur = cur->next;
        }

        ast_mutex_unlock(&valetparking_lock);

        return RESULT_SUCCESS;
}

static char showvaletparked_help[] =
"Usage: show valetparkedcalls\n"
"       Lists currently Valet Parked calls.\n";

static struct ast_cli_entry showvaletparked =
{ { "show", "valetparkedcalls", NULL }, handle_valetparkedcalls, "Lists 
valetparked calls", showvaletparked_help };
/* Dump lot status */
static int manager_valetparking_status( struct mansession *s, struct message *m 
)
{
        struct valetparkeduser *cur;

        astman_send_ack(s, m, "Valet Parked calls will follow");

        ast_mutex_lock(&valetparking_lock);

        cur=valetparkinglot;
        while(cur) {
                ast_cli(s->fd, "Event: ValetParkedCall\r\n"
                        "Exten: %d\r\n"
                        "Channel: %s\r\n"
                        "Timeout: %ld\r\n"
                        "CallerID: %s\r\n"
                        "\r\n"
                        ,cur->valetparkingnum, cur->chan->name
                        ,(long)cur->start.tv_sec + 
(long)(cur->valetparkingtime/1000) - (long)time(NULL)
                        ,(cur->chan->callerid ? cur->chan->callerid : "")
                        );

                cur = cur->next;
        }

        ast_mutex_unlock(&valetparking_lock);

        return RESULT_SUCCESS;
}

int load_module(void)
{
        int res;

        ast_cli_register(&showvaletparked);
        valetparkingtime = DEFAULT_VALETPARK_TIME;
        pthread_create(&valetparking_thread, NULL, do_valetparking_thread, 
NULL);
        res = ast_register_application(valetunparkedcall, valetunpark_call, 
vupsynopsis, vupdesc);
        res = ast_register_application(valetparkedcall, valetpark_call, 
vpcsynopsis, vpcdesc);
        res = ast_register_application(valetparking, ast_valetparking, 
vpsynopsis, vpdesc);
        res = ast_register_application(valetparklist,valetpark_list, 
vlsynopsis, vldesc);



        if (!res) {
                ast_manager_register( "ValetparkedCalls", 0, 
manager_valetparking_status, "List valetparked calls" );
        }

        return res;
}

int unload_module(void)
{
        STANDARD_HANGUP_LOCALUSERS;

        if (!ast_mutex_lock(&valetparking_lock)) {
        if (valetparking_thread && (valetparking_thread != AST_PTHREADT_STOP)) {
            pthread_cancel(valetparking_thread);
            pthread_kill(valetparking_thread, SIGURG);
            pthread_join(valetparking_thread, NULL);
        }
        valetparking_thread = AST_PTHREADT_STOP;
        ast_mutex_unlock(&valetparking_lock);
    } else {
        ast_log(LOG_WARNING, "Unable to lock the valet\n");
        return -1;
    }


        ast_manager_unregister( "ValetparkedCalls" );
        ast_cli_unregister(&showvaletparked);
        ast_unregister_application(valetunparkedcall);
        ast_unregister_application(valetparkedcall);
        ast_unregister_application(valetparking);
        ast_unregister_application(valetparklist);
        return 0;
}

char *description(void)
{
        return "Valet Parking Application";
}

int usecount(void)
{
        int res;
        STANDARD_USECOUNT(res);
        res += valetparking_count();
        return res;
}

char *key()
{
        return ASTERISK_GPL_KEY;
}
_______________________________________________
Asterisk-Users mailing list
Asterisk-Users@lists.digium.com
http://lists.digium.com/mailman/listinfo/asterisk-users
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-users

Reply via email to