提交 b8ac781c authored 作者: Mathieu Parent's avatar Mathieu Parent

Skinny: Implement shared lines and more

- Shared lines (same line on several phones)
  + Active lines stored in db
- Separate SQL mutex per profile
- New event skinny::call_state
- Clean port_message
- More protocol understanding:
  + stimulus may have call_id
  + off_hook may have call_id
  + set_ringer may have call_id and line_instance
  + New DisplayPriNotifyMessage
- Use Cisco terms for Call state
  + Congestion -> LineInUse
  + CallRemoteMultiline -> InUseRemotely
- Add line_instance to Lines table (relative position contrary to
  absolute position)
- Less assertions as FS already does some
上级 0bdc1568
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#define SKINNY_EVENT_UNREGISTER "skinny::unregister" #define SKINNY_EVENT_UNREGISTER "skinny::unregister"
#define SKINNY_EVENT_EXPIRE "skinny::expire" #define SKINNY_EVENT_EXPIRE "skinny::expire"
#define SKINNY_EVENT_ALARM "skinny::alarm" #define SKINNY_EVENT_ALARM "skinny::alarm"
#define SKINNY_EVENT_CALL_STATE "skinny::call_state"
struct skinny_globals { struct skinny_globals {
/* data */ /* data */
...@@ -49,6 +50,7 @@ struct skinny_globals { ...@@ -49,6 +50,7 @@ struct skinny_globals {
switch_mutex_t *calls_mutex; switch_mutex_t *calls_mutex;
switch_hash_t *profile_hash; switch_hash_t *profile_hash;
switch_event_node_t *heartbeat_node; switch_event_node_t *heartbeat_node;
switch_event_node_t *call_state_node;
int running; int running;
}; };
typedef struct skinny_globals skinny_globals_t; typedef struct skinny_globals skinny_globals_t;
...@@ -72,6 +74,7 @@ struct skinny_profile { ...@@ -72,6 +74,7 @@ struct skinny_profile {
char *odbc_user; char *odbc_user;
char *odbc_pass; char *odbc_pass;
switch_odbc_handle_t *master_odbc; switch_odbc_handle_t *master_odbc;
switch_mutex_t *sql_mutex;
/* stats */ /* stats */
uint32_t ib_calls; uint32_t ib_calls;
uint32_t ob_calls; uint32_t ob_calls;
...@@ -103,8 +106,6 @@ struct listener { ...@@ -103,8 +106,6 @@ struct listener {
skinny_profile_t *profile; skinny_profile_t *profile;
char device_name[16]; char device_name[16];
uint32_t device_instance; uint32_t device_instance;
switch_core_session_t *session[SKINNY_MAX_LINES];
uint32_t line_state[SKINNY_MAX_LINES]; /* See enum skinny_key_set */
switch_socket_t *sock; switch_socket_t *sock;
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
...@@ -153,14 +154,11 @@ struct private_object { ...@@ -153,14 +154,11 @@ struct private_object {
switch_mutex_t *mutex; switch_mutex_t *mutex;
switch_mutex_t *flag_mutex; switch_mutex_t *flag_mutex;
/* identification */ /* identification */
struct listener *listener;
uint32_t line;
uint32_t call_id; uint32_t call_id;
uint32_t party_id; uint32_t party_id;
char *line_name;
char *line_shortname; skinny_profile_t *profile;
char *line_displayname;
char dest[10];
/* codec */ /* codec */
char *iananame; char *iananame;
switch_codec_t read_codec; switch_codec_t read_codec;
...@@ -182,6 +180,13 @@ struct private_object { ...@@ -182,6 +180,13 @@ struct private_object {
typedef struct private_object private_t; typedef struct private_object private_t;
/*****************************************************************************/
/* PROFILES FUNCTIONS */
/*****************************************************************************/
switch_status_t skinny_profile_find_listener_by_device_name_and_instance(skinny_profile_t *profile, const char *device_name, uint32_t device_instance, listener_t **listener);
char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id);
switch_core_session_t * skinny_profile_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id);
/*****************************************************************************/ /*****************************************************************************/
/* SQL FUNCTIONS */ /* SQL FUNCTIONS */
/*****************************************************************************/ /*****************************************************************************/
...@@ -197,13 +202,13 @@ switch_status_t keepalive_listener(listener_t *listener, void *pvt); ...@@ -197,13 +202,13 @@ switch_status_t keepalive_listener(listener_t *listener, void *pvt);
/*****************************************************************************/ /*****************************************************************************/
/* CHANNEL FUNCTIONS */ /* CHANNEL FUNCTIONS */
/*****************************************************************************/ /*****************************************************************************/
uint32_t skinny_line_perform_set_state(listener_t *listener, const char *file, const char *func, int line, uint32_t instance, uint32_t state, uint32_t call_id); void skinny_line_perform_set_state(const char *file, const char *func, int line, listener_t *listener, uint32_t line_instance, uint32_t call_id, uint32_t call_state);
#define skinny_line_set_state(listener, instance, state, call_id) skinny_line_perform_set_state(listener, __FILE__, __SWITCH_FUNC__, __LINE__, instance, state, call_id) #define skinny_line_set_state(listener, line_instance, call_id, call_state) skinny_line_perform_set_state(__FILE__, __SWITCH_FUNC__, __LINE__, listener, line_instance, call_id, call_state)
uint32_t skinny_line_get_state(listener_t *listener, uint32_t instance); uint32_t skinny_line_get_state(listener_t *listener, uint32_t line_instance, uint32_t call_id);
switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force); switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force);
void tech_init(private_t *tech_pvt, switch_core_session_t *session, listener_t *listener, uint32_t line); void tech_init(private_t *tech_pvt, skinny_profile_t *profile, switch_core_session_t *session);
switch_status_t channel_on_init(switch_core_session_t *session); switch_status_t channel_on_init(switch_core_session_t *session);
switch_status_t channel_on_hangup(switch_core_session_t *session); switch_status_t channel_on_hangup(switch_core_session_t *session);
switch_status_t channel_on_destroy(switch_core_session_t *session); switch_status_t channel_on_destroy(switch_core_session_t *session);
......
...@@ -59,6 +59,9 @@ struct register_message { ...@@ -59,6 +59,9 @@ struct register_message {
/* PortMessage */ /* PortMessage */
#define PORT_MESSAGE 0x0002 #define PORT_MESSAGE 0x0002
struct port_message {
uint16_t port;
};
/* KeypadButtonMessage */ /* KeypadButtonMessage */
#define KEYPAD_BUTTON_MESSAGE 0x0003 #define KEYPAD_BUTTON_MESSAGE 0x0003
...@@ -73,14 +76,14 @@ struct keypad_button_message { ...@@ -73,14 +76,14 @@ struct keypad_button_message {
struct stimulus_message { struct stimulus_message {
uint32_t instance_type; /* See enum skinny_button_definition */ uint32_t instance_type; /* See enum skinny_button_definition */
uint32_t instance; uint32_t instance;
/* uint32_t call_reference; */ uint32_t call_id;
}; };
/* OffHookMessage */ /* OffHookMessage */
#define OFF_HOOK_MESSAGE 0x0006 #define OFF_HOOK_MESSAGE 0x0006
struct off_hook_message { struct off_hook_message {
uint32_t line_instance; uint32_t line_instance;
/* uint32_t call_id; */ uint32_t call_id;
}; };
/* OnHookMessage */ /* OnHookMessage */
...@@ -150,7 +153,7 @@ struct open_receive_channel_ack_message { ...@@ -150,7 +153,7 @@ struct open_receive_channel_ack_message {
struct soft_key_event_message { struct soft_key_event_message {
uint32_t event; uint32_t event;
uint32_t line_instance; uint32_t line_instance;
uint32_t callreference; uint32_t call_id;
}; };
/* UnregisterMessage */ /* UnregisterMessage */
...@@ -186,10 +189,10 @@ struct register_available_lines_message { ...@@ -186,10 +189,10 @@ struct register_available_lines_message {
/* RegisterAckMessage */ /* RegisterAckMessage */
#define REGISTER_ACK_MESSAGE 0x0081 #define REGISTER_ACK_MESSAGE 0x0081
struct register_ack_message { struct register_ack_message {
uint32_t keepAlive; uint32_t keep_alive;
char dateFormat[6]; char date_format[6];
char reserved[2]; char reserved[2];
uint32_t secondaryKeepAlive; uint32_t secondary_keep_alive;
char reserved2[4]; char reserved2[4];
}; };
...@@ -214,7 +217,8 @@ struct stop_tone_message { ...@@ -214,7 +217,8 @@ struct stop_tone_message {
struct set_ringer_message { struct set_ringer_message {
uint32_t ring_type; /* See enum skinny_ring_type */ uint32_t ring_type; /* See enum skinny_ring_type */
uint32_t ring_mode; /* See enum skinny_ring_mode */ uint32_t ring_mode; /* See enum skinny_ring_mode */
uint32_t unknown; /* ?? */ uint32_t line_instance;
uint32_t call_id;
}; };
/* SetLampMessage */ /* SetLampMessage */
...@@ -470,6 +474,14 @@ struct feature_stat_res_message { ...@@ -470,6 +474,14 @@ struct feature_stat_res_message {
uint32_t status; uint32_t status;
}; };
/* DisplayPriNotifyMessage */
#define DISPLAY_PRI_NOTIFY_MESSAGE 0x0120
struct display_pri_notify_message {
uint32_t message_timeout;
uint32_t priority;
char notify[32];
};
/* ServiceUrlStatMessage */ /* ServiceUrlStatMessage */
#define SERVICE_URL_STAT_RES_MESSAGE 0x012F #define SERVICE_URL_STAT_RES_MESSAGE 0x012F
struct service_url_stat_res_message { struct service_url_stat_res_message {
...@@ -487,6 +499,7 @@ struct service_url_stat_res_message { ...@@ -487,6 +499,7 @@ struct service_url_stat_res_message {
union skinny_data { union skinny_data {
struct register_message reg; struct register_message reg;
struct port_message port;
struct keypad_button_message keypad_button; struct keypad_button_message keypad_button;
struct stimulus_message stimulus; struct stimulus_message stimulus;
struct off_hook_message off_hook; struct off_hook_message off_hook;
...@@ -529,6 +542,7 @@ union skinny_data { ...@@ -529,6 +542,7 @@ union skinny_data {
struct unregister_ack_message unregister_ack; struct unregister_ack_message unregister_ack;
struct dialed_number_message dialed_number; struct dialed_number_message dialed_number;
struct feature_stat_res_message feature_res; struct feature_stat_res_message feature_res;
struct display_pri_notify_message display_pri_notify;
struct service_url_stat_res_message service_url_res; struct service_url_stat_res_message service_url_res;
uint16_t as_uint16; uint16_t as_uint16;
...@@ -598,16 +612,24 @@ typedef switch_status_t (*skinny_command_t) (char **argv, int argc, switch_strea ...@@ -598,16 +612,24 @@ typedef switch_status_t (*skinny_command_t) (char **argv, int argc, switch_strea
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received Too Short Skinny Message (Expected %" SWITCH_SIZE_T_FMT ", got %d).\n", len+4, message->length);\ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received Too Short Skinny Message (Expected %" SWITCH_SIZE_T_FMT ", got %d).\n", len+4, message->length);\
return SWITCH_STATUS_FALSE;\ return SWITCH_STATUS_FALSE;\
} }
#define skinny_check_data_length_soft(message, len) \
(message->length >= len+4)
switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req); switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req);
switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, switch_event_types_t event_id, const char *subclass_name); switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, switch_event_types_t event_id, const char *subclass_name);
switch_status_t skinny_send_call_info(switch_core_session_t *session); switch_status_t skinny_send_call_info(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
switch_status_t skinny_session_walk_lines(skinny_profile_t *profile, char *channel_uuid, switch_core_db_callback_func_t callback, void *data);
switch_call_cause_t skinny_ring_lines(private_t *tech_pvt);
switch_status_t skinny_create_session(listener_t *listener, uint32_t line, uint32_t to_state); switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *line_instance, switch_core_session_t **session);
switch_status_t skinny_process_dest(listener_t *listener, uint32_t line); switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace);
switch_status_t skinny_answer(switch_core_session_t *session); switch_status_t skinny_session_ring_out(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
switch_status_t skinny_session_answer(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
switch_status_t skinny_session_start_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
switch_status_t skinny_session_hold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
switch_status_t skinny_session_unhold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
void skinny_line_get(listener_t *listener, uint32_t instance, struct line_stat_res_message **button); void skinny_line_get(listener_t *listener, uint32_t instance, struct line_stat_res_message **button);
void skinny_speed_dial_get(listener_t *listener, uint32_t instance, struct speed_dial_stat_res_message **button); void skinny_speed_dial_get(listener_t *listener, uint32_t instance, struct speed_dial_stat_res_message **button);
...@@ -631,7 +653,8 @@ switch_status_t stop_tone(listener_t *listener, ...@@ -631,7 +653,8 @@ switch_status_t stop_tone(listener_t *listener,
switch_status_t set_ringer(listener_t *listener, switch_status_t set_ringer(listener_t *listener,
uint32_t ring_type, uint32_t ring_type,
uint32_t ring_mode, uint32_t ring_mode,
uint32_t unknown); uint32_t line_instance,
uint32_t call_id);
switch_status_t set_lamp(listener_t *listener, switch_status_t set_lamp(listener_t *listener,
uint32_t stimulus, uint32_t stimulus,
uint32_t stimulus_instance, uint32_t stimulus_instance,
...@@ -710,6 +733,10 @@ switch_status_t send_dialed_number(listener_t *listener, ...@@ -710,6 +733,10 @@ switch_status_t send_dialed_number(listener_t *listener,
char called_party[24], char called_party[24],
uint32_t line_instance, uint32_t line_instance,
uint32_t call_id); uint32_t call_id);
switch_status_t send_display_pri_notify(listener_t *listener,
uint32_t message_timeout,
uint32_t priority,
char *notify);
switch_status_t send_reset(listener_t *listener, switch_status_t send_reset(listener_t *listener,
uint32_t reset_type); uint32_t reset_type);
......
...@@ -77,7 +77,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { ...@@ -77,7 +77,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
{"ResetMessage", RESET_MESSAGE}, {"ResetMessage", RESET_MESSAGE},
{"KeepAliveAckMessage", KEEP_ALIVE_ACK_MESSAGE}, {"KeepAliveAckMessage", KEEP_ALIVE_ACK_MESSAGE},
{"OpenReceiveChannelMessage", OPEN_RECEIVE_CHANNEL_MESSAGE}, {"OpenReceiveChannelMessage", OPEN_RECEIVE_CHANNEL_MESSAGE},
{"OCloseReceiveChannelMessage", CLOSE_RECEIVE_CHANNEL_MESSAGE}, {"CloseReceiveChannelMessage", CLOSE_RECEIVE_CHANNEL_MESSAGE},
{"SoftKeyTemplateResMessage", SOFT_KEY_TEMPLATE_RES_MESSAGE}, {"SoftKeyTemplateResMessage", SOFT_KEY_TEMPLATE_RES_MESSAGE},
{"SoftKeySetResMessage", SOFT_KEY_SET_RES_MESSAGE}, {"SoftKeySetResMessage", SOFT_KEY_SET_RES_MESSAGE},
{"SelectSoftKeysMessage", SELECT_SOFT_KEYS_MESSAGE}, {"SelectSoftKeysMessage", SELECT_SOFT_KEYS_MESSAGE},
...@@ -88,6 +88,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { ...@@ -88,6 +88,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
{"UnregisterAckMessage", UNREGISTER_ACK_MESSAGE}, {"UnregisterAckMessage", UNREGISTER_ACK_MESSAGE},
{"DialedNumberMessage", DIALED_NUMBER_MESSAGE}, {"DialedNumberMessage", DIALED_NUMBER_MESSAGE},
{"FeatureResMessage", FEATURE_STAT_RES_MESSAGE}, {"FeatureResMessage", FEATURE_STAT_RES_MESSAGE},
{"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE},
{"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE}, {"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE},
{NULL, 0} {NULL, 0}
}; };
...@@ -168,13 +169,13 @@ struct skinny_table SKINNY_CALL_STATES[] = { ...@@ -168,13 +169,13 @@ struct skinny_table SKINNY_CALL_STATES[] = {
{"RingIn", SKINNY_RING_IN}, {"RingIn", SKINNY_RING_IN},
{"Connected", SKINNY_CONNECTED}, {"Connected", SKINNY_CONNECTED},
{"Busy", SKINNY_BUSY}, {"Busy", SKINNY_BUSY},
{"Congestion", SKINNY_CONGESTION}, {"LineInUse", SKINNY_LINE_IN_USE},
{"Hold", SKINNY_HOLD}, {"Hold", SKINNY_HOLD},
{"CallWaiting", SKINNY_CALL_WAITING}, {"CallWaiting", SKINNY_CALL_WAITING},
{"CallTransfer", SKINNY_CALL_TRANSFER}, {"CallTransfer", SKINNY_CALL_TRANSFER},
{"CallPark", SKINNY_CALL_PARK}, {"CallPark", SKINNY_CALL_PARK},
{"Proceed", SKINNY_PROCEED}, {"Proceed", SKINNY_PROCEED},
{"CallRemoteMultiline", SKINNY_CALL_REMOTE_MULTILINE}, {"InUseRemotely", SKINNY_IN_USE_REMOTELY},
{"InvalidNumber", SKINNY_INVALID_NUMBER}, {"InvalidNumber", SKINNY_INVALID_NUMBER},
{NULL, 0} {NULL, 0}
}; };
......
...@@ -84,7 +84,7 @@ uint32_t func(const char *str)\ ...@@ -84,7 +84,7 @@ uint32_t func(const char *str)\
} }
struct skinny_table SKINNY_MESSAGE_TYPES[55]; struct skinny_table SKINNY_MESSAGE_TYPES[56];
const char *skinny_message_type2str(uint32_t id); const char *skinny_message_type2str(uint32_t id);
uint32_t skinny_str2message_type(const char *str); uint32_t skinny_str2message_type(const char *str);
#define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES)
...@@ -210,13 +210,13 @@ enum skinny_call_state { ...@@ -210,13 +210,13 @@ enum skinny_call_state {
SKINNY_RING_IN = 4, SKINNY_RING_IN = 4,
SKINNY_CONNECTED = 5, SKINNY_CONNECTED = 5,
SKINNY_BUSY = 6, SKINNY_BUSY = 6,
SKINNY_CONGESTION = 7, SKINNY_LINE_IN_USE = 7,
SKINNY_HOLD = 8, SKINNY_HOLD = 8,
SKINNY_CALL_WAITING = 9, SKINNY_CALL_WAITING = 9,
SKINNY_CALL_TRANSFER = 10, SKINNY_CALL_TRANSFER = 10,
SKINNY_CALL_PARK = 11, SKINNY_CALL_PARK = 11,
SKINNY_PROCEED = 12, SKINNY_PROCEED = 12,
SKINNY_CALL_REMOTE_MULTILINE = 13, SKINNY_IN_USE_REMOTELY = 13,
SKINNY_INVALID_NUMBER = 14 SKINNY_INVALID_NUMBER = 14
}; };
struct skinny_table SKINNY_CALL_STATES[15]; struct skinny_table SKINNY_CALL_STATES[15];
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论