提交 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 @@
#define SKINNY_EVENT_UNREGISTER "skinny::unregister"
#define SKINNY_EVENT_EXPIRE "skinny::expire"
#define SKINNY_EVENT_ALARM "skinny::alarm"
#define SKINNY_EVENT_CALL_STATE "skinny::call_state"
struct skinny_globals {
/* data */
......@@ -49,6 +50,7 @@ struct skinny_globals {
switch_mutex_t *calls_mutex;
switch_hash_t *profile_hash;
switch_event_node_t *heartbeat_node;
switch_event_node_t *call_state_node;
int running;
};
typedef struct skinny_globals skinny_globals_t;
......@@ -72,6 +74,7 @@ struct skinny_profile {
char *odbc_user;
char *odbc_pass;
switch_odbc_handle_t *master_odbc;
switch_mutex_t *sql_mutex;
/* stats */
uint32_t ib_calls;
uint32_t ob_calls;
......@@ -103,8 +106,6 @@ struct listener {
skinny_profile_t *profile;
char device_name[16];
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_memory_pool_t *pool;
......@@ -153,14 +154,11 @@ struct private_object {
switch_mutex_t *mutex;
switch_mutex_t *flag_mutex;
/* identification */
struct listener *listener;
uint32_t line;
uint32_t call_id;
uint32_t party_id;
char *line_name;
char *line_shortname;
char *line_displayname;
char dest[10];
skinny_profile_t *profile;
/* codec */
char *iananame;
switch_codec_t read_codec;
......@@ -182,6 +180,13 @@ struct private_object {
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 */
/*****************************************************************************/
......@@ -197,13 +202,13 @@ switch_status_t keepalive_listener(listener_t *listener, void *pvt);
/*****************************************************************************/
/* 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);
#define skinny_line_set_state(listener, instance, state, call_id) skinny_line_perform_set_state(listener, __FILE__, __SWITCH_FUNC__, __LINE__, instance, state, 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, 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);
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_hangup(switch_core_session_t *session);
switch_status_t channel_on_destroy(switch_core_session_t *session);
......
......@@ -59,6 +59,9 @@ struct register_message {
/* PortMessage */
#define PORT_MESSAGE 0x0002
struct port_message {
uint16_t port;
};
/* KeypadButtonMessage */
#define KEYPAD_BUTTON_MESSAGE 0x0003
......@@ -73,14 +76,14 @@ struct keypad_button_message {
struct stimulus_message {
uint32_t instance_type; /* See enum skinny_button_definition */
uint32_t instance;
/* uint32_t call_reference; */
uint32_t call_id;
};
/* OffHookMessage */
#define OFF_HOOK_MESSAGE 0x0006
struct off_hook_message {
uint32_t line_instance;
/* uint32_t call_id; */
uint32_t call_id;
};
/* OnHookMessage */
......@@ -150,7 +153,7 @@ struct open_receive_channel_ack_message {
struct soft_key_event_message {
uint32_t event;
uint32_t line_instance;
uint32_t callreference;
uint32_t call_id;
};
/* UnregisterMessage */
......@@ -186,10 +189,10 @@ struct register_available_lines_message {
/* RegisterAckMessage */
#define REGISTER_ACK_MESSAGE 0x0081
struct register_ack_message {
uint32_t keepAlive;
char dateFormat[6];
uint32_t keep_alive;
char date_format[6];
char reserved[2];
uint32_t secondaryKeepAlive;
uint32_t secondary_keep_alive;
char reserved2[4];
};
......@@ -214,7 +217,8 @@ struct stop_tone_message {
struct set_ringer_message {
uint32_t ring_type; /* See enum skinny_ring_type */
uint32_t ring_mode; /* See enum skinny_ring_mode */
uint32_t unknown; /* ?? */
uint32_t line_instance;
uint32_t call_id;
};
/* SetLampMessage */
......@@ -470,6 +474,14 @@ struct feature_stat_res_message {
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 */
#define SERVICE_URL_STAT_RES_MESSAGE 0x012F
struct service_url_stat_res_message {
......@@ -487,6 +499,7 @@ struct service_url_stat_res_message {
union skinny_data {
struct register_message reg;
struct port_message port;
struct keypad_button_message keypad_button;
struct stimulus_message stimulus;
struct off_hook_message off_hook;
......@@ -529,6 +542,7 @@ union skinny_data {
struct unregister_ack_message unregister_ack;
struct dialed_number_message dialed_number;
struct feature_stat_res_message feature_res;
struct display_pri_notify_message display_pri_notify;
struct service_url_stat_res_message service_url_res;
uint16_t as_uint16;
......@@ -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);\
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_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_process_dest(listener_t *listener, uint32_t line);
switch_status_t skinny_answer(switch_core_session_t *session);
switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *line_instance, switch_core_session_t **session);
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_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_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,
switch_status_t set_ringer(listener_t *listener,
uint32_t ring_type,
uint32_t ring_mode,
uint32_t unknown);
uint32_t line_instance,
uint32_t call_id);
switch_status_t set_lamp(listener_t *listener,
uint32_t stimulus,
uint32_t stimulus_instance,
......@@ -710,6 +733,10 @@ switch_status_t send_dialed_number(listener_t *listener,
char called_party[24],
uint32_t line_instance,
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,
uint32_t reset_type);
......
......@@ -77,7 +77,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
{"ResetMessage", RESET_MESSAGE},
{"KeepAliveAckMessage", KEEP_ALIVE_ACK_MESSAGE},
{"OpenReceiveChannelMessage", OPEN_RECEIVE_CHANNEL_MESSAGE},
{"OCloseReceiveChannelMessage", CLOSE_RECEIVE_CHANNEL_MESSAGE},
{"CloseReceiveChannelMessage", CLOSE_RECEIVE_CHANNEL_MESSAGE},
{"SoftKeyTemplateResMessage", SOFT_KEY_TEMPLATE_RES_MESSAGE},
{"SoftKeySetResMessage", SOFT_KEY_SET_RES_MESSAGE},
{"SelectSoftKeysMessage", SELECT_SOFT_KEYS_MESSAGE},
......@@ -88,6 +88,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
{"UnregisterAckMessage", UNREGISTER_ACK_MESSAGE},
{"DialedNumberMessage", DIALED_NUMBER_MESSAGE},
{"FeatureResMessage", FEATURE_STAT_RES_MESSAGE},
{"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE},
{"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE},
{NULL, 0}
};
......@@ -168,13 +169,13 @@ struct skinny_table SKINNY_CALL_STATES[] = {
{"RingIn", SKINNY_RING_IN},
{"Connected", SKINNY_CONNECTED},
{"Busy", SKINNY_BUSY},
{"Congestion", SKINNY_CONGESTION},
{"LineInUse", SKINNY_LINE_IN_USE},
{"Hold", SKINNY_HOLD},
{"CallWaiting", SKINNY_CALL_WAITING},
{"CallTransfer", SKINNY_CALL_TRANSFER},
{"CallPark", SKINNY_CALL_PARK},
{"Proceed", SKINNY_PROCEED},
{"CallRemoteMultiline", SKINNY_CALL_REMOTE_MULTILINE},
{"InUseRemotely", SKINNY_IN_USE_REMOTELY},
{"InvalidNumber", SKINNY_INVALID_NUMBER},
{NULL, 0}
};
......
......@@ -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);
uint32_t skinny_str2message_type(const char *str);
#define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES)
......@@ -210,13 +210,13 @@ enum skinny_call_state {
SKINNY_RING_IN = 4,
SKINNY_CONNECTED = 5,
SKINNY_BUSY = 6,
SKINNY_CONGESTION = 7,
SKINNY_LINE_IN_USE = 7,
SKINNY_HOLD = 8,
SKINNY_CALL_WAITING = 9,
SKINNY_CALL_TRANSFER = 10,
SKINNY_CALL_PARK = 11,
SKINNY_PROCEED = 12,
SKINNY_CALL_REMOTE_MULTILINE = 13,
SKINNY_IN_USE_REMOTELY = 13,
SKINNY_INVALID_NUMBER = 14
};
struct skinny_table SKINNY_CALL_STATES[15];
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论