summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--channels/chan_skinny.c113
1 files changed, 83 insertions, 30 deletions
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 7c5ca907b..070ad7b80 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -273,6 +273,9 @@ struct register_message {
uint32_t ip;
uint32_t type;
uint32_t maxStreams;
+ uint32_t space;
+ uint8_t protocolVersion;
+ char space2[3] ;
};
#define IP_PORT_MESSAGE 0x0002
@@ -350,11 +353,18 @@ struct alarm_message {
};
#define OPEN_RECEIVE_CHANNEL_ACK_MESSAGE 0x0022
-struct open_receive_channel_ack_message {
+struct open_receive_channel_ack_message_ip4 {
uint32_t status;
uint32_t ipAddr;
uint32_t port;
- uint32_t passThruId;
+ uint32_t callReference;
+};
+struct open_receive_channel_ack_message_ip6 {
+ uint32_t status;
+ uint32_t space;
+ char ipAddr[16];
+ uint32_t port;
+ uint32_t callReference;
};
#define SOFT_KEY_SET_REQ_MESSAGE 0x0025
@@ -392,6 +402,7 @@ struct start_tone_message {
struct stop_tone_message {
uint32_t instance;
uint32_t reference;
+ uint32_t space;
};
#define SET_RINGER_MESSAGE 0x0085
@@ -424,11 +435,11 @@ struct set_microphone_message {
struct media_qualifier {
uint32_t precedence;
uint32_t vad;
- uint16_t packets;
+ uint32_t packets;
uint32_t bitRate;
};
-struct start_media_transmission_message {
+struct start_media_transmission_message_ip4 {
uint32_t conferenceId;
uint32_t passThruPartyId;
uint32_t remoteIp;
@@ -436,7 +447,19 @@ struct start_media_transmission_message {
uint32_t packetSize;
uint32_t payloadType;
struct media_qualifier qualifier;
- uint32_t space[16];
+ uint32_t space[19];
+};
+
+struct start_media_transmission_message_ip6 {
+ uint32_t conferenceId;
+ uint32_t passThruPartyId;
+ uint32_t space;
+ char remoteIp[16];
+ uint32_t remotePort;
+ uint32_t packetSize;
+ uint32_t payloadType;
+ struct media_qualifier qualifier;
+ uint32_t space2[19];
};
#define STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B
@@ -580,6 +603,9 @@ struct displaytext_message {
#define CLEAR_NOTIFY_MESSAGE 0x0115
#define CLEAR_DISPLAY_MESSAGE 0x009A
+struct clear_display_message {
+ uint32_t space;
+};
#define CAPABILITIES_REQ_MESSAGE 0x009B
@@ -614,7 +640,7 @@ struct open_receive_channel_message {
uint32_t capability;
uint32_t echo;
uint32_t bitrate;
- uint32_t space[16];
+ uint32_t space[36];
};
#define CLOSE_RECEIVE_CHANNEL_MESSAGE 0x0106
@@ -1012,6 +1038,7 @@ union skinny_data {
struct version_res_message version;
struct button_template_res_message buttontemplate;
struct displaytext_message displaytext;
+ struct clear_display_message cleardisplay;
struct display_prompt_status_message displaypromptstatus;
struct clear_prompt_message clearpromptstatus;
struct definetimedate_message definetimedate;
@@ -1036,10 +1063,12 @@ union skinny_data {
struct set_speaker_message setspeaker;
struct set_microphone_message setmicrophone;
struct call_info_message callinfo;
- struct start_media_transmission_message startmedia;
+ struct start_media_transmission_message_ip4 startmedia_ip4;
+ struct start_media_transmission_message_ip6 startmedia_ip6;
struct stop_media_transmission_message stopmedia;
struct open_receive_channel_message openreceivechannel;
- struct open_receive_channel_ack_message openreceivechannelack;
+ struct open_receive_channel_ack_message_ip4 openreceivechannelack_ip4;
+ struct open_receive_channel_ack_message_ip6 openreceivechannelack_ip6;
struct close_receive_channel_message closereceivechannel;
struct display_notify_message displaynotify;
struct dialed_number_message dialednumber;
@@ -1382,6 +1411,7 @@ struct skinny_addon {
char version_id[16]; \
char vmexten[AST_MAX_EXTENSION]; \
int type; \
+ int protocolversion; \
int registered; \
int hookstate; \
int lastlineinstance; \
@@ -2057,6 +2087,7 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s)
&& ast_apply_ha(d->ha, &addr)) {
s->device = d;
d->type = letohl(req->data.reg.type);
+ d->protocolversion = letohl(req->data.reg.protocolVersion);
if (ast_strlen_zero(d->version_id)) {
ast_copy_string(d->version_id, version_id, sizeof(d->version_id));
}
@@ -2582,7 +2613,7 @@ static void transmit_ringer_mode(struct skinny_device *d, int mode)
static void transmit_clear_display_message(struct skinny_device *d, int instance, int reference)
{
struct skinny_req *req;
- if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE)))
+ if (!(req = req_alloc(sizeof(struct clear_display_message), CLEAR_DISPLAY_MESSAGE)))
return;
//what do we want hear CLEAR_DISPLAY_MESSAGE or CLEAR_PROMPT_STATUS???
@@ -2706,19 +2737,33 @@ static void transmit_startmediatransmission(struct skinny_device *d, struct skin
{
struct skinny_req *req;
- if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE)))
- return;
-
- req->data.startmedia.conferenceId = htolel(sub->callid);
- req->data.startmedia.passThruPartyId = htolel(sub->callid);
- req->data.startmedia.remoteIp = dest.sin_addr.s_addr;
- req->data.startmedia.remotePort = htolel(ntohs(dest.sin_port));
- req->data.startmedia.packetSize = htolel(fmt.cur_ms);
- req->data.startmedia.payloadType = htolel(codec_ast2skinny(&fmt.format));
- req->data.startmedia.qualifier.precedence = htolel(127);
- req->data.startmedia.qualifier.vad = htolel(0);
- req->data.startmedia.qualifier.packets = htolel(0);
- req->data.startmedia.qualifier.bitRate = htolel(0);
+ if (d->protocolversion < 17) {
+ if (!(req = req_alloc(sizeof(struct start_media_transmission_message_ip4), START_MEDIA_TRANSMISSION_MESSAGE)))
+ return;
+ req->data.startmedia_ip4.conferenceId = htolel(sub->callid);
+ req->data.startmedia_ip4.passThruPartyId = htolel(sub->callid);
+ req->data.startmedia_ip4.remoteIp = dest.sin_addr.s_addr;
+ req->data.startmedia_ip4.remotePort = htolel(ntohs(dest.sin_port));
+ req->data.startmedia_ip4.packetSize = htolel(fmt.cur_ms);
+ req->data.startmedia_ip4.payloadType = htolel(codec_ast2skinny(&fmt.format));
+ req->data.startmedia_ip4.qualifier.precedence = htolel(127);
+ req->data.startmedia_ip4.qualifier.vad = htolel(0);
+ req->data.startmedia_ip4.qualifier.packets = htolel(0);
+ req->data.startmedia_ip4.qualifier.bitRate = htolel(0);
+ } else {
+ if (!(req = req_alloc(sizeof(struct start_media_transmission_message_ip6), START_MEDIA_TRANSMISSION_MESSAGE)))
+ return;
+ req->data.startmedia_ip6.conferenceId = htolel(sub->callid);
+ req->data.startmedia_ip6.passThruPartyId = htolel(sub->callid);
+ memcpy(req->data.startmedia_ip6.remoteIp, &dest.sin_addr.s_addr, sizeof(dest.sin_addr.s_addr));
+ req->data.startmedia_ip6.remotePort = htolel(ntohs(dest.sin_port));
+ req->data.startmedia_ip6.packetSize = htolel(fmt.cur_ms);
+ req->data.startmedia_ip6.payloadType = htolel(codec_ast2skinny(&fmt.format));
+ req->data.startmedia_ip6.qualifier.precedence = htolel(127);
+ req->data.startmedia_ip6.qualifier.vad = htolel(0);
+ req->data.startmedia_ip6.qualifier.packets = htolel(0);
+ req->data.startmedia_ip6.qualifier.bitRate = htolel(0);
+ }
transmit_response(d, req);
}
@@ -6181,25 +6226,33 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
uint32_t addr;
int port;
int status;
- int passthruid;
+ int callid;
- status = letohl(req->data.openreceivechannelack.status);
+ status = (d->protocolversion<17)?letohl(req->data.openreceivechannelack_ip4.status):letohl(req->data.openreceivechannelack_ip6.status);
if (status) {
ast_log(LOG_ERROR, "Open Receive Channel Failure\n");
return 0;
}
- addr = req->data.openreceivechannelack.ipAddr;
- port = letohl(req->data.openreceivechannelack.port);
- passthruid = letohl(req->data.openreceivechannelack.passThruId);
+ if (d->protocolversion<17) {
+ addr = req->data.openreceivechannelack_ip4.ipAddr;
+ port = letohl(req->data.openreceivechannelack_ip4.port);
+ callid = letohl(req->data.openreceivechannelack_ip4.callReference);
+ } else {
+ memcpy(&addr, &req->data.openreceivechannelack_ip6.ipAddr, sizeof(addr));
+ port = letohl(req->data.openreceivechannelack_ip6.port);
+ callid = letohl(req->data.openreceivechannelack_ip6.callReference);
+ }
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = addr;
sin.sin_port = htons(port);
- sub = find_subchannel_by_reference(d, passthruid);
+ sub = find_subchannel_by_reference(d, callid);
- if (!sub)
+ if (!sub) {
+ ast_log(LOG_ERROR, "Open Receive Channel Failure - can't find sub for %d\n", callid);
return 0;
+ }
l = sub->line;
@@ -6602,7 +6655,7 @@ static int handle_message(struct skinny_req *req, struct skinnysession *s)
case REGISTER_MESSAGE:
if (skinny_register(req, s)) {
ast_atomic_fetchadd_int(&unauth_sessions, -1);
- ast_verb(3, "Device '%s' successfully registered\n", s->device->name);
+ ast_verb(3, "Device '%s' successfully registered (protoVers %d)\n", s->device->name, s->device->protocolversion);
transmit_registerack(s->device);
transmit_capabilitiesreq(s->device);
} else {