fixup and merge in FS-4027 enhancements for additional device support

This commit is contained in:
Nathan Neulinger 2013-07-12 11:39:23 -05:00
parent 5c9bb344ab
commit f21d4a0fc0
3 changed files with 306 additions and 46 deletions

View File

@ -623,6 +623,26 @@ switch_status_t perform_send_set_speaker_mode(listener_t *listener,
return skinny_send_reply_quiet(listener, message);
}
switch_status_t perform_send_srvreq_response(listener_t *listener,
const char *file, const char *func, int line,
char *ip, uint32_t port)
{
skinny_message_t *message;
message = switch_core_alloc(listener->pool, 12+sizeof(message->data.serv_res_mess));
message->type = SERVER_RESPONSE_MESSAGE;
message->length = 4 + sizeof(message->data.serv_res_mess);
message->data.serv_res_mess.serverListenPort[0] = port;
switch_inet_pton(AF_INET,ip, &message->data.serv_res_mess.serverIpAddr[0]);
switch_copy_string(message->data.serv_res_mess.server[0].serverName,ip,sizeof(message->data.serv_res_mess.server[0].serverName));
skinny_log_l_ffl(listener, file, func, line, SWITCH_LOG_DEBUG,
"Sending Server Request Response with IP (%s) and Port (%d)\n", ip, port);
return skinny_send_reply(listener, message);
}
switch_status_t perform_send_start_media_transmission(listener_t *listener,
const char *file, const char *func, int line,
uint32_t conference_id,

View File

@ -36,6 +36,53 @@
/* mod_skinny.h should be loaded first */
#include "mod_skinny.h"
/*****************************************************************************/
/* SKINNY TYPES */
/*****************************************************************************/
typedef enum {
SKINNY_CODEC_NONE = 0,
SKINNY_CODEC_NONSTANDARD = 1,
SKINNY_CODEC_ALAW_64K = 2,
SKINNY_CODEC_ALAW_56K = 3,
SKINNY_CODEC_ULAW_64K = 4,
SKINNY_CODEC_ULAW_56K = 5,
SKINNY_CODEC_G722_64K = 6,
SKINNY_CODEC_G722_56K = 7,
SKINNY_CODEC_G722_48K = 8,
SKINNY_CODEC_G723_1 = 9,
SKINNY_CODEC_G728 = 10,
SKINNY_CODEC_G729 = 11,
SKINNY_CODEC_G729A = 12,
SKINNY_CODEC_IS11172 = 13,
SKINNY_CODEC_IS13818 = 14,
SKINNY_CODEC_G729B = 15,
SKINNY_CODEC_G729AB = 16,
SKINNY_CODEC_GSM_FULL = 18,
SKINNY_CODEC_GSM_HALF = 19,
SKINNY_CODEC_GSM_EFULL = 20,
SKINNY_CODEC_WIDEBAND_256K = 25,
SKINNY_CODEC_DATA_64K = 32,
SKINNY_CODEC_DATA_56K = 33,
SKINNY_CODEC_G722_1_32K = 40,
SKINNY_CODEC_G722_1_24K = 41,
SKINNY_CODEC_GSM = 80,
SKINNY_CODEC_ACTIVEVOICE = 81,
SKINNY_CODEC_G726_32K = 82,
SKINNY_CODEC_G726_24K = 83,
SKINNY_CODEC_G726_16K = 84,
SKINNY_CODEC_G729B_BIS = 85,
SKINNY_CODEC_G729B_LOW = 86,
SKINNY_CODEC_H261 = 100,
SKINNY_CODEC_H263 = 101,
SKINNY_CODEC_VIDEO = 102,
SKINNY_CODEC_H264 = 103,
SKINNY_CODEC_T120 = 105,
SKINNY_CODEC_H224 = 106,
SKINNY_CODEC_RFC2833_DYNPAYLOAD = 257
} skinny_codecs;
char* skinny_codec2string(skinny_codecs skinnycodec);
/*****************************************************************************/
/* SKINNY MESSAGE DATA */
/*****************************************************************************/
@ -211,6 +258,145 @@ struct PACKED data_message {
#define DEVICE_UPDATECAPABILITIES 0x0030
#define MAX_CUSTOM_PICTURES 6
#define MAX_LAYOUT_WITH_SAME_SERVICE 5
#define MAX_SERVICE_TYPE 4
#define SKINNY_MAX_CAPABILITIES 18 /*!< max capabilities allowed in Cap response message */
#define SKINNY_MAX_VIDEO_CAPABILITIES 10
#define SKINNY_MAX_DATA_CAPABILITIES 5
#define MAX_LEVEL_PREFERENCE 4
/*!
* \brief Picture Format Structure
*/
typedef struct {
uint32_t customPictureFormatWidth; /*!< Picture Width */
uint32_t customPictureFormatHeight; /*!< Picture Height */
uint32_t customPictureFormatpixelAspectRatio; /*!< Picture Pixel Aspect Ratio */
uint32_t customPictureFormatpixelclockConversionCode; /*!< Picture Pixel Conversion Code */
uint32_t customPictureFormatpixelclockDivisor; /*!< Picture Pixel Divisor */
} customPictureFormat_t;
/*!
* \brief Video Level Preference Structure
*/
typedef struct {
uint32_t transmitPreference; /*!< Transmit Preference */
uint32_t format; /*!< Format / Codec */
uint32_t maxBitRate; /*!< Maximum BitRate */
uint32_t minBitRate; /*!< Minimum BitRate */
uint32_t MPI; /*!< */
uint32_t serviceNumber; /*!< Service Number */
} levelPreference_t; /*!< Level Preference Structure */
/*!
* \brief Layout Config Structure (Update Capabilities Message Struct)
* \since 20080111
*/
typedef struct {
uint32_t layout; /*!< Layout \todo what is layout? */
} layoutConfig_t; /*!< Layout Config Structure */
/*!
* \brief Service Resource Structure
*/
typedef struct {
uint32_t layoutCount; /*!< Layout Count */
layoutConfig_t layout[MAX_LAYOUT_WITH_SAME_SERVICE]; /*!< Layout */
uint32_t serviceNum; /*!< Service Number */
uint32_t maxStreams; /*!< Maximum number of Streams */
uint32_t maxConferences; /*!< Maximum number of Conferences */
uint32_t activeConferenceOnRegistration; /*!< Active Conference On Registration */
} serviceResource_t;
/*!
* \brief Audio Capabilities Structure
*/
typedef struct {
skinny_codecs lel_payloadCapability; /*!< PayLoad Capability */
uint32_t lel_maxFramesPerPacket; /*!< Maximum Number of Frames per IP Packet */
uint32_t lel_unknown[2]; /*!< this are related to G.723 */
} audioCap_t;
/*!
* \brief Video Capabilities Structure
*/
typedef struct {
skinny_codecs lel_payloadCapability; /*!< PayLoad Capability */
uint32_t lel_transmitOreceive; /*!< Transmit of Receive */
uint32_t lel_levelPreferenceCount; /*!< Level of Preference Count */
levelPreference_t levelPreference[MAX_LEVEL_PREFERENCE]; /*!< Level Preference */
// uint32_t lel_codec_options[2]; /*!< Codec Options */
union {
struct {
uint32_t unknown1;
uint32_t unknown2;
} h263;
struct {
uint32_t profile; /*!< H264 profile */
uint32_t level; /*!< H264 level */
} h264;
} codec_options;
/**
* Codec options contains data specific for every codec
*
* Here is a list of known parameters per codec
// H.261
uint32_t lel_temporalSpatialTradeOffCapability;
uint32_t lel_stillImageTransmission;
// H.263
uint32_t lel_h263_capability_bitfield;
uint32_t lel_annexNandWFutureUse;
// Video
uint32_t lel_modelNumber;
uint32_t lel_bandwidth;
*/
} videoCap_t; /*!< Video Capabilities Structure */
/*!
* \brief Data Capabilities Structure
*/
typedef struct {
uint32_t payloadCapability; /*!< Payload Capability */
uint32_t transmitOrReceive; /*!< Transmit or Receive */
uint32_t protocolDependentData; /*!< Protocol Dependent Data */
uint32_t maxBitRate; /*!< Maximum BitRate */
} dataCap_t; /*!< Data Capabilities Structure */
struct PACKED update_capabilities_message {
uint32_t lel_audioCapCount; /*!< Audio Capability Count */
uint32_t lel_videoCapCount; /*!< Video Capability Count */
uint32_t lel_dataCapCount; /*!< Data Capability Count */
uint32_t RTPPayloadFormat; /*!< RTP Payload Format */
uint32_t customPictureFormatCount; /*!< Custom Picture Format Count */
customPictureFormat_t customPictureFormat[MAX_CUSTOM_PICTURES]; /*!< Custom Picture Format */
uint32_t activeStreamsOnRegistration; /*!< Active Streams on Registration */
uint32_t maxBW; /*!< Max BW ?? */
uint32_t serviceResourceCount; /*!< Service Resource Count */
serviceResource_t serviceResource[MAX_SERVICE_TYPE]; /*!< Service Resource */
audioCap_t audioCaps[SKINNY_MAX_CAPABILITIES]; /*!< Audio Capabilities */
videoCap_t videoCaps[SKINNY_MAX_VIDEO_CAPABILITIES]; /*!< Video Capabilities */
dataCap_t dataCaps[SKINNY_MAX_DATA_CAPABILITIES]; /*!< Data Capabilities */
uint32_t unknown; /*!< Unknown */
};
/* ServiceUrlStatReqMessage */
#define SERVICE_URL_STAT_REQ_MESSAGE 0x0033
struct PACKED service_url_stat_req_message {
@ -447,6 +633,21 @@ struct PACKED register_reject_message {
};
#define SERVER_RESPONSE_MESSAGE 0x009E
#define ServerMaxNameSize 48
#define StationMaxServers 5
/*!
* \brief Station Identifier Structure
*/
typedef struct {
char serverName[ServerMaxNameSize]; /*!< Server Name */
} ServerIdentifier;
struct PACKED server_response_message {
ServerIdentifier server[StationMaxServers]; /*!< Server Identifier */
uint32_t serverListenPort[StationMaxServers]; /*!< Server is Listening on Port */
uint32_t serverIpAddr[StationMaxServers]; /*!< Server IP Port */
}; /*!< Server Result Message Structure */
/* ResetMessage */
#define RESET_MESSAGE 0x009F
@ -676,6 +877,7 @@ union skinny_data {
/* no data for CAPABILITIES_REQ_MESSAGE */
struct register_reject_message reg_rej;
struct reset_message reset;
struct server_response_message serv_res_mess;
/* no data for KEEP_ALIVE_ACK_MESSAGE */
struct open_receive_channel_message open_receive_channel;
struct close_receive_channel_message close_receive_channel;
@ -696,6 +898,7 @@ union skinny_data {
/* see field "extended_data" for USER_TO_DEVICE_DATA_VERSION1_MESSAGE */
struct dialed_phone_book_ack_message dialed_phone_book_ack;
struct update_capabilities_message upd_cap;
struct data_message data;
struct extended_data_message extended_data;
@ -725,52 +928,7 @@ struct PACKED skinny_message {
typedef struct skinny_message skinny_message_t;
/*****************************************************************************/
/* SKINNY TYPES */
/*****************************************************************************/
typedef enum {
SKINNY_CODEC_NONE = 0,
SKINNY_CODEC_NONSTANDARD = 1,
SKINNY_CODEC_ALAW_64K = 2,
SKINNY_CODEC_ALAW_56K = 3,
SKINNY_CODEC_ULAW_64K = 4,
SKINNY_CODEC_ULAW_56K = 5,
SKINNY_CODEC_G722_64K = 6,
SKINNY_CODEC_G722_56K = 7,
SKINNY_CODEC_G722_48K = 8,
SKINNY_CODEC_G723_1 = 9,
SKINNY_CODEC_G728 = 10,
SKINNY_CODEC_G729 = 11,
SKINNY_CODEC_G729A = 12,
SKINNY_CODEC_IS11172 = 13,
SKINNY_CODEC_IS13818 = 14,
SKINNY_CODEC_G729B = 15,
SKINNY_CODEC_G729AB = 16,
SKINNY_CODEC_GSM_FULL = 18,
SKINNY_CODEC_GSM_HALF = 19,
SKINNY_CODEC_GSM_EFULL = 20,
SKINNY_CODEC_WIDEBAND_256K = 25,
SKINNY_CODEC_DATA_64K = 32,
SKINNY_CODEC_DATA_56K = 33,
SKINNY_CODEC_G722_1_32K = 40,
SKINNY_CODEC_G722_1_24K = 41,
SKINNY_CODEC_GSM = 80,
SKINNY_CODEC_ACTIVEVOICE = 81,
SKINNY_CODEC_G726_32K = 82,
SKINNY_CODEC_G726_24K = 83,
SKINNY_CODEC_G726_16K = 84,
SKINNY_CODEC_G729B_BIS = 85,
SKINNY_CODEC_G729B_LOW = 86,
SKINNY_CODEC_H261 = 100,
SKINNY_CODEC_H263 = 101,
SKINNY_CODEC_VIDEO = 102,
SKINNY_CODEC_H264 = 103,
SKINNY_CODEC_T120 = 105,
SKINNY_CODEC_H224 = 106,
SKINNY_CODEC_RFC2833_DYNPAYLOAD = 257
} skinny_codecs;
char* skinny_codec2string(skinny_codecs skinnycodec);
/*****************************************************************************/
/* SKINNY FUNCTIONS */
@ -862,6 +1020,11 @@ switch_status_t perform_send_set_speaker_mode(listener_t *listener,
uint32_t mode);
#define send_set_speaker_mode(listener, ...) perform_send_set_speaker_mode(listener, __FILE__, __SWITCH_FUNC__, __LINE__, __VA_ARGS__)
switch_status_t perform_send_srvreq_response(listener_t *listener,
const char *file, const char *func, int line,
char *ip, uint32_t port);
#define send_srvreq_response(listener, ...) perform_send_srvreq_response(listener, __FILE__, __SWITCH_FUNC__, __LINE__, __VA_ARGS__)
switch_status_t perform_send_start_media_transmission(listener_t *listener,
const char *file, const char *func, int line,
uint32_t conference_id,

View File

@ -2183,6 +2183,79 @@ switch_status_t skinny_handle_accessory_status_message(listener_t *listener, ski
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_updatecapabilities(listener_t *listener, skinny_message_t *request)
{
char *sql;
skinny_profile_t *profile;
uint32_t i = 0;
uint32_t n = 0;
char *codec_order[SWITCH_MAX_CODECS];
char *codec_string;
size_t string_len, string_pos, pos;
switch_assert(listener->profile);
switch_assert(listener->device_name);
profile = listener->profile;
skinny_check_data_length(request, sizeof(request->data.upd_cap.lel_audioCapCount));
n = request->data.upd_cap.lel_audioCapCount;
if (n > SWITCH_MAX_CODECS) {
n = SWITCH_MAX_CODECS;
}
string_len = -1;
skinny_check_data_length(request, sizeof(request->data.upd_cap.lel_audioCapCount) + n * sizeof(request->data.upd_cap.audioCaps[0]));
for (i = 0; i < n; i++) {
char *codec = skinny_codec2string(request->data.upd_cap.audioCaps[i].lel_payloadCapability);
codec_order[i] = codec;
string_len += strlen(codec)+1;
}
i = 0;
pos = 0;
codec_string = switch_core_alloc(listener->pool, string_len+1);
for (string_pos = 0; string_pos < string_len; string_pos++) {
char *codec = codec_order[i];
switch_assert(i < n);
if(pos == strlen(codec)) {
codec_string[string_pos] = ',';
i++;
pos = 0;
} else {
codec_string[string_pos] = codec[pos++];
}
}
codec_string[string_len] = '\0';
if ((sql = switch_mprintf(
"UPDATE skinny_devices SET codec_string='%s' WHERE name='%s'",
codec_string,
listener->device_name
))) {
skinny_execute_sql(profile, sql, profile->sql_mutex);
switch_safe_free(sql);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Codecs %s supported.\n", codec_string);
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_server_req_message(listener_t *listener, skinny_message_t *request)
{
skinny_profile_t *profile;
profile = listener->profile;
skinny_log_l(listener, SWITCH_LOG_INFO, "Received Server Request Message (length=%d).\n", request->length);
send_srvreq_response(listener, profile->ip, profile->port);
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_xml_alarm(listener_t *listener, skinny_message_t *request)
{
switch_event_t *event = NULL;
@ -2208,7 +2281,7 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re
skinny_log_l(listener, SWITCH_LOG_DEBUG, "Received %s (type=%x,length=%d).\n",
skinny_message_type2str(request->type), request->type, request->length);
}
if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE && request->type != XML_ALARM_MESSAGE) {
if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE && request->type != XML_ALARM_MESSAGE && request->type != KEEP_ALIVE_MESSAGE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Device should send a register message first. Received %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length);
return SWITCH_STATUS_FALSE;
@ -2280,6 +2353,10 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re
return skinny_handle_accessory_status_message(listener, request);
case XML_ALARM_MESSAGE:
return skinny_handle_xml_alarm(listener, request);
case DEVICE_UPDATECAPABILITIES:
return skinny_handle_updatecapabilities(listener, request);
case SERVER_REQ_MESSAGE:
return skinny_handle_server_req_message(listener, request);
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Unhandled %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length);