diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index eb7e45ebc0..8cd893284c 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -136,6 +136,9 @@ struct listener { char device_name[16]; uint32_t device_instance; uint32_t device_type; + uint32_t headset; + uint32_t handset; + uint32_t speaker; char firmware_version[16]; char *soft_key_set_set; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index eff0091c07..1eed692157 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -178,7 +178,7 @@ struct PACKED soft_key_event_message { /* HeadsetStatusMessage */ #define HEADSET_STATUS_MESSAGE 0x002B struct PACKED headset_status_message { - uint32_t mode; + uint32_t mode; /* 1=HeadsetOn; 2=HeadsetOff */ }; /* RegisterAvailableLinesMessage */ @@ -243,6 +243,14 @@ struct PACKED dialed_phone_book_message { char phone_number[256]; }; +/* AccessoryStatusMessage */ +#define ACCESSORY_STATUS_MESSAGE 0x0049 +struct PACKED accessory_status_message { + uint32_t accessory_id; + uint32_t accessory_status; + uint32_t unknown; +}; + /* RegisterAckMessage */ #define REGISTER_ACK_MESSAGE 0x0081 struct PACKED register_ack_message { @@ -633,6 +641,7 @@ union skinny_data { /* see field "extended_data" for DEVICE_TO_USER_DATA_VERSION1_MESSAGE */ /* see field "extended_data" for DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE */ struct dialed_phone_book_message dialed_phone_book; + struct accessory_status_message accessory_status; struct register_ack_message reg_ack; struct start_tone_message start_tone; struct stop_tone_message stop_tone; diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 12c83b846a..efe02a9811 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1902,7 +1902,14 @@ switch_status_t skinny_headset_status_message(listener_t *listener, skinny_messa { skinny_check_data_length(request, sizeof(request->data.headset_status)); - /* Nothing to do */ + switch(request->data.headset_status.mode) { + case 1: + listener->headset = SKINNY_ACCESSORY_STATE_OFFHOOK; + break; + default: + listener->headset = SKINNY_ACCESSORY_STATE_ONHOOK; + break; + } return SWITCH_STATUS_SUCCESS; } @@ -2028,6 +2035,24 @@ switch_status_t skinny_handle_dialed_phone_book_message(listener_t *listener, sk return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_accessory_status_message(listener_t *listener, skinny_message_t *request) +{ + skinny_check_data_length(request, sizeof(request->data.accessory_status)); + + switch(request->data.accessory_status.accessory_id) { + case SKINNY_ACCESSORY_HEADSET: + listener->headset = request->data.accessory_status.accessory_status; + break; + case SKINNY_ACCESSORY_HANDSET: + listener->handset = request->data.accessory_status.accessory_status; + break; + case SKINNY_ACCESSORY_SPEAKER: + listener->speaker = request->data.accessory_status.accessory_status; + break; + } + + return SWITCH_STATUS_SUCCESS; +} switch_status_t skinny_handle_xml_alarm(listener_t *listener, skinny_message_t *request) { @@ -2124,6 +2149,8 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_handle_extended_data_message(listener, request); case DIALED_PHONE_BOOK_MESSAGE: return skinny_handle_dialed_phone_book_message(listener, request); + case ACCESSORY_STATUS_MESSAGE: + return skinny_handle_accessory_status_message(listener, request); case XML_ALARM_MESSAGE: return skinny_handle_xml_alarm(listener, request); default: diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index 5a627dba0b..59bb4a1f2f 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -66,6 +66,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {DEVICE_TO_USER_DATA_VERSION1_MESSAGE, "DeviceToUserDataVersion1Message"}, {DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE, "DeviceToUserDataResponseVersion1Message"}, {DIALED_PHONE_BOOK_MESSAGE, "DialedPhoneBookMessage"}, + {ACCESSORY_STATUS_MESSAGE, "AccessoryStatusMessage"}, {REGISTER_ACK_MESSAGE, "RegisterAckMessage"}, {START_TONE_MESSAGE, "StartToneMessage"}, {STOP_TONE_MESSAGE, "StopToneMessage"}, @@ -255,6 +256,25 @@ struct skinny_table SKINNY_DEVICE_RESET_TYPES[] = { SKINNY_DECLARE_ID2STR(skinny_device_reset_type2str, SKINNY_DEVICE_RESET_TYPES, "DeviceResetTypeUnknown") SKINNY_DECLARE_STR2ID(skinny_str2device_reset_type, SKINNY_DEVICE_RESET_TYPES, -1) +struct skinny_table SKINNY_ACCESSORY_TYPES[] = { + {SKINNY_ACCESSORY_NONE, "AccessoryNone"}, + {SKINNY_ACCESSORY_HEADSET, "Headset"}, + {SKINNY_ACCESSORY_HANDSET, "Handset"}, + {SKINNY_ACCESSORY_SPEAKER, "Speaker"}, + {0, NULL} +}; +SKINNY_DECLARE_ID2STR(skinny_accessory_type2str, SKINNY_ACCESSORY_TYPES, "AccessoryUnknown") +SKINNY_DECLARE_STR2ID(skinny_str2accessory_type, SKINNY_ACCESSORY_TYPES, -1) + +struct skinny_table SKINNY_ACCESSORY_STATES[] = { + {SKINNY_ACCESSORY_STATE_NONE, "AccessoryNoState"}, + {SKINNY_ACCESSORY_STATE_OFFHOOK, "OffHook"}, + {SKINNY_ACCESSORY_STATE_ONHOOK, "OnHook"}, + {0, NULL} +}; +SKINNY_DECLARE_ID2STR(skinny_accessory_state2str, SKINNY_ACCESSORY_STATES, "AccessoryStateUnknown") +SKINNY_DECLARE_STR2ID(skinny_str2accessory_state, SKINNY_ACCESSORY_STATES, -1) + /* For Emacs: * Local Variables: * mode:c diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index 0e0c9b1b5b..383e5bb2b1 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -87,7 +87,7 @@ uint32_t func(const char *str)\ } -extern struct skinny_table SKINNY_MESSAGE_TYPES[71]; +extern struct skinny_table SKINNY_MESSAGE_TYPES[72]; 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) @@ -248,6 +248,27 @@ const char *skinny_device_reset_type2str(uint32_t id); uint32_t skinny_str2device_reset_type(const char *str); #define SKINNY_PUSH_DEVICE_RESET_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_DEVICE_RESET_TYPES) +enum skinny_accessory_types { + SKINNY_ACCESSORY_NONE = 0x00, + SKINNY_ACCESSORY_HEADSET = 0x01, + SKINNY_ACCESSORY_HANDSET = 0x02, + SKINNY_ACCESSORY_SPEAKER = 0x03 +}; +extern struct skinny_table SKINNY_ACCESSORY_TYPES[5]; +const char *skinny_accessory_type2str(uint32_t id); +uint32_t skinny_str2accessory_type(const char *str); +#define SKINNY_PUSH_ACCESSORY_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_ACCESSORY_TYPES) + +enum skinny_accessory_states { + SKINNY_ACCESSORY_STATE_NONE = 0x00, + SKINNY_ACCESSORY_STATE_OFFHOOK = 0x01, + SKINNY_ACCESSORY_STATE_ONHOOK = 0x02 +}; +extern struct skinny_table SKINNY_ACCESSORY_STATES[4]; +const char *skinny_accessory_state2str(uint32_t id); +uint32_t skinny_str2accessory_state(const char *str); +#define SKINNY_PUSH_ACCESSORY_STATES SKINNY_DECLARE_PUSH_MATCH(SKINNY_ACCESSORY_STATES) + #endif /* _SKINNY_TABLES_H */ /* For Emacs: