--- chan_skinny.c.bak 2004-04-02 21:45:28.649405104 -0700 +++ chan_skinny.c 2004-04-03 01:48:04.437588952 -0700 @@ -507,6 +507,9 @@ static int amaflags = 0; static int callnums = 1; +/* Speed Dial Keys */ +#define SPEED_MAX 10 +static char *speed[SPEED_MAX]; #define SUB_REAL 0 #define SUB_ALT 1 @@ -664,6 +667,9 @@ int progress; struct skinny_line *next; struct skinny_device *parent; + + /* Speed Dials */ + char *speed[SPEED_MAX]; }; static struct skinny_device { @@ -1044,6 +1050,12 @@ free(d); return NULL; } + } else if (!strcasecmp(v->name, "speed")) { + int sn = atoi(v->value); + if(sn < SPEED_MAX && sn >= 0) { + speed[sn] = malloc(strlen(v->value)); + strcpy(speed[sn], &v->value[2]); + } } else if (!strcasecmp(v->name, "port")) { d->addr.sin_port = htons(atoi(v->value)); } else if (!strcasecmp(v->name, "device")) { @@ -1137,6 +1149,13 @@ /* ASSUME we're onhook at this point*/ l->hookstate = SKINNY_ONHOOK; + for (i = 0; i < SPEED_MAX; i++) + if(speed[i]) { + l->speed[i] = speed[i]; + ast_verbose(VERBOSE_PREFIX_3 "Speeddial %d = %s\n", i, speed[i]); + speed[i] = NULL; + } + for (i = 0; i < MAX_SUBS; i++) { sub = malloc(sizeof(struct skinny_subchannel)); if (sub) { @@ -1803,6 +1822,94 @@ return tmp; } +/** skinny_open_line + * We must take the phone off the hook and open a line to it. If there is already a line + * open then no action needs to be taken. Some of this code should look familiar + * Methos + */ +static struct ast_channel *skinny_open_line( struct skinnysession *s, pthread_t *t) +{ + struct skinny_subchannel *sub; + struct ast_channel *c; + + sub = find_subchannel_by_line(s->device->lines); + if (!sub) { + ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name); + return 0; + } + sub->parent->hookstate = SKINNY_OFFHOOK; + + if (sub->outgoing) { + transmit_callstate(s, s->device->lines->instance, SKINNY_OFFHOOK, sub->callid); + transmit_tone(s, SKINNY_SILENCE); + ast_setstate(sub->owner, AST_STATE_UP); + // select soft keys + } else { + if (!sub->owner) { + + transmit_callstate(s, s->device->lines->instance, SKINNY_OFFHOOK, sub->callid); + transmit_speaker_mode(s, 1); + transmit_tone(s, SKINNY_DIALTONE); + c = skinny_new(sub, AST_STATE_DOWN); + if(c) { + /* start switch */ + if (pthread_create(t, NULL, skinny_ss, c)) { + ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); + ast_hangup(c); + } + } else { + ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name, s->device->name); + } + + } else { + ast_log(LOG_DEBUG, "Current sub [%s] already has owner\n", sub->owner->name); + } + } + + return c; +} + +/** skinny_speeddial + * When a speed dial button is pressed for the session, we want to dial the number. + * The speed dial number is taken from skinny.conf + * speed = 3,5551212 where the first number is the instance from the phone, and + * the second one is the number to be dialed. + * + *Methos + */ +static void skinny_speeddial(struct skinnysession *s, char *num) +{ + struct skinny_subchannel *sub; + struct ast_frame f = { 0, }; + int i; + + sub = find_subchannel_by_line(s->device->lines); + + f.frametype = AST_FRAME_DTMF; + f.src = "skinny"; + + /* I am not sure if there is a better way. */ + for( i=0; iowner) { + /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */ + ast_queue_frame(sub->owner, &f, 1); + if (sub->next->owner) { + ast_queue_frame(sub->next->owner, &f, 1); + } + } else { + printf("No owner: %s\n", s->device->lines->name); + } + + usleep(150000); + } + +} + static int handle_message(skinny_req *req, struct skinnysession *s) { struct skinny_subchannel *sub; @@ -1891,6 +1998,14 @@ if (skinnydebug) { printf("Recieved Stimulus: SpeedDial(%d)\n", stimulusInstance); } + + /* The speed dial opens a line then dials */ + + c = skinny_open_line(s, &t); + sub = find_subchannel_by_line(s->device->lines); + if(sub->parent->speed[stimulusInstance]) { + skinny_speeddial(s, sub->parent->speed[stimulusInstance]); + } break; case STIMULUS_HOLD: // Easy enough @@ -2644,6 +2759,12 @@ } llast = l; l = l->next; + + /* get rid of all the speed dials */ + for (i = 0; i < SPEED_MAX; i++) + if(speed[i]) + free(speed[i]); + free(llast); } dlast = d;