Index: channels/chan_skinny.c =================================================================== --- channels/chan_skinny.c (revision 68156) +++ channels/chan_skinny.c (working copy) @@ -169,6 +169,13 @@ uint32_t callReference; }; + +#define ENBLOC_CALL_MESSAGE 0x0004 +struct enbloc_call_message { + char calledParty[24]; +}; + + #define STIMULUS_MESSAGE 0x0005 struct stimulus_message { uint32_t stimulus; @@ -260,15 +267,20 @@ #define START_TONE_MESSAGE 0x0082 struct start_tone_message { uint32_t tone; + uint32_t space[3]; }; #define STOP_TONE_MESSAGE 0x0083 +struct stop_tone_message { + uint32_t space[2]; +}; #define SET_RINGER_MESSAGE 0x0085 struct set_ringer_message { uint32_t ringerMode; uint32_t unknown1; /* See notes in transmit_ringer_mode */ uint32_t unknown2; + uint32_t space[2]; }; #define SET_LAMP_MESSAGE 0x0086 @@ -293,7 +305,7 @@ struct media_qualifier { uint32_t precedence; uint32_t vad; - uint32_t packets; + uint16_t packets; uint32_t bitRate; }; @@ -305,12 +317,14 @@ uint32_t packetSize; uint32_t payloadType; struct media_qualifier qualifier; + uint32_t space[16]; }; #define STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B struct stop_media_transmission_message { uint32_t conferenceId; uint32_t passThruPartyId; + uint32_t space[3]; }; #define CALL_INFO_MESSAGE 0x008F @@ -332,6 +346,7 @@ char calledPartyVoiceMailbox[24]; char originalCalledPartyVoiceMailbox[24]; char lastRedirectingVoiceMailbox[24]; + uint32_t space[3]; }; #define SPEED_DIAL_STAT_RES_MESSAGE 0x0091 @@ -345,8 +360,8 @@ struct line_stat_res_message { uint32_t lineNumber; char lineDirNumber[24]; - char lineDisplayName[42]; - uint32_t space; + char lineDisplayName[24]; + uint32_t space[15]; }; #define DEFINETIMEDATE_MESSAGE 0x0094 @@ -431,7 +446,6 @@ }; #define CLEAR_NOTIFY_MESSAGE 0x0115 -#define CLEAR_PROMPT_MESSAGE 0x0113 #define CLEAR_DISPLAY_MESSAGE 0x009A #define CAPABILITIES_REQ_MESSAGE 0x009B @@ -467,12 +481,14 @@ uint32_t capability; uint32_t echo; uint32_t bitrate; + uint32_t space[16]; }; #define CLOSE_RECEIVE_CHANNEL_MESSAGE 0x0106 struct close_receive_channel_message { uint32_t conferenceId; uint32_t partyId; + uint32_t space[2]; }; #define SOFT_KEY_TEMPLATE_RES_MESSAGE 0x0108 @@ -543,6 +559,7 @@ static const uint8_t soft_key_default_onhook[] = { SOFTKEY_REDIAL, + SOFTKEY_NEWCALL, SOFTKEY_CFWDALL, SOFTKEY_CFWDBUSY, SOFTKEY_GPICKUP, @@ -662,6 +679,7 @@ uint32_t callState; uint32_t lineInstance; uint32_t callReference; + uint32_t space[3]; }; #define DISPLAY_PROMPT_STATUS_MESSAGE 0x0112 @@ -672,6 +690,12 @@ uint32_t callReference; }; +#define CLEAR_PROMPT_MESSAGE 0x0113 +struct clear_prompt_message { + uint32_t lineInstance; + uint32_t callReference; +}; + #define DISPLAY_NOTIFY_MESSAGE 0x0114 struct display_notify_message { uint32_t displayTimeout; @@ -701,6 +725,7 @@ struct button_template_res_message buttontemplate; struct displaytext_message displaytext; struct display_prompt_status_message displaypromptstatus; + struct clear_prompt_message clearpromptstatus; struct definetimedate_message definetimedate; struct start_tone_message starttone; struct speed_dial_stat_res_message speeddial; @@ -730,6 +755,7 @@ struct display_notify_message displaynotify; struct dialed_number_message dialednumber; struct soft_key_event_message softkeyeventmessage; + struct enbloc_call_message enbloccallmessage; }; /* packet composition */ @@ -929,7 +957,7 @@ struct skinny_line { ast_mutex_t lock; char name[80]; - char label[42]; /* Label that shows next to the line buttons */ + char label[24]; /* Label that shows next to the line buttons */ char accountcode[AST_MAX_ACCOUNT_CODE]; char exten[AST_MAX_EXTENSION]; /* Extension where to start */ char context[AST_MAX_CONTEXT]; @@ -1208,6 +1237,9 @@ if (!instance) instance = 1; + if (!instance) + instance = 1; + for (l = d->lines; l; l = l->next) { if (l->instance == instance) break; @@ -1598,7 +1630,7 @@ if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE))) return; } else { - if (!(req = req_alloc(0, STOP_TONE_MESSAGE))) + if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE))) return; } @@ -1665,9 +1697,12 @@ struct skinny_req *req; if (text == 0) { - if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE))) + if (!(req = req_alloc(sizeof(struct clear_prompt_message), CLEAR_PROMPT_MESSAGE))) return; + req->data.clearpromptstatus.lineInstance = 0; + req->data.clearpromptstatus.callReference = 0; + if (skinnydebug) ast_verbose("Clearing Display\n"); } else { @@ -1702,17 +1737,28 @@ { struct skinny_req *req; - if (!(req = req_alloc(sizeof(struct display_prompt_status_message), DISPLAY_PROMPT_STATUS_MESSAGE))) - return; + if (text == 0) { + if (!(req = req_alloc(sizeof(struct clear_prompt_message), CLEAR_PROMPT_MESSAGE))) + return; - ast_copy_string(req->data.displaypromptstatus.promptMessage, text, sizeof(req->data.displaypromptstatus.promptMessage)); - req->data.displaypromptstatus.messageTimeout = htolel(t); - req->data.displaypromptstatus.lineInstance = htolel(instance); - req->data.displaypromptstatus.callReference = htolel(callid); + req->data.clearpromptstatus.lineInstance = htolel(instance); + req->data.clearpromptstatus.callReference = htolel(callid); - if (skinnydebug) - ast_verbose("Displaying Prompt Status '%s'\n", text); + if (skinnydebug) + ast_verbose("Clearing Prompt\n"); + } else { + if (!(req = req_alloc(sizeof(struct display_prompt_status_message), DISPLAY_PROMPT_STATUS_MESSAGE))) + return; + ast_copy_string(req->data.displaypromptstatus.promptMessage, text, sizeof(req->data.displaypromptstatus.promptMessage)); + req->data.displaypromptstatus.messageTimeout = htolel(t); + req->data.displaypromptstatus.lineInstance = htolel(instance); + req->data.displaypromptstatus.callReference = htolel(callid); + + if (skinnydebug) + ast_verbose("Displaying Prompt Status '%s'\n", text); + } + transmit_response(s, req); } @@ -3904,6 +3957,56 @@ return 1; } +static int handle_enbloc_call_message(struct skinny_req *req, struct skinnysession *s) +{ + struct skinny_device *d = s->device; + struct skinny_line *l; + struct skinny_subchannel *sub = NULL; + struct ast_channel *c; + pthread_t t; + + if (skinnydebug) + ast_verbose("Received Enbloc Call: %s\n", req->data.enbloccallmessage.calledParty); + + sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); + + if (!sub) { + l = find_line_by_instance(d, d->lastlineinstance); + if (!l) { + return 0; + } + } else { + l = sub->parent; + } + + c = skinny_new(l, AST_STATE_DOWN); + + if(!c) { + ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); + } else { + l->hookstate = SKINNY_OFFHOOK; + + sub = c->tech_pvt; + transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid); + if (skinnydebug) + ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); + transmit_displaymessage(s, NULL); /* clear display */ + transmit_tone(s, SKINNY_DIALTONE); + + if (!ast_ignore_pattern(c->context, req->data.enbloccallmessage.calledParty)) { + transmit_tone(s, SKINNY_SILENCE); + } + ast_copy_string(c->exten, req->data.enbloccallmessage.calledParty, sizeof(c->exten)); + if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { + ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); + ast_hangup(c); + } + } + + return 1; +} + + static int handle_soft_key_set_req_message(struct skinny_req *req, struct skinnysession *s) { int i; @@ -3925,6 +4028,7 @@ for (i = 0; i < (sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); i++) { if (defaults[y] == i+1) { req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyTemplateIndex[y] = htolel(i+1); + req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyInfoIndex[y] = htolel(i+301); } } } @@ -4308,6 +4424,9 @@ } else res = handle_keypad_button_message(req, s); break; + case ENBLOC_CALL_MESSAGE: + res = handle_enbloc_call_message(req, s); + break; case STIMULUS_MESSAGE: res = handle_stimulus_message(req, s); break; @@ -4330,6 +4449,8 @@ res = handle_speed_dial_stat_req_message(req, s); break; case LINE_STATE_REQ_MESSAGE: + if (skinnydebug) + ast_verbose("Received LineStatRequest\n"); res = handle_line_state_req_message(req, s); break; case TIME_DATE_REQ_MESSAGE: