[asterisk-commits] qwell: trunk r56594 - in /trunk: channels/
configs/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Fri Feb 23 19:23:44 MST 2007
Author: qwell
Date: Fri Feb 23 20:23:43 2007
New Revision: 56594
URL: http://svn.digium.com/view/asterisk?view=rev&rev=56594
Log:
Allow a Skinny device to monitor a dialplan hint (w00t!).
See skinny.conf.sample for configuration example.
Note: Some devices (seen on 12SP+/30VIP) will lock up if they monitor too many hints.
This seems to be a hardware limitation - there isn't anything we can do about it.
Modified:
trunk/channels/chan_skinny.c
trunk/configs/skinny.conf.sample
Modified: trunk/channels/chan_skinny.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_skinny.c?view=diff&rev=56594&r1=56593&r2=56594
==============================================================================
--- trunk/channels/chan_skinny.c (original)
+++ trunk/channels/chan_skinny.c Fri Feb 23 20:23:43 2007
@@ -409,8 +409,8 @@
/* Custom button types - add our own between 0xB0 and 0xCF.
This may need to be revised in the future,
if stimuluses are ever added in this range. */
-#define BT_CUST_LINESPEEDDIAL 0xB0 /* line or speeddial */
-#define BT_CUST_HINT 0xB1 /* pipe dream */
+#define BT_CUST_LINESPEEDDIAL 0xB0 /* line or speeddial with/without hint */
+#define BT_CUST_LINE 0xB1 /* line or speeddial with hint only */
struct button_template_res_message {
uint32_t buttonOffset;
@@ -830,6 +830,7 @@
#define SKINNY_TRANSFER 10
#define SKINNY_PARK 11
#define SKINNY_PROGRESS 12
+#define SKINNY_CALLREMOTEMULTILINE 13
#define SKINNY_INVALID 14
#define SKINNY_SILENCE 0x00
@@ -974,8 +975,12 @@
struct skinny_speeddial {
ast_mutex_t lock;
char label[42];
+ char context[AST_MAX_CONTEXT];
char exten[AST_MAX_EXTENSION];
int instance;
+ int stateid;
+ int laststate;
+ int isHint;
struct skinny_speeddial *next;
struct skinny_device *parent;
@@ -1059,6 +1064,8 @@
/* .bridge = ast_rtp_bridge, */
};
+static int skinny_extensionstate_cb(char *context, char* exten, int state, void *data);
+
static void *get_button_template(struct skinnysession *s, struct button_definition_template *btn)
{
struct skinny_device *d = s->device;
@@ -1070,7 +1077,7 @@
case SKINNY_DEVICE_30VIP:
/* 13 rows, 2 columns */
for (i = 0; i < 4; i++)
- (btn++)->buttonDefinition = BT_LINE;
+ (btn++)->buttonDefinition = BT_CUST_LINE;
(btn++)->buttonDefinition = BT_REDIAL;
(btn++)->buttonDefinition = BT_VOICEMAIL;
(btn++)->buttonDefinition = BT_CALLPARK;
@@ -1087,16 +1094,15 @@
case SKINNY_DEVICE_12:
/* 6 rows, 2 columns */
for (i = 0; i < 2; i++)
- (btn++)->buttonDefinition = BT_LINE;
- (btn++)->buttonDefinition = BT_REDIAL;
- for (i = 0; i < 3; i++)
+ (btn++)->buttonDefinition = BT_CUST_LINE;
+ for (i = 0; i < 4; i++)
(btn++)->buttonDefinition = BT_SPEEDDIAL;
(btn++)->buttonDefinition = BT_HOLD;
+ (btn++)->buttonDefinition = BT_REDIAL;
(btn++)->buttonDefinition = BT_TRANSFER;
(btn++)->buttonDefinition = BT_FORWARDALL;
(btn++)->buttonDefinition = BT_CALLPARK;
(btn++)->buttonDefinition = BT_VOICEMAIL;
- (btn++)->buttonDefinition = BT_CONFERENCE;
break;
case SKINNY_DEVICE_7910:
(btn++)->buttonDefinition = BT_LINE;
@@ -1285,12 +1291,12 @@
return sub;
}
-static struct skinny_speeddial *find_speeddial_by_instance(struct skinny_device *d, int instance)
+static struct skinny_speeddial *find_speeddial_by_instance(struct skinny_device *d, int instance, int isHint)
{
struct skinny_speeddial *sd;
for (sd = d->speeddials; sd; sd = sd->next) {
- if (sd->instance == instance)
+ if (sd->isHint == isHint && sd->instance == instance)
break;
}
@@ -1344,10 +1350,11 @@
}
}
-
static int skinny_register(struct skinny_req *req, struct skinnysession *s)
{
struct skinny_device *d;
+ struct skinny_line *l;
+ struct skinny_speeddial *sd;
struct sockaddr_in sin;
socklen_t slen;
@@ -1369,6 +1376,13 @@
sin.sin_addr = __ourip;
}
d->ourip = sin.sin_addr;
+
+ for (sd = d->speeddials; sd; sd = sd->next) {
+ sd->stateid = ast_extension_state_add(sd->context, sd->exten, skinny_extensionstate_cb, sd);
+ }
+ for (l = d->lines; l; l = l->next) {
+ ast_device_state_changed("Skinny/%s@%s", l->name, d->name);
+ }
break;
}
}
@@ -1382,12 +1396,22 @@
static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
{
struct skinny_device *d;
+ struct skinny_line *l;
+ struct skinny_speeddial *sd;
d = s->device;
if (d) {
d->session = NULL;
d->registered = 0;
+
+ for (sd = d->speeddials; sd; sd = sd->next) {
+ if (sd->stateid > -1)
+ ast_extension_state_del(sd->stateid, NULL);
+ }
+ for (l = d->lines; l; l = l->next) {
+ ast_device_state_changed("Skinny/%s@%s", l->name, d->name);
+ }
}
return -1; /* main loop will destroy the session */
@@ -1682,6 +1706,59 @@
req->data.dialednumber.callReference = htolel(callid);
transmit_response(s, req);
+}
+
+static int skinny_extensionstate_cb(char *context, char *exten, int state, void *data)
+{
+ struct skinny_speeddial *sd = data;
+ struct skinny_device *d = sd->parent;
+ struct skinnysession *s = d->session;
+ char hint[AST_MAX_EXTENSION];
+ int callstate = SKINNY_CALLREMOTEMULTILINE;
+ int lamp = SKINNY_LAMP_OFF;
+
+ switch (state) {
+ case AST_EXTENSION_DEACTIVATED: /* Retry after a while */
+ case AST_EXTENSION_REMOVED: /* Extension is gone */
+ ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify Device %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", d->name);
+ sd->stateid = -1;
+ callstate = SKINNY_ONHOOK;
+ lamp = SKINNY_LAMP_OFF;
+ break;
+ case AST_EXTENSION_RINGING:
+ case AST_EXTENSION_UNAVAILABLE:
+ callstate = SKINNY_RINGIN;
+ lamp = SKINNY_LAMP_BLINK;
+ break;
+ case AST_EXTENSION_BUSY: /* callstate = SKINNY_BUSY wasn't wanting to work - I'll settle for this */
+ case AST_EXTENSION_INUSE:
+ callstate = SKINNY_CALLREMOTEMULTILINE;
+ lamp = SKINNY_LAMP_ON;
+ break;
+ case AST_EXTENSION_ONHOLD:
+ callstate = SKINNY_HOLD;
+ lamp = SKINNY_LAMP_WINK;
+ break;
+ case AST_EXTENSION_NOT_INUSE:
+ default:
+ callstate = SKINNY_ONHOOK;
+ lamp = SKINNY_LAMP_OFF;
+ break;
+ }
+
+ if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, sd->context, sd->exten)) {
+ /* If they are not registered, we will override notification and show no availability */
+ if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
+ callstate = SKINNY_ONHOOK;
+ lamp = SKINNY_LAMP_FLASH;
+ }
+ }
+
+ transmit_lamp_indication(s, STIMULUS_LINE, sd->instance, lamp);
+ transmit_callstate(s, sd->instance, callstate, 0);
+ sd->laststate = state;
+
+ return 0;
}
/*
@@ -2099,17 +2176,25 @@
if (!(sd = ast_calloc(1, sizeof(struct skinny_speeddial)))) {
return NULL;
} else {
- char *stringp, *exten, *label;
+ char *stringp, *exten, *context, *label;
stringp = v->value;
exten = strsep(&stringp, ",");
- label = strsep(&stringp, ",");
+ if ((context = strchr(exten, '@'))) {
+ *context++ = '\0';
+ }
+ label = stringp;
ast_mutex_init(&sd->lock);
ast_copy_string(sd->exten, exten, sizeof(sd->exten));
- if (label)
- ast_copy_string(sd->label, label, sizeof(sd->label));
- else
- ast_copy_string(sd->label, exten, sizeof(sd->label));
- sd->instance = speeddialInstance++;
+ if (!ast_strlen_zero(context)) {
+ sd->isHint = 1;
+ sd->instance = lineInstance++;
+ ast_copy_string(sd->context, context, sizeof(sd->context));
+ } else {
+ sd->isHint = 0;
+ sd->instance = speeddialInstance++;
+ sd->context[0] = '\0';
+ }
+ ast_copy_string(sd->label, S_OR(label, exten), sizeof(sd->label));
sd->parent = d;
@@ -2833,7 +2918,7 @@
req->data.stopmedia.passThruPartyId = htolel(sub->callid);
transmit_response(s, req);
- transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
+ transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_WINK);
sub->onhold = 1;
return 1;
}
@@ -3058,7 +3143,7 @@
ast_verbose("Received Stimulus: SpeedDial(%d)\n", instance);
#if 0
- if (!(sd = find_speeddial_by_instance(d, instance))) {
+ if (!(sd = find_speeddial_by_instance(d, instance, 0))) {
return 0;
}
@@ -3162,7 +3247,7 @@
if (skinnydebug)
ast_verbose("Received Stimulus: Line(%d)\n", instance);
- l = find_line_by_instance(s->device, instance);
+ l = find_line_by_instance(d, instance);
if (!l) {
return 0;
@@ -3174,6 +3259,8 @@
transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
l->hookstate = SKINNY_OFFHOOK;
+
+ ast_device_state_changed("Skinny/%s@%s", l->name, d->name);
if (sub && sub->outgoing) {
/* We're answering a ringing call */
@@ -3216,6 +3303,8 @@
ast_verbose("RECEIVED UNKNOWN STIMULUS: %d(%d)\n", event, instance);
break;
}
+ ast_device_state_changed("Skinny/%s@%s", l->name, d->name);
+
return 1;
}
@@ -3243,15 +3332,16 @@
l = sub->parent;
}
+ transmit_ringer_mode(s, SKINNY_RING_OFF);
+ l->hookstate = SKINNY_OFFHOOK;
+
+ ast_device_state_changed("Skinny/%s@%s", l->name, d->name);
+
if (sub && sub->onhold) {
- transmit_ringer_mode(s, SKINNY_RING_OFF);
- l->hookstate = SKINNY_OFFHOOK;
return 1;
}
- transmit_ringer_mode(s, SKINNY_RING_OFF);
transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
- l->hookstate = SKINNY_OFFHOOK;
if (sub && sub->outgoing) {
/* We're answering a ringing call */
@@ -3308,17 +3398,19 @@
}
l = sub->parent;
- if (sub->onhold) {
- l->hookstate = SKINNY_ONHOOK;
- return 0;
- }
-
if (l->hookstate == SKINNY_ONHOOK) {
/* Something else already put us back on hook */
return 0;
}
+ l->hookstate = SKINNY_ONHOOK;
+
+ ast_device_state_changed("Skinny/%s@%s", l->name, d->name);
+
+ if (sub->onhold) {
+ return 0;
+ }
+
sub->cxmode = SKINNY_CX_RECVONLY;
- l->hookstate = SKINNY_ONHOOK;
transmit_callstate(s, l->instance, l->hookstate, sub->callid);
if (skinnydebug)
ast_verbose("Skinny %s@%s went on hook\n", l->name, d->name);
@@ -3393,7 +3485,7 @@
instance = letohl(req->data.speeddialreq.speedDialNumber);
- sd = find_speeddial_by_instance(d, instance);
+ sd = find_speeddial_by_instance(d, instance, 0);
if (!sd) {
return 0;
@@ -3414,6 +3506,7 @@
{
struct skinny_device *d = s->device;
struct skinny_line *l;
+ struct skinny_speeddial *sd = NULL;
int instance;
instance = letohl(req->data.line.lineNumber);
@@ -3423,6 +3516,10 @@
l = find_line_by_instance(d, instance);
if (!l) {
+ sd = find_speeddial_by_instance(d, instance, 1);
+ }
+
+ if (!l && !sd) {
return 0;
}
@@ -3432,10 +3529,13 @@
return -1;
req->data.linestat.lineNumber = letohl(instance);
- memcpy(req->data.linestat.lineDirNumber, l->name,
- sizeof(req->data.linestat.lineDirNumber));
- memcpy(req->data.linestat.lineDisplayName, l->label,
- sizeof(req->data.linestat.lineDisplayName));
+ if (!l) {
+ memcpy(req->data.linestat.lineDirNumber, sd->label, sizeof(req->data.linestat.lineDirNumber));
+ memcpy(req->data.linestat.lineDisplayName, sd->label, sizeof(req->data.linestat.lineDisplayName));
+ } else {
+ memcpy(req->data.linestat.lineDirNumber, l->name, sizeof(req->data.linestat.lineDirNumber));
+ memcpy(req->data.linestat.lineDisplayName, l->label, sizeof(req->data.linestat.lineDisplayName));
+ }
transmit_response(s,req);
return 1;
}
@@ -3483,7 +3583,7 @@
for (i=0; i<42; i++) {
int btnSet = 0;
switch (btn[i].buttonDefinition) {
- case BT_CUST_LINESPEEDDIAL:
+ case BT_CUST_LINE:
/* assume failure */
req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
req->data.buttontemplate.definition[i].instanceNumber = htolel(0);
@@ -3502,7 +3602,46 @@
if (!btnSet) {
for (sd = d->speeddials; sd; sd = sd->next) {
- if (sd->instance == speeddialInstance) {
+ if (sd->isHint && sd->instance == lineInstance) {
+ ast_verbose("Adding button: %d, %d\n", BT_LINE, lineInstance);
+ req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
+ req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance);
+ lineInstance++;
+ buttonCount++;
+ btnSet = 1;
+ break;
+ }
+ }
+ }
+ break;
+ case BT_CUST_LINESPEEDDIAL:
+ /* assume failure */
+ req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
+ req->data.buttontemplate.definition[i].instanceNumber = htolel(0);
+
+ for (l = d->lines; l; l = l->next) {
+ if (l->instance == lineInstance) {
+ ast_verbose("Adding button: %d, %d\n", BT_LINE, lineInstance);
+ req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
+ req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance);
+ lineInstance++;
+ buttonCount++;
+ btnSet = 1;
+ break;
+ }
+ }
+
+ if (!btnSet) {
+ for (sd = d->speeddials; sd; sd = sd->next) {
+ if (sd->isHint && sd->instance == lineInstance) {
+ ast_verbose("Adding button: %d, %d\n", BT_LINE, lineInstance);
+ req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
+ req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance);
+ lineInstance++;
+ buttonCount++;
+ btnSet = 1;
+ break;
+ } else if (!sd->isHint && sd->instance == speeddialInstance) {
ast_verbose("Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
req->data.buttontemplate.definition[i].instanceNumber = htolel(speeddialInstance);
@@ -3535,18 +3674,16 @@
req->data.buttontemplate.definition[i].instanceNumber = 0;
for (sd = d->speeddials; sd; sd = sd->next) {
- if (sd->instance == speeddialInstance) {
+ if (!sd->isHint && sd->instance == speeddialInstance) {
ast_verbose("Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
- req->data.buttontemplate.definition[i].instanceNumber = htolel(speeddialInstance);
+ req->data.buttontemplate.definition[i].instanceNumber = htolel(speeddialInstance - 1);
speeddialInstance++;
buttonCount++;
btnSet = 1;
break;
}
}
- break;
- case BT_CUST_HINT:
break;
case BT_NONE:
break;
@@ -3737,6 +3874,8 @@
ast_verbose("Received Softkey Event: %d(%d)\n", event, instance);
return 0;
}
+
+ ast_device_state_changed("Skinny/%s@%s", l->name, d->name);
switch(event) {
case SOFTKEY_NONE:
@@ -3965,6 +4104,8 @@
ast_verbose("Received unknown Softkey Event: %d(%d)\n", event, instance);
break;
}
+ ast_device_state_changed("Skinny/%s@%s", l->name, d->name);
+
return 1;
}
Modified: trunk/configs/skinny.conf.sample
URL: http://svn.digium.com/view/asterisk/trunk/configs/skinny.conf.sample?view=diff&rev=56594&r1=56593&r2=56594
==============================================================================
--- trunk/configs/skinny.conf.sample (original)
+++ trunk/configs/skinny.conf.sample Fri Feb 23 20:23:43 2007
@@ -83,7 +83,7 @@
;linelabel="John"
;mailbox=110
;line => 110
-;speeddial => 111,Jack Smith
-;speeddial => 112,Bob Peterson
+;speeddial => 111,Jack Smith ; Adds a speeddial button to a device.
+;speeddial => 112 at hints,Bob Peterson ; When a context is specified, the speeddial watches a dialplan hint.
;addon => 7914
;addon => 7914
More information about the asterisk-commits
mailing list