diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index baf96d4..7595f15 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -38,7 +38,7 @@ /*****************************************************************************/ /* SKINNY FUNCTIONS */ /*****************************************************************************/ -char* skinny_codec2string(enum skinny_codecs skinnycodec) +char* skinny_codec2string(skinny_codecs skinnycodec) { switch (skinnycodec) { case SKINNY_CODEC_ALAW_64K: @@ -154,10 +154,10 @@ switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req) do_sleep = 0; ptr += mlen; memcpy(request, mbuf, bytes); -#ifdef SKINNY_MEGA_DEBUG +#ifndef SKINNY_MEGA_DEBUG switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Got request: length=%d,reserved=%x,type=%x\n", - request->length,request->reserved,request->type); + "Got request: length=%d,version=%x,type=%x\n", + request->length,request->version,request->type); #endif if(request->length < SKINNY_MESSAGE_FIELD_SIZE) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, @@ -479,6 +479,8 @@ switch_status_t send_register_ack(listener_t *listener, return skinny_send_reply(listener, message); } + + switch_status_t send_start_tone(listener_t *listener, uint32_t tone, uint32_t reserved, @@ -552,6 +554,22 @@ switch_status_t send_set_speaker_mode(listener_t *listener, return skinny_send_reply(listener, message); } + +switch_status_t send_srvreq_response(listener_t *listener, 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)); + + return skinny_send_reply(listener, message); +} + switch_status_t send_start_media_transmission(listener_t *listener, uint32_t conference_id, uint32_t pass_thru_party_id, diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index a04f8bc..1d4b380 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -50,6 +50,175 @@ #pragma pack(push, r1, 1) #endif + +/**** required data strucures for Update Capabilities ***/ + +#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 + + +/*****************************************************************************/ +/* 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); + +/*! + * \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 */ + +/**** required data strucures for Updatea Capabilities ***/ + + struct PACKED register_message { char device_name[16]; uint32_t user_id; @@ -145,6 +314,10 @@ struct PACKED capabilities_res_message { struct station_capabilities caps[SWITCH_MAX_CODECS]; }; + +#define SERVER_REQ_MESSAGE 0x0012 + + /* AlarmMessage */ #define ALARM_MESSAGE 0x0020 struct PACKED alarm_message { @@ -207,6 +380,31 @@ struct PACKED data_message { #define DEVICE_TO_USER_DATA_RESPONSE_MESSAGE 0x002F /* See struct PACKED data_message */ +/* Update Capabilities */ +#define DEVICE_UPDATECAPABILITIES 0x0030 + +struct PACKED UpdateCapabilitiesMessage { + 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 */ +} ; /*!< Update Capabilities Message Structure */ + /* ServiceUrlStatReqMessage */ #define SERVICE_URL_STAT_REQ_MESSAGE 0x0033 struct PACKED service_url_stat_req_message { @@ -419,6 +617,23 @@ struct PACKED button_definition { uint8_t button_definition; /* See enum skinny_button_definition */ }; +#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 ServerResMessage { + 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 */ + + #define SKINNY_MAX_BUTTON_COUNT 42 struct PACKED button_template_message { uint32_t button_offset; @@ -670,6 +885,7 @@ union skinny_data { /* no data for CAPABILITIES_REQ_MESSAGE */ struct register_reject_message reg_rej; struct reset_message reset; + struct ServerResMessage 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; @@ -690,6 +906,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 UpdateCapabilitiesMessage upd_cap; struct data_message data; struct extended_data_message extended_data; @@ -719,47 +936,6 @@ struct PACKED skinny_message { typedef struct skinny_message skinny_message_t; -/*****************************************************************************/ -/* SKINNY TYPES */ -/*****************************************************************************/ -enum skinny_codecs { - 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_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_T120 = 105, - SKINNY_CODEC_H224 = 106, - SKINNY_CODEC_RFC2833_DYNPAYLOAD = 257 -}; - -char* skinny_codec2string(enum skinny_codecs skinnycodec); /*****************************************************************************/ /* SKINNY FUNCTIONS */ @@ -819,6 +995,7 @@ switch_status_t send_set_lamp(listener_t *listener, uint32_t mode); switch_status_t send_set_speaker_mode(listener_t *listener, uint32_t mode); +switch_status_t send_srvreq_response(listener_t *listener, char *ip, uint32_t port); switch_status_t send_start_media_transmission(listener_t *listener, uint32_t conference_id, uint32_t pass_thru_party_id, diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 8e47691..5e2667a 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1613,6 +1613,66 @@ switch_status_t skinny_handle_capabilities_response(listener_t *listener, skinny 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_alarm(listener_t *listener, skinny_message_t *request) { switch_event_t *event = NULL; @@ -2060,6 +2120,36 @@ switch_status_t skinny_handle_accessory_status_message(listener_t *listener, ski 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; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Sent back to device - %s:%u\n", profile->ip, profile->port); +/** + if (!s->ourip.s_addr) { + pbx_log(LOG_ERROR, "%s: Session IP Changed mid flight\n", DEV_ID_LOG(d)); + return; + } + + if (s->device->session != s) { + pbx_log(LOG_ERROR, "%s: Wrong Session or Session Changed mid flight\n", DEV_ID_LOG(d)); + return; + } +**/ + /* old protocol function replaced by the SEP file server addesses list */ + //sccp_log(DEBUGCAT_CORE) (VERBOSE_PREFIX_3 "%s: Sending servers message\n", DEV_ID_LOG(d)); + + 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; @@ -2080,6 +2170,9 @@ switch_status_t skinny_handle_xml_alarm(listener_t *listener, skinny_message_t * return SWITCH_STATUS_SUCCESS; } + + + switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request) { if (listener->profile->debug >= 10 || request->type != KEEP_ALIVE_MESSAGE) { @@ -2087,7 +2180,7 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re "Received %s (type=%x,length=%d) from %s:%d.\n", skinny_message_type2str(request->type), request->type, request->length, listener->device_name, listener->device_instance); } - 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; @@ -2159,6 +2252,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); diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index f5ce877..ccede06 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -51,6 +51,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {BUTTON_TEMPLATE_REQ_MESSAGE, "ButtonTemplateReqMessage"}, {VERSION_REQ_MESSAGE, "VersionReqMessage"}, {CAPABILITIES_RES_MESSAGE, "CapabilitiesReqMessage"}, + {SERVER_REQ_MESSAGE, "Server Request Message"}, {ALARM_MESSAGE, "AlarmMessage"}, {OPEN_RECEIVE_CHANNEL_ACK_MESSAGE, "OpenReceiveChannelAckMessage"}, {SOFT_KEY_SET_REQ_MESSAGE, "SoftKeySetReqMessage"}, @@ -61,6 +62,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {REGISTER_AVAILABLE_LINES_MESSAGE, "RegisterAvailableLinesMessage"}, {DEVICE_TO_USER_DATA_MESSAGE, "DeviceToUserDataMessage"}, {DEVICE_TO_USER_DATA_RESPONSE_MESSAGE, "DeviceToUserDataResponseMessage"}, + {DEVICE_UPDATECAPABILITIES, "DeviceUpdateCapabilities"}, {SERVICE_URL_STAT_REQ_MESSAGE, "ServiceUrlStatReqMessage"}, {FEATURE_STAT_REQ_MESSAGE, "FeatureStatReqMessage"}, {DEVICE_TO_USER_DATA_VERSION1_MESSAGE, "DeviceToUserDataVersion1Message"}, @@ -85,6 +87,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {VERSION_MESSAGE, "VersionMessage"}, {CAPABILITIES_REQ_MESSAGE, "CapabilitiesReqMessage"}, {REGISTER_REJECT_MESSAGE, "RegisterRejectMessage"}, + {SERVER_RESPONSE_MESSAGE, "ServerResponseMessage"}, {RESET_MESSAGE, "ResetMessage"}, {KEEP_ALIVE_ACK_MESSAGE, "KeepAliveAckMessage"}, {OPEN_RECEIVE_CHANNEL_MESSAGE, "OpenReceiveChannelMessage"}, @@ -122,6 +125,7 @@ SKINNY_DECLARE_STR2ID(skinny_str2message_type, SKINNY_MESSAGE_TYPES, -1) {8, "Cisco IP Phone 7940"}, {9, "Cisco IP Phone 7935"}, {12, "Cisco ATA 186"}, + {302, "Cisco IP Phone 7985"}, {365, "Cisco IP Phone CP-7921G"}, {404, "Cisco IP Phone CP-7962G"}, {436, "Cisco IP Phone CP-7965G"}, diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index 502c0b5..3c24993 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -87,12 +87,12 @@ if (my_matches) {\ } -extern struct skinny_table SKINNY_MESSAGE_TYPES[72]; +extern struct skinny_table SKINNY_MESSAGE_TYPES[75]; const char *skinny_message_type2str(uint32_t id); uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) -extern struct skinny_table SKINNY_DEVICE_TYPES[16]; +extern struct skinny_table SKINNY_DEVICE_TYPES[17]; const char *skinny_device_type2str(uint32_t id); uint32_t skinny_str2device_type(const char *str); #define SKINNY_PUSH_DEVICE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_DEVICE_TYPES)