mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-08 10:58:15 +00:00
Merge hint patch, add new variables, and misc. PBX cleanups
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@722 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -35,6 +35,7 @@ ${CALLERIDNUM} Caller ID Number only
|
|||||||
${EXTEN} Current extension
|
${EXTEN} Current extension
|
||||||
${CONTEXT} Current context
|
${CONTEXT} Current context
|
||||||
${PRIORITY} Current priority
|
${PRIORITY} Current priority
|
||||||
|
${CHANNEL} Current channel name
|
||||||
|
|
||||||
There are two reference modes - reference by value and reference by name.
|
There are two reference modes - reference by value and reference by name.
|
||||||
To refer to a variable with its name (as an argument to a function that
|
To refer to a variable with its name (as an argument to a function that
|
||||||
|
|||||||
1
cdr.c
1
cdr.c
@@ -21,6 +21,7 @@
|
|||||||
#include <asterisk/callerid.h>
|
#include <asterisk/callerid.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
int ast_default_amaflags = AST_CDR_DOCUMENTATION;
|
int ast_default_amaflags = AST_CDR_DOCUMENTATION;
|
||||||
|
|||||||
78
channel.c
78
channel.c
@@ -64,6 +64,7 @@ struct chanlist {
|
|||||||
char description[80];
|
char description[80];
|
||||||
int capabilities;
|
int capabilities;
|
||||||
struct ast_channel * (*requester)(char *type, int format, void *data);
|
struct ast_channel * (*requester)(char *type, int format, void *data);
|
||||||
|
int (*devicestate)(void *data);
|
||||||
struct chanlist *next;
|
struct chanlist *next;
|
||||||
} *backends = NULL;
|
} *backends = NULL;
|
||||||
struct ast_channel *channels = NULL;
|
struct ast_channel *channels = NULL;
|
||||||
@@ -143,6 +144,13 @@ time_t myt;
|
|||||||
|
|
||||||
int ast_channel_register(char *type, char *description, int capabilities,
|
int ast_channel_register(char *type, char *description, int capabilities,
|
||||||
struct ast_channel *(*requester)(char *type, int format, void *data))
|
struct ast_channel *(*requester)(char *type, int format, void *data))
|
||||||
|
{
|
||||||
|
return ast_channel_register_ex(type, description, capabilities, requester, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ast_channel_register_ex(char *type, char *description, int capabilities,
|
||||||
|
struct ast_channel *(*requester)(char *type, int format, void *data),
|
||||||
|
int (*devicestate)(void *data))
|
||||||
{
|
{
|
||||||
struct chanlist *chan, *last=NULL;
|
struct chanlist *chan, *last=NULL;
|
||||||
if (PTHREAD_MUTEX_LOCK(&chlock)) {
|
if (PTHREAD_MUTEX_LOCK(&chlock)) {
|
||||||
@@ -169,6 +177,7 @@ int ast_channel_register(char *type, char *description, int capabilities,
|
|||||||
strncpy(chan->description, description, sizeof(chan->description)-1);
|
strncpy(chan->description, description, sizeof(chan->description)-1);
|
||||||
chan->capabilities = capabilities;
|
chan->capabilities = capabilities;
|
||||||
chan->requester = requester;
|
chan->requester = requester;
|
||||||
|
chan->devicestate = devicestate;
|
||||||
chan->next = NULL;
|
chan->next = NULL;
|
||||||
if (last)
|
if (last)
|
||||||
last->next = chan;
|
last->next = chan;
|
||||||
@@ -469,6 +478,7 @@ void ast_channel_free(struct ast_channel *chan)
|
|||||||
struct ast_var_t *vardata;
|
struct ast_var_t *vardata;
|
||||||
struct ast_frame *f, *fp;
|
struct ast_frame *f, *fp;
|
||||||
struct varshead *headp;
|
struct varshead *headp;
|
||||||
|
char name[AST_CHANNEL_NAME];
|
||||||
|
|
||||||
headp=&chan->varshead;
|
headp=&chan->varshead;
|
||||||
|
|
||||||
@@ -489,10 +499,14 @@ void ast_channel_free(struct ast_channel *chan)
|
|||||||
ast_log(LOG_WARNING, "Unable to find channel in list\n");
|
ast_log(LOG_WARNING, "Unable to find channel in list\n");
|
||||||
if (chan->pvt->pvt)
|
if (chan->pvt->pvt)
|
||||||
ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
|
ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
|
||||||
|
|
||||||
|
strncpy(name, chan->name, sizeof(name)-1);
|
||||||
|
|
||||||
/* Stop monitoring */
|
/* Stop monitoring */
|
||||||
if (chan->monitor) {
|
if (chan->monitor) {
|
||||||
chan->monitor->stop( chan, 0 );
|
chan->monitor->stop( chan, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free translatosr */
|
/* Free translatosr */
|
||||||
if (chan->pvt->readtrans)
|
if (chan->pvt->readtrans)
|
||||||
ast_translator_free_path(chan->pvt->readtrans);
|
ast_translator_free_path(chan->pvt->readtrans);
|
||||||
@@ -537,6 +551,8 @@ void ast_channel_free(struct ast_channel *chan)
|
|||||||
chan->pvt = NULL;
|
chan->pvt = NULL;
|
||||||
free(chan);
|
free(chan);
|
||||||
PTHREAD_MUTEX_UNLOCK(&chlock);
|
PTHREAD_MUTEX_UNLOCK(&chlock);
|
||||||
|
|
||||||
|
ast_device_state_changed(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
|
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
|
||||||
@@ -1409,6 +1425,7 @@ struct ast_channel *ast_request(char *type, int format, void *data)
|
|||||||
if (chan->requester)
|
if (chan->requester)
|
||||||
c = chan->requester(type, capabilities, data);
|
c = chan->requester(type, capabilities, data);
|
||||||
if (c) {
|
if (c) {
|
||||||
|
// ast_device_state_changed(c->name);
|
||||||
manager_event(EVENT_FLAG_CALL, "Newchannel",
|
manager_event(EVENT_FLAG_CALL, "Newchannel",
|
||||||
"Channel: %s\r\n"
|
"Channel: %s\r\n"
|
||||||
"State: %s\r\n"
|
"State: %s\r\n"
|
||||||
@@ -1425,6 +1442,66 @@ struct ast_channel *ast_request(char *type, int format, void *data)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ast_parse_device_state(char *device)
|
||||||
|
{
|
||||||
|
char name[AST_CHANNEL_NAME] = "";
|
||||||
|
char *cut;
|
||||||
|
struct ast_channel *chan;
|
||||||
|
|
||||||
|
chan = ast_channel_walk(NULL);
|
||||||
|
while (chan) {
|
||||||
|
strncpy(name, chan->name, sizeof(name)-1);
|
||||||
|
cut = strchr(name,'-');
|
||||||
|
if (cut)
|
||||||
|
*cut = 0;
|
||||||
|
if (!strcmp(name, device))
|
||||||
|
return AST_DEVICE_INUSE;
|
||||||
|
chan = ast_channel_walk(chan);
|
||||||
|
}
|
||||||
|
return AST_DEVICE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ast_device_state(char *device)
|
||||||
|
{
|
||||||
|
char tech[AST_MAX_EXTENSION] = "";
|
||||||
|
char *number;
|
||||||
|
struct chanlist *chanls;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
strncpy(tech, device, sizeof(tech)-1);
|
||||||
|
number = strchr(tech, '/');
|
||||||
|
if (!number) {
|
||||||
|
return AST_DEVICE_INVALID;
|
||||||
|
}
|
||||||
|
*number = 0;
|
||||||
|
number++;
|
||||||
|
|
||||||
|
if (PTHREAD_MUTEX_LOCK(&chlock)) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to lock channel list\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
chanls = backends;
|
||||||
|
while(chanls) {
|
||||||
|
if (!strcasecmp(tech, chanls->type)) {
|
||||||
|
PTHREAD_MUTEX_UNLOCK(&chlock);
|
||||||
|
if (!chanls->devicestate)
|
||||||
|
return ast_parse_device_state(device);
|
||||||
|
else {
|
||||||
|
res = chanls->devicestate(number);
|
||||||
|
if (res == AST_DEVICE_UNKNOWN)
|
||||||
|
return ast_parse_device_state(device);
|
||||||
|
else
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chanls = chanls->next;
|
||||||
|
}
|
||||||
|
if (!chanls)
|
||||||
|
ast_log(LOG_WARNING, "No channel type registered for '%s'\n", tech);
|
||||||
|
PTHREAD_MUTEX_UNLOCK(&chlock);
|
||||||
|
return AST_DEVICE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
int ast_call(struct ast_channel *chan, char *addr, int timeout)
|
int ast_call(struct ast_channel *chan, char *addr, int timeout)
|
||||||
{
|
{
|
||||||
/* Place an outgoing call, but don't wait any longer than timeout ms before returning.
|
/* Place an outgoing call, but don't wait any longer than timeout ms before returning.
|
||||||
@@ -1813,6 +1890,7 @@ int ast_setstate(struct ast_channel *chan, int state)
|
|||||||
int oldstate = chan->_state;
|
int oldstate = chan->_state;
|
||||||
chan->_state = state;
|
chan->_state = state;
|
||||||
if (oldstate == AST_STATE_DOWN) {
|
if (oldstate == AST_STATE_DOWN) {
|
||||||
|
ast_device_state_changed(chan->name);
|
||||||
manager_event(EVENT_FLAG_CALL, "Newchannel",
|
manager_event(EVENT_FLAG_CALL, "Newchannel",
|
||||||
"Channel: %s\r\n"
|
"Channel: %s\r\n"
|
||||||
"State: %s\r\n"
|
"State: %s\r\n"
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <asterisk/lock.h>
|
#include <asterisk/lock.h>
|
||||||
#include <asterisk/vmodem.h>
|
#include <asterisk/vmodem.h>
|
||||||
#include <asterisk/module.h>
|
#include <asterisk/module.h>
|
||||||
|
|||||||
@@ -1740,10 +1740,10 @@ static int respprep(struct sip_request *resp, struct sip_pvt *p, char *msg, stru
|
|||||||
char contact[256];
|
char contact[256];
|
||||||
char *c;
|
char *c;
|
||||||
if ((c=getsipuri(ot))) {
|
if ((c=getsipuri(ot))) {
|
||||||
snprintf(contact, sizeof(contact), "<%s@%s>", c, inet_ntoa(p->ourip));
|
snprintf(contact, sizeof(contact), "<%s@%s:%d>", c, inet_ntoa(p->ourip), ourport);
|
||||||
free(c);
|
free(c);
|
||||||
} else {
|
} else {
|
||||||
snprintf(contact, sizeof(contact), "<%s>", inet_ntoa(p->ourip));
|
snprintf(contact, sizeof(contact), "<%s:%d>", inet_ntoa(p->ourip), ourport);
|
||||||
}
|
}
|
||||||
snprintf(tmp, sizeof(tmp), "%d", p->expirey);
|
snprintf(tmp, sizeof(tmp), "%d", p->expirey);
|
||||||
add_header(resp, "Expires", tmp);
|
add_header(resp, "Expires", tmp);
|
||||||
@@ -1754,10 +1754,10 @@ static int respprep(struct sip_request *resp, struct sip_pvt *p, char *msg, stru
|
|||||||
very stupidly *sigh* XXX */
|
very stupidly *sigh* XXX */
|
||||||
char *c;
|
char *c;
|
||||||
if ((c=getsipuri(ot))) {
|
if ((c=getsipuri(ot))) {
|
||||||
snprintf(contact, sizeof(contact), "<%s@%s>", c, inet_ntoa(p->ourip));
|
snprintf(contact, sizeof(contact), "<%s@%s:%d>", c, inet_ntoa(p->ourip), ourport);
|
||||||
free(c);
|
free(c);
|
||||||
} else {
|
} else {
|
||||||
snprintf(contact, sizeof(contact), "<%s>", inet_ntoa(p->ourip));
|
snprintf(contact, sizeof(contact), "<%s:%d>", inet_ntoa(p->ourip), ourport);
|
||||||
}
|
}
|
||||||
add_header(resp, "Contact", contact);
|
add_header(resp, "Contact", contact);
|
||||||
}
|
}
|
||||||
@@ -2048,7 +2048,8 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, char *cmd, c
|
|||||||
}
|
}
|
||||||
if (!n)
|
if (!n)
|
||||||
n = l;
|
n = l;
|
||||||
snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%08x", n, l, inet_ntoa(p->ourip), p->tag);
|
snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%08x", n, l, inet_ntoa(p->ourip), ourport, p->tag);
|
||||||
|
|
||||||
if (strlen(p->username)) {
|
if (strlen(p->username)) {
|
||||||
if (ntohs(p->sa.sin_port) != DEFAULT_SIP_PORT) {
|
if (ntohs(p->sa.sin_port) != DEFAULT_SIP_PORT) {
|
||||||
snprintf(invite, sizeof(invite), "sip:%s@%s:%d",p->username, inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port));
|
snprintf(invite, sizeof(invite), "sip:%s@%s:%d",p->username, inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port));
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ struct ast_translator_pvt {
|
|||||||
|
|
||||||
#define speex_coder_pvt ast_translator_pvt
|
#define speex_coder_pvt ast_translator_pvt
|
||||||
|
|
||||||
static struct ast_translator_pvt *lintospeex_new()
|
static struct ast_translator_pvt *lintospeex_new(void)
|
||||||
{
|
{
|
||||||
struct speex_coder_pvt *tmp;
|
struct speex_coder_pvt *tmp;
|
||||||
tmp = malloc(sizeof(struct speex_coder_pvt));
|
tmp = malloc(sizeof(struct speex_coder_pvt));
|
||||||
@@ -77,7 +77,7 @@ static struct ast_translator_pvt *lintospeex_new()
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ast_translator_pvt *speextolin_new()
|
static struct ast_translator_pvt *speextolin_new(void)
|
||||||
{
|
{
|
||||||
struct speex_coder_pvt *tmp;
|
struct speex_coder_pvt *tmp;
|
||||||
tmp = malloc(sizeof(struct speex_coder_pvt));
|
tmp = malloc(sizeof(struct speex_coder_pvt));
|
||||||
@@ -95,7 +95,7 @@ static struct ast_translator_pvt *speextolin_new()
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ast_frame *lintospeex_sample()
|
static struct ast_frame *lintospeex_sample(void)
|
||||||
{
|
{
|
||||||
static struct ast_frame f;
|
static struct ast_frame f;
|
||||||
f.frametype = AST_FRAME_VOICE;
|
f.frametype = AST_FRAME_VOICE;
|
||||||
@@ -110,7 +110,7 @@ static struct ast_frame *lintospeex_sample()
|
|||||||
return &f;
|
return &f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ast_frame *speextolin_sample()
|
static struct ast_frame *speextolin_sample(void)
|
||||||
{
|
{
|
||||||
static struct ast_frame f;
|
static struct ast_frame f;
|
||||||
f.frametype = AST_FRAME_VOICE;
|
f.frametype = AST_FRAME_VOICE;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ ${CALLERIDNUM} Caller ID Number only
|
|||||||
${EXTEN} Current extension
|
${EXTEN} Current extension
|
||||||
${CONTEXT} Current context
|
${CONTEXT} Current context
|
||||||
${PRIORITY} Current priority
|
${PRIORITY} Current priority
|
||||||
|
${CHANNEL} Current channel name
|
||||||
|
|
||||||
There are two reference modes - reference by value and reference by name.
|
There are two reference modes - reference by value and reference by name.
|
||||||
To refer to a variable with its name (as an argument to a function that
|
To refer to a variable with its name (as an argument to a function that
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ static char *exts = "alaw|al";
|
|||||||
|
|
||||||
|
|
||||||
/* Returns time in msec since system boot. */
|
/* Returns time in msec since system boot. */
|
||||||
static unsigned long get_time()
|
static unsigned long get_time(void)
|
||||||
{
|
{
|
||||||
struct tms buf;
|
struct tms buf;
|
||||||
clock_t cur;
|
clock_t cur;
|
||||||
|
|||||||
@@ -233,6 +233,19 @@ struct chanmon;
|
|||||||
/*! Do not transmit voice data */
|
/*! Do not transmit voice data */
|
||||||
#define AST_STATE_MUTE (1 << 16)
|
#define AST_STATE_MUTE (1 << 16)
|
||||||
|
|
||||||
|
/*! Device is valid but channel didn't know state */
|
||||||
|
#define AST_DEVICE_UNKNOWN 0
|
||||||
|
/*! Device is not used */
|
||||||
|
#define AST_DEVICE_NOT_INUSE 1
|
||||||
|
/*! Device is in use */
|
||||||
|
#define AST_DEVICE_INUSE 2
|
||||||
|
/*! Device is busy */
|
||||||
|
#define AST_DEVICE_BUSY 3
|
||||||
|
/*! Device is invalid */
|
||||||
|
#define AST_DEVICE_INVALID 4
|
||||||
|
/*! Device is unavailable */
|
||||||
|
#define AST_DEVICE_UNAVAILABLE 5
|
||||||
|
|
||||||
//! Requests a channel
|
//! Requests a channel
|
||||||
/*!
|
/*!
|
||||||
* \param type type of channel to request
|
* \param type type of channel to request
|
||||||
@@ -244,6 +257,27 @@ struct chanmon;
|
|||||||
*/
|
*/
|
||||||
struct ast_channel *ast_request(char *type, int format, void *data);
|
struct ast_channel *ast_request(char *type, int format, void *data);
|
||||||
|
|
||||||
|
//! Search the Channels by Name
|
||||||
|
/*!
|
||||||
|
* \param device like a dialstring
|
||||||
|
* Search the Device in active channels by compare the channelname against
|
||||||
|
* the devicename. Compared are only the first chars to the first '-' char.
|
||||||
|
* Returns an AST_DEVICE_UNKNOWN if no channel found or
|
||||||
|
* AST_DEVICE_INUSE if a channel is found
|
||||||
|
*/
|
||||||
|
int ast_parse_device_state(char *device);
|
||||||
|
|
||||||
|
//! Asks a channel for device state
|
||||||
|
/*!
|
||||||
|
* \param device like a dialstring
|
||||||
|
* Asks a channel for device state, data is normaly a number from dialstring
|
||||||
|
* used by the low level module
|
||||||
|
* Trys the channel devicestate callback if not supported search in the
|
||||||
|
* active channels list for the device.
|
||||||
|
* Returns an AST_DEVICE_??? state -1 on failure
|
||||||
|
*/
|
||||||
|
int ast_device_state(char *device);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \param type type of channel to request
|
* \param type type of channel to request
|
||||||
* \param format requested channel format
|
* \param format requested channel format
|
||||||
@@ -271,6 +305,11 @@ struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int
|
|||||||
int ast_channel_register(char *type, char *description, int capabilities,
|
int ast_channel_register(char *type, char *description, int capabilities,
|
||||||
struct ast_channel* (*requester)(char *type, int format, void *data));
|
struct ast_channel* (*requester)(char *type, int format, void *data));
|
||||||
|
|
||||||
|
/* Same like the upper function but with support for devicestate */
|
||||||
|
int ast_channel_register_ex(char *type, char *description, int capabilities,
|
||||||
|
struct ast_channel *(*requester)(char *type, int format, void *data),
|
||||||
|
int (*devicestate)(void *data));
|
||||||
|
|
||||||
//! Unregister a channel class
|
//! Unregister a channel class
|
||||||
/*
|
/*
|
||||||
* \param type the character string that corresponds to the channel you wish to unregister
|
* \param type the character string that corresponds to the channel you wish to unregister
|
||||||
|
|||||||
@@ -29,12 +29,27 @@ extern "C" {
|
|||||||
//! Special return values from applications to the PBX
|
//! Special return values from applications to the PBX
|
||||||
#define AST_PBX_KEEPALIVE 10 /* Destroy the thread, but don't hang up the channel */
|
#define AST_PBX_KEEPALIVE 10 /* Destroy the thread, but don't hang up the channel */
|
||||||
|
|
||||||
|
//! Special Priority for an hint
|
||||||
|
#define PRIORITY_HINT -1
|
||||||
|
|
||||||
|
//! Extension states
|
||||||
|
//! No device INUSE or BUSY
|
||||||
|
#define AST_EXTENSION_NOT_INUSE 0
|
||||||
|
//! One or more devices INUSE
|
||||||
|
#define AST_EXTENSION_INUSE 1
|
||||||
|
//! All devices BUSY
|
||||||
|
#define AST_EXTENSION_BUSY 2
|
||||||
|
//! All devices UNAVAILABLE/UNREGISTERED
|
||||||
|
#define AST_EXTENSION_UNAVAILABLE 3
|
||||||
|
|
||||||
struct ast_context;
|
struct ast_context;
|
||||||
struct ast_exten;
|
struct ast_exten;
|
||||||
struct ast_include;
|
struct ast_include;
|
||||||
struct ast_ignorepat;
|
struct ast_ignorepat;
|
||||||
struct ast_sw;
|
struct ast_sw;
|
||||||
|
|
||||||
|
typedef int (*ast_notify_cb_type)(char *context, char* id, int state, void *data);
|
||||||
|
|
||||||
//! Data structure associated with an asterisk switch
|
//! Data structure associated with an asterisk switch
|
||||||
struct ast_switch {
|
struct ast_switch {
|
||||||
/*! NULL */
|
/*! NULL */
|
||||||
@@ -189,6 +204,57 @@ int ast_register_application(char *app, int (*execute)(struct ast_channel *, voi
|
|||||||
*/
|
*/
|
||||||
int ast_unregister_application(char *app);
|
int ast_unregister_application(char *app);
|
||||||
|
|
||||||
|
//! Uses hint and devicestate callback to get the state of an extension
|
||||||
|
/*!
|
||||||
|
* \param c this is not important
|
||||||
|
* \param context which context to look in
|
||||||
|
* \param exten which extension to get state
|
||||||
|
* Returns extension state !! = AST_EXTENSION_???
|
||||||
|
*/
|
||||||
|
int ast_extension_state(struct ast_channel *c, char *context, char *exten);
|
||||||
|
|
||||||
|
//! Tells Asterisk the State for Device is changed
|
||||||
|
/*!
|
||||||
|
* \param device devicename like a dialstring
|
||||||
|
* Asterisk polls the new extensionstates and calls the registered
|
||||||
|
* callbacks for the changed extensions
|
||||||
|
* Returns 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int ast_device_state_changed(char *device);
|
||||||
|
|
||||||
|
//! Registers a state change callback
|
||||||
|
/*!
|
||||||
|
* \param context which context to look in
|
||||||
|
* \param exten which extension to get state
|
||||||
|
* \param callback callback to call if state changed
|
||||||
|
* \param data to pass to callback
|
||||||
|
* The callback is called if the state for extension is changed
|
||||||
|
* Return -1 on failure, ID on success
|
||||||
|
*/
|
||||||
|
int ast_extension_state_add(char *context, char *exten,
|
||||||
|
ast_notify_cb_type callback, void *data);
|
||||||
|
|
||||||
|
//! Deletes a registered state change callback by ID
|
||||||
|
/*!
|
||||||
|
* \param id of the callback to delete
|
||||||
|
* Removes the callback from list of callbacks
|
||||||
|
* Return 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int ast_extension_state_del(int id);
|
||||||
|
|
||||||
|
//! If an extension exists, return non-zero
|
||||||
|
/*!
|
||||||
|
* \param hint buffer for hint
|
||||||
|
* \param maxlen size of hint buffer
|
||||||
|
* \param c this is not important
|
||||||
|
* \param context which context to look in
|
||||||
|
* \param exten which extension to search for
|
||||||
|
* If an extension within the given context with the priority PRIORITY_HINT
|
||||||
|
* is found a non zero value will be returned.
|
||||||
|
* Otherwise, 0 is returned.
|
||||||
|
*/
|
||||||
|
int ast_get_hint(char *hint, int maxlen, struct ast_channel *c, char *context, char *exten);
|
||||||
|
|
||||||
//! If an extension exists, return non-zero
|
//! If an extension exists, return non-zero
|
||||||
// work
|
// work
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
350
pbx.c
350
pbx.c
@@ -132,6 +132,22 @@ struct ast_app {
|
|||||||
struct ast_app *next;
|
struct ast_app *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* An extension state notify */
|
||||||
|
struct ast_notify_cb {
|
||||||
|
int id;
|
||||||
|
void *data;
|
||||||
|
ast_notify_cb_type callback;
|
||||||
|
struct ast_notify_cb *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ast_notify {
|
||||||
|
struct ast_exten *exten;
|
||||||
|
int laststate;
|
||||||
|
struct ast_notify_cb *callbacks;
|
||||||
|
struct ast_notify *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static int pbx_builtin_prefix(struct ast_channel *, void *);
|
static int pbx_builtin_prefix(struct ast_channel *, void *);
|
||||||
static int pbx_builtin_stripmsd(struct ast_channel *, void *);
|
static int pbx_builtin_stripmsd(struct ast_channel *, void *);
|
||||||
static int pbx_builtin_answer(struct ast_channel *, void *);
|
static int pbx_builtin_answer(struct ast_channel *, void *);
|
||||||
@@ -294,6 +310,11 @@ static struct ast_app *apps = NULL;
|
|||||||
static pthread_mutex_t switchlock = AST_MUTEX_INITIALIZER;
|
static pthread_mutex_t switchlock = AST_MUTEX_INITIALIZER;
|
||||||
struct ast_switch *switches = NULL;
|
struct ast_switch *switches = NULL;
|
||||||
|
|
||||||
|
/* Lock for extension state notifys */
|
||||||
|
static pthread_mutex_t notifylock = AST_MUTEX_INITIALIZER;
|
||||||
|
static int notifycnt = 0;
|
||||||
|
struct ast_notify *notifys = NULL;
|
||||||
|
|
||||||
int pbx_exec(struct ast_channel *c, /* Channel */
|
int pbx_exec(struct ast_channel *c, /* Channel */
|
||||||
struct ast_app *app,
|
struct ast_app *app,
|
||||||
void *data, /* Data for execution */
|
void *data, /* Data for execution */
|
||||||
@@ -676,20 +697,19 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan, char *cont
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pbx_substitute_variables_temp(struct ast_channel *c,char *cp3,char **cp4)
|
static void pbx_substitute_variables_temp(struct ast_channel *c,char *cp3,char **cp4, char *workspace, int workspacelen)
|
||||||
{
|
{
|
||||||
char *first,*second;
|
char *first,*second;
|
||||||
int offset,offset2;
|
int offset,offset2;
|
||||||
struct ast_var_t *variables;
|
struct ast_var_t *variables;
|
||||||
char *name, *num; /* for callerid name + num variables */
|
char *name, *num; /* for callerid name + num variables */
|
||||||
struct varshead *headp;
|
struct varshead *headp;
|
||||||
char pri[80];
|
|
||||||
headp=&c->varshead;
|
headp=&c->varshead;
|
||||||
*cp4=NULL;
|
*cp4=NULL;
|
||||||
/* Now we have the variable name on cp3 */
|
/* Now we have the variable name on cp3 */
|
||||||
if ((first=strchr(cp3,':'))) {
|
if ((first=strchr(cp3,':'))) {
|
||||||
*first='\0';
|
*first='\0';
|
||||||
pbx_substitute_variables_temp(c,cp3,cp4);
|
pbx_substitute_variables_temp(c,cp3,cp4,workspace,workspacelen);
|
||||||
if (!(*cp4)) return;
|
if (!(*cp4)) return;
|
||||||
offset=atoi(first+1);
|
offset=atoi(first+1);
|
||||||
if ((second=strchr(first+1,':'))) {
|
if ((second=strchr(first+1,':'))) {
|
||||||
@@ -711,20 +731,18 @@ static void pbx_substitute_variables_temp(struct ast_channel *c,char *cp3,char *
|
|||||||
*cp4+=strlen(*cp4)+offset;
|
*cp4+=strlen(*cp4)+offset;
|
||||||
(*cp4)[offset2] = '\0';
|
(*cp4)[offset2] = '\0';
|
||||||
} else if (!strcmp(cp3, "CALLERIDNUM")) {
|
} else if (!strcmp(cp3, "CALLERIDNUM")) {
|
||||||
char cid[256] = "";
|
|
||||||
if (c->callerid)
|
if (c->callerid)
|
||||||
strncpy(cid, c->callerid, sizeof(cid) - 1);
|
strncpy(workspace, c->callerid, workspacelen - 1);
|
||||||
ast_callerid_parse(cid, &name, &num);
|
ast_callerid_parse(workspace, &name, &num);
|
||||||
if (num) {
|
if (num) {
|
||||||
ast_shrink_phone_number(num);
|
ast_shrink_phone_number(num);
|
||||||
*cp4 = num;
|
*cp4 = num;
|
||||||
} else
|
} else
|
||||||
*cp4 = "";
|
*cp4 = "";
|
||||||
} else if (!strcmp(cp3, "CALLERIDNAME")) {
|
} else if (!strcmp(cp3, "CALLERIDNAME")) {
|
||||||
char cid[256] = "";
|
|
||||||
if (c->callerid)
|
if (c->callerid)
|
||||||
strncpy(cid, c->callerid, sizeof(cid) - 1);
|
strncpy(workspace, c->callerid, workspacelen - 1);
|
||||||
ast_callerid_parse(cid, &name, &num);
|
ast_callerid_parse(workspace, &name, &num);
|
||||||
if (name)
|
if (name)
|
||||||
*cp4 = name;
|
*cp4 = name;
|
||||||
else
|
else
|
||||||
@@ -733,6 +751,11 @@ static void pbx_substitute_variables_temp(struct ast_channel *c,char *cp3,char *
|
|||||||
*cp4 = c->callerid;
|
*cp4 = c->callerid;
|
||||||
if (!(*cp4))
|
if (!(*cp4))
|
||||||
*cp4 = "";
|
*cp4 = "";
|
||||||
|
} else if (!strcmp(cp3, "HINT")) {
|
||||||
|
if (!ast_get_hint(workspace, workspacelen - 1, c, c->context, c->exten))
|
||||||
|
*cp4 = "";
|
||||||
|
else
|
||||||
|
*cp4 = workspace;
|
||||||
} else if (!strcmp(cp3, "EXTEN")) {
|
} else if (!strcmp(cp3, "EXTEN")) {
|
||||||
*cp4 = c->exten;
|
*cp4 = c->exten;
|
||||||
} else if (!strncmp(cp3, "EXTEN-", strlen("EXTEN-")) &&
|
} else if (!strncmp(cp3, "EXTEN-", strlen("EXTEN-")) &&
|
||||||
@@ -760,8 +783,10 @@ static void pbx_substitute_variables_temp(struct ast_channel *c,char *cp3,char *
|
|||||||
} else if (!strcmp(cp3, "CONTEXT")) {
|
} else if (!strcmp(cp3, "CONTEXT")) {
|
||||||
*cp4 = c->context;
|
*cp4 = c->context;
|
||||||
} else if (!strcmp(cp3, "PRIORITY")) {
|
} else if (!strcmp(cp3, "PRIORITY")) {
|
||||||
snprintf(pri, sizeof(pri), "%d", c->priority);
|
snprintf(workspace, workspacelen, "%d", c->priority);
|
||||||
*cp4 = pri;
|
*cp4 = workspace;
|
||||||
|
} else if (!strcmp(cp3, "CHANNEL")) {
|
||||||
|
*cp4 = c->name;
|
||||||
} else {
|
} else {
|
||||||
AST_LIST_TRAVERSE(headp,variables,entries) {
|
AST_LIST_TRAVERSE(headp,variables,entries) {
|
||||||
#if 0
|
#if 0
|
||||||
@@ -796,6 +821,7 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,char *cp1,char
|
|||||||
char *cp4,*cp2;
|
char *cp4,*cp2;
|
||||||
char *tmp,*wherearewe,*finish=NULL,*ltmp,*lval,*nextvar;
|
char *tmp,*wherearewe,*finish=NULL,*ltmp,*lval,*nextvar;
|
||||||
int length,variables=0;
|
int length,variables=0;
|
||||||
|
char workspace[256];
|
||||||
|
|
||||||
wherearewe=tmp=cp1;
|
wherearewe=tmp=cp1;
|
||||||
cp2=*ecp2;
|
cp2=*ecp2;
|
||||||
@@ -854,7 +880,7 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,char *cp1,char
|
|||||||
cp1=cp2;
|
cp1=cp2;
|
||||||
}
|
}
|
||||||
if (count) {
|
if (count) {
|
||||||
pbx_substitute_variables_temp(c,cp1,&cp4);
|
pbx_substitute_variables_temp(c,cp1,&cp4, workspace, sizeof(workspace));
|
||||||
if (cp4) {
|
if (cp4) {
|
||||||
/* reset output variable so we could store the result */
|
/* reset output variable so we could store the result */
|
||||||
*cp2='\0';
|
*cp2='\0';
|
||||||
@@ -1080,6 +1106,300 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct ast_exten *ast_hint_extension(struct ast_channel *c, char *context, char *exten)
|
||||||
|
{
|
||||||
|
struct ast_exten *e;
|
||||||
|
struct ast_switch *sw;
|
||||||
|
char *data;
|
||||||
|
int status = 0;
|
||||||
|
char *incstack[AST_PBX_MAX_STACK];
|
||||||
|
int stacklen = 0;
|
||||||
|
|
||||||
|
if (ast_pthread_mutex_lock(&conlock)) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to obtain lock\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
e = pbx_find_extension(c, context, exten, PRIORITY_HINT, "", HELPER_EXISTS, incstack, &stacklen, &status, &sw, &data);
|
||||||
|
ast_pthread_mutex_unlock(&conlock);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ast_extension_state2(struct ast_exten *e)
|
||||||
|
{
|
||||||
|
char hint[AST_MAX_EXTENSION] = "";
|
||||||
|
char *cur, *rest;
|
||||||
|
int res = -1;
|
||||||
|
int allunavailable = 1, allbusy = 1, allfree = 1;
|
||||||
|
int busy = 0;
|
||||||
|
|
||||||
|
strncpy(hint, ast_get_extension_app(e), sizeof(hint)-1);
|
||||||
|
|
||||||
|
cur = hint;
|
||||||
|
do {
|
||||||
|
rest = strchr(cur, '&');
|
||||||
|
if (rest) {
|
||||||
|
*rest = 0;
|
||||||
|
rest++;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ast_device_state(cur);
|
||||||
|
switch (res) {
|
||||||
|
case AST_DEVICE_NOT_INUSE:
|
||||||
|
allunavailable = 0;
|
||||||
|
allbusy = 0;
|
||||||
|
break;
|
||||||
|
case AST_DEVICE_INUSE:
|
||||||
|
return AST_EXTENSION_INUSE;
|
||||||
|
case AST_DEVICE_BUSY:
|
||||||
|
allunavailable = 0;
|
||||||
|
allfree = 0;
|
||||||
|
busy = 1;
|
||||||
|
break;
|
||||||
|
case AST_DEVICE_UNAVAILABLE:
|
||||||
|
case AST_DEVICE_INVALID:
|
||||||
|
allbusy = 0;
|
||||||
|
allfree = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
allunavailable = 0;
|
||||||
|
allbusy = 0;
|
||||||
|
allfree = 0;
|
||||||
|
}
|
||||||
|
cur = rest;
|
||||||
|
} while (cur);
|
||||||
|
|
||||||
|
if (allfree)
|
||||||
|
return AST_EXTENSION_NOT_INUSE;
|
||||||
|
if (allbusy)
|
||||||
|
return AST_EXTENSION_BUSY;
|
||||||
|
if (allunavailable)
|
||||||
|
return AST_EXTENSION_UNAVAILABLE;
|
||||||
|
if (busy)
|
||||||
|
return AST_EXTENSION_INUSE;
|
||||||
|
|
||||||
|
return AST_EXTENSION_NOT_INUSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ast_extension_state(struct ast_channel *c, char *context, char *exten)
|
||||||
|
{
|
||||||
|
struct ast_exten *e;
|
||||||
|
|
||||||
|
e = ast_hint_extension(c, context, exten);
|
||||||
|
if (!e)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ast_extension_state2(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ast_device_state_changed(char *device)
|
||||||
|
{
|
||||||
|
struct ast_notify *list;
|
||||||
|
struct ast_notify_cb *cblist;
|
||||||
|
char hint[AST_MAX_EXTENSION];
|
||||||
|
char *cur, *rest;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
pthread_mutex_lock(¬ifylock);
|
||||||
|
|
||||||
|
list = notifys;
|
||||||
|
|
||||||
|
while (list) {
|
||||||
|
|
||||||
|
strcpy(hint, ast_get_extension_app(list->exten));
|
||||||
|
cur = hint;
|
||||||
|
do {
|
||||||
|
rest = strchr(cur, '&');
|
||||||
|
if (rest) {
|
||||||
|
*rest = 0;
|
||||||
|
rest++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(cur, device, strlen(cur))) {
|
||||||
|
// Found extension execute callbacks
|
||||||
|
state = ast_extension_state2(list->exten);
|
||||||
|
if ((state != -1) && (state != list->laststate)) {
|
||||||
|
cblist = list->callbacks;
|
||||||
|
while (cblist) {
|
||||||
|
cblist->callback(list->exten->parent->name, list->exten->exten, state, cblist->data);
|
||||||
|
cblist = cblist->next;
|
||||||
|
}
|
||||||
|
list->laststate = state;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cur = rest;
|
||||||
|
} while (cur);
|
||||||
|
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(¬ifylock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ast_extension_state_add(char *context, char *exten,
|
||||||
|
ast_notify_cb_type callback, void *data)
|
||||||
|
{
|
||||||
|
struct ast_notify *list;
|
||||||
|
struct ast_notify_cb *cblist;
|
||||||
|
struct ast_exten *e;
|
||||||
|
|
||||||
|
pthread_mutex_lock(¬ifylock);
|
||||||
|
list = notifys;
|
||||||
|
|
||||||
|
while (list) {
|
||||||
|
if (!strcmp(list->exten->parent->name, context) &&
|
||||||
|
!strcmp(list->exten->exten, exten))
|
||||||
|
break;
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!list) {
|
||||||
|
e = ast_hint_extension(NULL, context, exten);
|
||||||
|
if (!e) {
|
||||||
|
pthread_mutex_unlock(¬ifylock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
list = malloc(sizeof(struct ast_notify));
|
||||||
|
if (!list) {
|
||||||
|
pthread_mutex_unlock(¬ifylock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Initialize and insert new item */
|
||||||
|
memset(list, 0, sizeof(struct ast_notify));
|
||||||
|
list->exten = e;
|
||||||
|
list->laststate = -1;
|
||||||
|
list->next = notifys;
|
||||||
|
notifys = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now inserts the callback */
|
||||||
|
cblist = malloc(sizeof(struct ast_notify_cb));
|
||||||
|
if (!cblist) {
|
||||||
|
pthread_mutex_unlock(¬ifylock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(cblist, 0, sizeof(struct ast_notify_cb));
|
||||||
|
cblist->id = notifycnt++;
|
||||||
|
cblist->callback = callback;
|
||||||
|
cblist->data = data;
|
||||||
|
|
||||||
|
cblist->next = list->callbacks;
|
||||||
|
list->callbacks = cblist;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(¬ifylock);
|
||||||
|
return cblist->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ast_extension_state_clean(struct ast_exten *e)
|
||||||
|
{
|
||||||
|
/* Cleanup the Notifys if hint is removed */
|
||||||
|
struct ast_notify *list, *prev = NULL;
|
||||||
|
struct ast_notify_cb *cblist, *cbprev;
|
||||||
|
|
||||||
|
pthread_mutex_lock(¬ifylock);
|
||||||
|
|
||||||
|
list = notifys;
|
||||||
|
while(list) {
|
||||||
|
if (list->exten==e) {
|
||||||
|
cbprev = NULL;
|
||||||
|
cblist = list->callbacks;
|
||||||
|
while (cblist) {
|
||||||
|
cbprev = cblist;
|
||||||
|
cblist = cblist->next;
|
||||||
|
cblist->callback(list->exten->parent->name, list->exten->exten, -1, cblist->data);
|
||||||
|
free(cbprev);
|
||||||
|
}
|
||||||
|
list->callbacks = NULL;
|
||||||
|
|
||||||
|
if (!prev) {
|
||||||
|
notifys = list->next;
|
||||||
|
free(list);
|
||||||
|
list = notifys;
|
||||||
|
} else {
|
||||||
|
prev->next = list->next;
|
||||||
|
free(list);
|
||||||
|
list = prev->next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prev = list;
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(¬ifylock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ast_extension_state_del(int id)
|
||||||
|
{
|
||||||
|
struct ast_notify *list, *prev = NULL;
|
||||||
|
struct ast_notify_cb *cblist, *cbprev;
|
||||||
|
|
||||||
|
pthread_mutex_lock(¬ifylock);
|
||||||
|
|
||||||
|
list = notifys;
|
||||||
|
while (list) {
|
||||||
|
cblist = list->callbacks;
|
||||||
|
cbprev = NULL;
|
||||||
|
while (cblist) {
|
||||||
|
if (cblist->id==id) {
|
||||||
|
if (!cbprev) {
|
||||||
|
list->callbacks = cblist->next;
|
||||||
|
free(cblist);
|
||||||
|
cblist = list->callbacks;
|
||||||
|
} else {
|
||||||
|
cbprev->next = cblist->next;
|
||||||
|
free(cblist);
|
||||||
|
cblist = cbprev->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!list->callbacks) {
|
||||||
|
if (!prev) {
|
||||||
|
notifys = list->next;
|
||||||
|
free(list);
|
||||||
|
list = notifys;
|
||||||
|
} else {
|
||||||
|
prev->next = list->next;
|
||||||
|
free(list);
|
||||||
|
list = prev->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
cbprev = cblist;
|
||||||
|
cblist = cblist->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can have only one item
|
||||||
|
if (cblist)
|
||||||
|
break;
|
||||||
|
|
||||||
|
prev = list;
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(¬ifylock);
|
||||||
|
if (list)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ast_get_hint(char *hint, int maxlen, struct ast_channel *c, char *context, char *exten)
|
||||||
|
{
|
||||||
|
struct ast_exten *e;
|
||||||
|
e = ast_hint_extension(c, context, exten);
|
||||||
|
if (e) {
|
||||||
|
strncpy(hint, ast_get_extension_app(e), maxlen);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int ast_exists_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid)
|
int ast_exists_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid)
|
||||||
{
|
{
|
||||||
return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_EXISTS);
|
return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_EXISTS);
|
||||||
@@ -1544,6 +1864,9 @@ int ast_context_remove_extension2(struct ast_context *con, char *extension, int
|
|||||||
peer = exten;
|
peer = exten;
|
||||||
while (peer) {
|
while (peer) {
|
||||||
exten = peer->peer;
|
exten = peer->peer;
|
||||||
|
|
||||||
|
if (!peer->priority==PRIORITY_HINT)
|
||||||
|
ast_extension_state_clean(peer);
|
||||||
|
|
||||||
peer->datad(peer->data);
|
peer->datad(peer->data);
|
||||||
free(peer);
|
free(peer);
|
||||||
@@ -1589,6 +1912,8 @@ int ast_context_remove_extension2(struct ast_context *con, char *extension, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* now, free whole priority extension */
|
/* now, free whole priority extension */
|
||||||
|
if (peer->priority==PRIORITY_HINT)
|
||||||
|
ast_extension_state_clean(peer);
|
||||||
peer->datad(peer->data);
|
peer->datad(peer->data);
|
||||||
free(peer);
|
free(peer);
|
||||||
|
|
||||||
@@ -2956,6 +3281,7 @@ int ast_add_extension2(struct ast_context *con,
|
|||||||
tmp->matchcid = 0;
|
tmp->matchcid = 0;
|
||||||
}
|
}
|
||||||
strncpy(tmp->app, application, sizeof(tmp->app)-1);
|
strncpy(tmp->app, application, sizeof(tmp->app)-1);
|
||||||
|
tmp->parent = con;
|
||||||
tmp->data = data;
|
tmp->data = data;
|
||||||
tmp->datad = datad;
|
tmp->datad = datad;
|
||||||
tmp->registrar = registrar;
|
tmp->registrar = registrar;
|
||||||
|
|||||||
@@ -344,14 +344,16 @@ static int handle_context_remove_extension(int fd, int argc, char *argv[])
|
|||||||
* why? because atoi (strtol) returns 0 if any characters in
|
* why? because atoi (strtol) returns 0 if any characters in
|
||||||
* string and whole extension will be removed, it's not good
|
* string and whole extension will be removed, it's not good
|
||||||
*/
|
*/
|
||||||
while (*c != '\0') {
|
if (strcmp("hint", c)) {
|
||||||
|
while (*c != '\0') {
|
||||||
if (!isdigit(*c++)) {
|
if (!isdigit(*c++)) {
|
||||||
ast_cli(fd, "Invalid priority '%s'\n", argv[3]);
|
ast_cli(fd, "Invalid priority '%s'\n", argv[3]);
|
||||||
return RESULT_FAILURE;
|
return RESULT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
removing_priority = atoi(argv[3]);
|
||||||
removing_priority = atoi(argv[3]);
|
} else
|
||||||
|
removing_priority = PRIORITY_HINT;
|
||||||
|
|
||||||
if (removing_priority == 0) {
|
if (removing_priority == 0) {
|
||||||
ast_cli(fd, "If you want to remove whole extension, please " \
|
ast_cli(fd, "If you want to remove whole extension, please " \
|
||||||
@@ -983,11 +985,17 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
|
|||||||
context_header_written = 1;
|
context_header_written = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(output, "exten => %s,%d,%s,%s\n",
|
if (!ast_get_extension_priority(p)==PRIORITY_HINT)
|
||||||
ast_get_extension_name(p),
|
fprintf(output, "exten => %s,%d,%s,%s\n",
|
||||||
ast_get_extension_priority(p),
|
ast_get_extension_name(p),
|
||||||
ast_get_extension_app(p),
|
ast_get_extension_priority(p),
|
||||||
(char *)ast_get_extension_app_data(p));
|
ast_get_extension_app(p),
|
||||||
|
(char *)ast_get_extension_app_data(p));
|
||||||
|
else
|
||||||
|
fprintf(output, "exten => %s,hint,%s\n",
|
||||||
|
ast_get_extension_name(p),
|
||||||
|
ast_get_extension_app(p));
|
||||||
|
|
||||||
}
|
}
|
||||||
p = ast_walk_extension_priorities(e, p);
|
p = ast_walk_extension_priorities(e, p);
|
||||||
}
|
}
|
||||||
@@ -1058,6 +1066,7 @@ static int handle_context_add_extension(int fd, int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
char *whole_exten;
|
char *whole_exten;
|
||||||
char *exten, *prior;
|
char *exten, *prior;
|
||||||
|
int iprior = -2;
|
||||||
char *cidmatch, *app, *app_data;
|
char *cidmatch, *app, *app_data;
|
||||||
char *start, *end;
|
char *start, *end;
|
||||||
|
|
||||||
@@ -1075,6 +1084,11 @@ static int handle_context_add_extension(int fd, int argc, char *argv[])
|
|||||||
cidmatch = NULL;
|
cidmatch = NULL;
|
||||||
}
|
}
|
||||||
prior = strsep(&whole_exten,",");
|
prior = strsep(&whole_exten,",");
|
||||||
|
if (!strcmp(prior, "hint")) {
|
||||||
|
iprior = PRIORITY_HINT;
|
||||||
|
} else {
|
||||||
|
iprior = atoi(prior);
|
||||||
|
}
|
||||||
app = strsep(&whole_exten,",");
|
app = strsep(&whole_exten,",");
|
||||||
if ((start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
|
if ((start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
|
||||||
*start = *end = '\0';
|
*start = *end = '\0';
|
||||||
@@ -1085,9 +1099,11 @@ static int handle_context_add_extension(int fd, int argc, char *argv[])
|
|||||||
} else
|
} else
|
||||||
app_data = whole_exten;
|
app_data = whole_exten;
|
||||||
|
|
||||||
if (!exten || !prior || !app || !app_data) return RESULT_SHOWUSAGE;
|
if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT)) return RESULT_SHOWUSAGE;
|
||||||
|
|
||||||
if (ast_add_extension(argv[4], argc == 6 ? 1 : 0, exten, atoi(prior), cidmatch, app,
|
if (!app_data)
|
||||||
|
app_data="";
|
||||||
|
if (ast_add_extension(argv[4], argc == 6 ? 1 : 0, exten, iprior, cidmatch, app,
|
||||||
(void *)strdup(app_data), free, registrar)) {
|
(void *)strdup(app_data), free, registrar)) {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case ENOMEM:
|
case ENOMEM:
|
||||||
@@ -1500,6 +1516,7 @@ static int pbx_load_module(void)
|
|||||||
while(v) {
|
while(v) {
|
||||||
if (!strcasecmp(v->name, "exten")) {
|
if (!strcasecmp(v->name, "exten")) {
|
||||||
char *stringp=NULL;
|
char *stringp=NULL;
|
||||||
|
int ipri = -2;
|
||||||
tc = strdup(v->value);
|
tc = strdup(v->value);
|
||||||
if(tc!=NULL){
|
if(tc!=NULL){
|
||||||
stringp=tc;
|
stringp=tc;
|
||||||
@@ -1509,6 +1526,10 @@ static int pbx_load_module(void)
|
|||||||
pri = strsep(&stringp, ",");
|
pri = strsep(&stringp, ",");
|
||||||
if (!pri)
|
if (!pri)
|
||||||
pri="";
|
pri="";
|
||||||
|
if (!strcmp(pri,"hint"))
|
||||||
|
ipri=PRIORITY_HINT;
|
||||||
|
else
|
||||||
|
ipri=atoi(pri);
|
||||||
appl = stringp;
|
appl = stringp;
|
||||||
if (!appl)
|
if (!appl)
|
||||||
appl="";
|
appl="";
|
||||||
@@ -1544,7 +1565,7 @@ static int pbx_load_module(void)
|
|||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
data="";
|
data="";
|
||||||
if (ast_add_extension2(con, 0, ext, atoi(pri), cidmatch, appl, strdup(data), free, registrar)) {
|
if (ast_add_extension2(con, 0, ext, ipri, cidmatch, appl, strdup(data), free, registrar)) {
|
||||||
ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
|
ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
|
||||||
}
|
}
|
||||||
free(tc);
|
free(tc);
|
||||||
|
|||||||
Reference in New Issue
Block a user