mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-20 10:14:14 +00:00
Merge branch 'master' into smgmaster
This commit is contained in:
commit
5f7ab903bb
307 files changed
+16815
-2494
No files matched your search
@@ -52,7 +52,8 @@ typedef enum {
|
||||
TFLAG_BRIDGE = (1 << 4),
|
||||
TFLAG_BOWOUT = (1 << 5),
|
||||
TFLAG_BLEG = (1 << 6),
|
||||
TFLAG_APP = (1 << 7)
|
||||
TFLAG_APP = (1 << 7),
|
||||
TFLAG_BOWOUT_USED = (1 << 8)
|
||||
} TFLAGS;
|
||||
|
||||
struct private_object {
|
||||
@@ -635,7 +636,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
switch_assert(tech_pvt != NULL);
|
||||
|
||||
if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || switch_test_flag(tech_pvt, TFLAG_BOWOUT)) {
|
||||
if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -662,6 +663,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_WRITE);
|
||||
switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE);
|
||||
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_BOWOUT_USED);
|
||||
switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_BOWOUT_USED);
|
||||
|
||||
if (a_uuid && b_uuid) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
|
||||
"%s detected bridge on both ends, attempting direct connection.\n", switch_channel_get_name(channel));
|
||||
|
||||
@@ -1343,19 +1343,6 @@ static switch_status_t kill_listener(listener_t *listener, void *pvt)
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t kill_expired_listener(listener_t *listener, void *pvt)
|
||||
{
|
||||
switch_event_t *event = NULL;
|
||||
|
||||
if(listener->expire_time < switch_epoch_time_now(NULL)) {
|
||||
/* skinny::expire event */
|
||||
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_EXPIRE);
|
||||
switch_event_fire(&event);
|
||||
return kill_listener(listener, pvt);
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t keepalive_listener(listener_t *listener, void *pvt)
|
||||
{
|
||||
skinny_profile_t *profile;
|
||||
@@ -1414,6 +1401,13 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
|
||||
case SWITCH_STATUS_TIMEOUT:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Communication Time Out with %s:%d.\n",
|
||||
listener->remote_ip, listener->remote_port);
|
||||
|
||||
if(listener->expire_time < switch_epoch_time_now(NULL)) {
|
||||
switch_event_t *event = NULL;
|
||||
/* skinny::expire event */
|
||||
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_EXPIRE);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Communication Error with %s:%d.\n",
|
||||
@@ -1917,9 +1911,57 @@ static switch_status_t load_skinny_config(void)
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void skinny_heartbeat_event_handler(switch_event_t *event)
|
||||
static void skinny_user_to_device_event_handler(switch_event_t *event)
|
||||
{
|
||||
walk_listeners(kill_expired_listener, NULL);
|
||||
char *profile_name = switch_event_get_header_nil(event, "Skinny-Profile-Name");
|
||||
skinny_profile_t *profile;
|
||||
|
||||
if ((profile = skinny_find_profile(profile_name))) {
|
||||
char *device_name = switch_event_get_header_nil(event, "Skinny-Device-Name");
|
||||
uint32_t device_instance = atoi(switch_event_get_header_nil(event, "Skinny-Station-Instance"));
|
||||
listener_t *listener = NULL;
|
||||
skinny_profile_find_listener_by_device_name_and_instance(profile, device_name, device_instance, &listener);
|
||||
if(listener) {
|
||||
uint32_t message_type = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id"));
|
||||
uint32_t application_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Application-Id"));
|
||||
uint32_t line_instance = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Line-Instance"));
|
||||
uint32_t call_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Call-Id"));
|
||||
uint32_t transaction_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Transaction-Id"));
|
||||
uint32_t data_length = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Data-Length"));
|
||||
uint32_t sequence_flag = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Sequence-Flag"));
|
||||
uint32_t display_priority = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Display-Priority"));
|
||||
uint32_t conference_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Conference-Id"));
|
||||
uint32_t app_instance_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-App-Instance-Id"));
|
||||
uint32_t routing_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Routing-Id"));
|
||||
char *data = switch_event_get_body(event);
|
||||
if (message_type == 0) {
|
||||
message_type = skinny_str2message_type(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id-String"));
|
||||
}
|
||||
switch(message_type) {
|
||||
case USER_TO_DEVICE_DATA_MESSAGE:
|
||||
data_length = strlen(data); /* we ignore data_length sent */
|
||||
send_data(listener, message_type,
|
||||
application_id, line_instance, call_id, transaction_id, data_length,
|
||||
data);
|
||||
case USER_TO_DEVICE_DATA_VERSION1_MESSAGE:
|
||||
data_length = strlen(data); /* we ignore data_length sent */
|
||||
send_extended_data(listener, message_type,
|
||||
application_id, line_instance, call_id, transaction_id, data_length,
|
||||
sequence_flag, display_priority, conference_id, app_instance_id, routing_id,
|
||||
data);
|
||||
break;
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
||||
"Incorrect message type %s (%d).\n", skinny_message_type2str(message_type), message_type);
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
||||
"Device %s:%d in profile '%s' not found.\n", device_name, device_instance, profile_name);
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
||||
"Profile '%s' not found.\n", profile_name);
|
||||
}
|
||||
}
|
||||
|
||||
static void skinny_call_state_event_handler(switch_event_t *event)
|
||||
@@ -2129,10 +2171,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
/* bind to events */
|
||||
if ((switch_event_bind_removable(modname, SWITCH_EVENT_HEARTBEAT, NULL, skinny_heartbeat_event_handler, NULL, &globals.heartbeat_node) != SWITCH_STATUS_SUCCESS)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our heartbeat handler!\n");
|
||||
/* Not such severe to prevent loading */
|
||||
}
|
||||
if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_CALL_STATE, skinny_call_state_event_handler, NULL, &globals.call_state_node) != SWITCH_STATUS_SUCCESS)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our call_state handler!\n");
|
||||
return SWITCH_STATUS_TERM;
|
||||
@@ -2145,6 +2183,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our trap handler!\n");
|
||||
/* Not such severe to prevent loading */
|
||||
}
|
||||
if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE, skinny_user_to_device_event_handler, NULL, &globals.user_to_device_node) != SWITCH_STATUS_SUCCESS)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our user_to_device handler!\n");
|
||||
/* Not such severe to prevent loading */
|
||||
}
|
||||
|
||||
/* reserve events */
|
||||
if (switch_event_reserve_subclass(SKINNY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) {
|
||||
@@ -2167,6 +2209,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_CALL_STATE);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
if (switch_event_reserve_subclass(SKINNY_EVENT_USER_TO_DEVICE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_USER_TO_DEVICE);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
if (switch_event_reserve_subclass(SKINNY_EVENT_DEVICE_TO_USER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_DEVICE_TO_USER);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(globals.pool, modname);
|
||||
@@ -2205,7 +2255,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown)
|
||||
skinny_api_unregister();
|
||||
|
||||
/* release events */
|
||||
switch_event_unbind(&globals.heartbeat_node);
|
||||
switch_event_unbind(&globals.user_to_device_node);
|
||||
switch_event_unbind(&globals.call_state_node);
|
||||
switch_event_unbind(&globals.message_waiting_node);
|
||||
switch_event_unbind(&globals.trap_node);
|
||||
@@ -2214,6 +2264,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown)
|
||||
switch_event_free_subclass(SKINNY_EVENT_EXPIRE);
|
||||
switch_event_free_subclass(SKINNY_EVENT_ALARM);
|
||||
switch_event_free_subclass(SKINNY_EVENT_CALL_STATE);
|
||||
switch_event_free_subclass(SKINNY_EVENT_USER_TO_DEVICE);
|
||||
switch_event_free_subclass(SKINNY_EVENT_DEVICE_TO_USER);
|
||||
|
||||
switch_mutex_lock(mutex);
|
||||
|
||||
|
||||
@@ -43,13 +43,15 @@
|
||||
#define SKINNY_EVENT_EXPIRE "skinny::expire"
|
||||
#define SKINNY_EVENT_ALARM "skinny::alarm"
|
||||
#define SKINNY_EVENT_CALL_STATE "skinny::call_state"
|
||||
#define SKINNY_EVENT_USER_TO_DEVICE "skinny::user_to_device"
|
||||
#define SKINNY_EVENT_DEVICE_TO_USER "skinny::device_to_user"
|
||||
|
||||
struct skinny_globals {
|
||||
int running;
|
||||
switch_memory_pool_t *pool;
|
||||
switch_mutex_t *mutex;
|
||||
switch_hash_t *profile_hash;
|
||||
switch_event_node_t *heartbeat_node;
|
||||
switch_event_node_t *user_to_device_node;
|
||||
switch_event_node_t *call_state_node;
|
||||
switch_event_node_t *message_waiting_node;
|
||||
switch_event_node_t *trap_node;
|
||||
|
||||
@@ -366,6 +366,62 @@ static switch_status_t skinny_api_cmd_profile_device_send_reset_message(const ch
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t skinny_api_cmd_profile_device_send_data(const char *profile_name, const char *device_name, const char *message_type, char *params, const char *body, switch_stream_handle_t *stream)
|
||||
{
|
||||
skinny_profile_t *profile;
|
||||
|
||||
if ((profile = skinny_find_profile(profile_name))) {
|
||||
listener_t *listener = NULL;
|
||||
skinny_profile_find_listener_by_device_name(profile, device_name, &listener);
|
||||
if(listener) {
|
||||
switch_event_t *event = NULL;
|
||||
char *argv[64] = { 0 };
|
||||
int argc = 0;
|
||||
int x = 0;
|
||||
/* skinny::user_to_device event */
|
||||
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Message-Id-String", "%s", message_type);
|
||||
argc = switch_separate_string(params, ';', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
for (x = 0; x < argc; x++) {
|
||||
char *var_name, *var_value = NULL;
|
||||
var_name = argv[x];
|
||||
if (var_name && (var_value = strchr(var_name, '='))) {
|
||||
*var_value++ = '\0';
|
||||
}
|
||||
if (zstr(var_name)) {
|
||||
stream->write_function(stream, "-ERR No variable specified\n");
|
||||
} else {
|
||||
char *tmp = switch_mprintf("Skinny-UserToDevice-%s", var_name);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, tmp, "%s", var_value);
|
||||
switch_safe_free(tmp);
|
||||
/*
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Application-Id", "%d", request->data.extended_data.application_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Line-Instance", "%d", request->data.extended_data.line_instance);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Call-Id", "%d", request->data.extended_data.call_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Transaction-Id", "%d", request->data.extended_data.transaction_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Data-Length", "%d", request->data.extended_data.data_length);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Sequence-Flag", "%d", request->data.extended_data.sequence_flag);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Display-Priority", "%d", request->data.extended_data.display_priority);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Conference-Id", "%d", request->data.extended_data.conference_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-App-Instance-Id", "%d", request->data.extended_data.app_instance_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Routing-Id", "%d", request->data.extended_data.routing_id);
|
||||
*/
|
||||
}
|
||||
}
|
||||
switch_event_add_body(event, "%s", body);
|
||||
switch_event_fire(&event);
|
||||
stream->write_function(stream, "+OK\n");
|
||||
} else {
|
||||
stream->write_function(stream, "Listener not found!\n");
|
||||
}
|
||||
} else {
|
||||
stream->write_function(stream, "Profile not found!\n");
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static switch_status_t skinny_api_cmd_profile_set(const char *profile_name, const char *name, const char *value, switch_stream_handle_t *stream)
|
||||
{
|
||||
skinny_profile_t *profile;
|
||||
@@ -403,6 +459,7 @@ SWITCH_STANDARD_API(skinny_function)
|
||||
"skinny profile <profile_name> device <device_name> send SetLampMessage <stimulus> <instance> <lamp_mode>\n"
|
||||
"skinny profile <profile_name> device <device_name> send SetSpeakerModeMessage <speaker_mode>\n"
|
||||
"skinny profile <profile_name> device <device_name> send CallStateMessage <call_state> <line_instance> <call_id>\n"
|
||||
"skinny profile <profile_name> device <device_name> send <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> [ <param>=<value>;... ] <data>\n"
|
||||
"skinny profile <profile_name> set <name> <value>\n"
|
||||
"--------------------------------------------------------------------------------\n";
|
||||
if (session) {
|
||||
@@ -465,6 +522,16 @@ SWITCH_STANDARD_API(skinny_function)
|
||||
status = skinny_api_cmd_profile_device_send_reset_message(argv[1], argv[3], argv[6], stream);
|
||||
}
|
||||
break;
|
||||
case USER_TO_DEVICE_DATA_MESSAGE:
|
||||
case USER_TO_DEVICE_DATA_VERSION1_MESSAGE:
|
||||
if(argc == 8) {
|
||||
/* <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> [ <param>=<value>;... ] <data> */
|
||||
status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], argv[6], argv[7], stream);
|
||||
} else if(argc == 7) {
|
||||
/* <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> <data> */
|
||||
status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], "", argv[6], stream);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
stream->write_function(stream, "Unhandled message %s\n", argv[5]);
|
||||
}
|
||||
@@ -495,6 +562,8 @@ switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_
|
||||
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetLampMessage ::skinny::list_stimuli ::skinny::list_stimulus_instances ::skinny::list_stimulus_modes");
|
||||
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetSpeakerModeMessage ::skinny::list_speaker_modes");
|
||||
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send CallStateMessage ::skinny::list_call_states ::skinny::list_line_instances ::skinny::list_call_ids");
|
||||
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataMessage");
|
||||
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataVersion1Message");
|
||||
switch_console_set_complete("add skinny profile ::skinny::list_profiles set ::skinny::list_settings");
|
||||
|
||||
switch_console_add_complete_func("::skinny::list_profiles", skinny_api_list_profiles);
|
||||
|
||||
@@ -135,6 +135,10 @@ switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req)
|
||||
|
||||
status = switch_socket_recv(listener->sock, ptr, &mlen);
|
||||
|
||||
if (listener->expire_time && listener->expire_time < switch_epoch_time_now(NULL)) {
|
||||
return SWITCH_STATUS_TIMEOUT;
|
||||
}
|
||||
|
||||
if (!listener_is_ready(listener)) {
|
||||
break;
|
||||
}
|
||||
@@ -898,6 +902,68 @@ switch_status_t send_reset(listener_t *listener, uint32_t reset_type)
|
||||
return skinny_send_reply(listener, message);
|
||||
}
|
||||
|
||||
switch_status_t send_data(listener_t *listener, uint32_t message_type,
|
||||
uint32_t application_id,
|
||||
uint32_t line_instance,
|
||||
uint32_t call_id,
|
||||
uint32_t transaction_id,
|
||||
uint32_t data_length,
|
||||
const char *data)
|
||||
{
|
||||
skinny_message_t *message;
|
||||
switch_assert(data_length == strlen(data));
|
||||
/* data_length should be a multiple of 4 */
|
||||
if ((data_length % 4) != 0) {
|
||||
data_length = (data_length / 4 + 1) * 4;
|
||||
}
|
||||
message = switch_core_alloc(listener->pool, 12+sizeof(message->data.data)+data_length-1);
|
||||
message->type = message_type;
|
||||
message->length = 4 + sizeof(message->data.data)+data_length-1;
|
||||
message->data.data.application_id = application_id;
|
||||
message->data.data.line_instance = line_instance;
|
||||
message->data.data.call_id = call_id;
|
||||
message->data.data.transaction_id = transaction_id;
|
||||
message->data.data.data_length = data_length;
|
||||
strncpy(message->data.data.data, data, data_length);
|
||||
return skinny_send_reply(listener, message);
|
||||
}
|
||||
|
||||
switch_status_t send_extended_data(listener_t *listener, uint32_t message_type,
|
||||
uint32_t application_id,
|
||||
uint32_t line_instance,
|
||||
uint32_t call_id,
|
||||
uint32_t transaction_id,
|
||||
uint32_t data_length,
|
||||
uint32_t sequence_flag,
|
||||
uint32_t display_priority,
|
||||
uint32_t conference_id,
|
||||
uint32_t app_instance_id,
|
||||
uint32_t routing_id,
|
||||
const char *data)
|
||||
{
|
||||
skinny_message_t *message;
|
||||
switch_assert(data_length == strlen(data));
|
||||
/* data_length should be a multiple of 4 */
|
||||
if ((data_length % 4) != 0) {
|
||||
data_length = (data_length / 4 + 1) * 4;
|
||||
}
|
||||
message = switch_core_alloc(listener->pool, 12+sizeof(message->data.extended_data)+data_length-1);
|
||||
message->type = message_type;
|
||||
message->length = 4 + sizeof(message->data.extended_data)+data_length-1;
|
||||
message->data.extended_data.application_id = application_id;
|
||||
message->data.extended_data.line_instance = line_instance;
|
||||
message->data.extended_data.call_id = call_id;
|
||||
message->data.extended_data.transaction_id = transaction_id;
|
||||
message->data.extended_data.data_length = data_length;
|
||||
message->data.extended_data.sequence_flag = sequence_flag;
|
||||
message->data.extended_data.display_priority = display_priority;
|
||||
message->data.extended_data.conference_id = conference_id;
|
||||
message->data.extended_data.app_instance_id = app_instance_id;
|
||||
message->data.extended_data.routing_id = routing_id;
|
||||
strncpy(message->data.extended_data.data, data, data_length);
|
||||
return skinny_send_reply(listener, message);
|
||||
}
|
||||
|
||||
switch_status_t skinny_perform_send_reply(listener_t *listener, const char *file, const char *func, int line, skinny_message_t *reply)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
@@ -174,6 +174,21 @@ struct PACKED register_available_lines_message {
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
/* DeviceToUserDataMessage */
|
||||
#define DEVICE_TO_USER_DATA_MESSAGE 0x002E
|
||||
struct PACKED data_message {
|
||||
uint32_t application_id;
|
||||
uint32_t line_instance;
|
||||
uint32_t call_id;
|
||||
uint32_t transaction_id;
|
||||
uint32_t data_length;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
/* DeviceToUserDataResponseMessage */
|
||||
#define DEVICE_TO_USER_DATA_RESPONSE_MESSAGE 0x002F
|
||||
/* See struct PACKED data_message */
|
||||
|
||||
/* ServiceUrlStatReqMessage */
|
||||
#define SERVICE_URL_STAT_REQ_MESSAGE 0x0033
|
||||
struct PACKED service_url_stat_req_message {
|
||||
@@ -186,6 +201,26 @@ struct PACKED feature_stat_req_message {
|
||||
uint32_t feature_index;
|
||||
};
|
||||
|
||||
/* DeviceToUserDataVersion1Message */
|
||||
#define DEVICE_TO_USER_DATA_VERSION1_MESSAGE 0x0041
|
||||
struct PACKED extended_data_message {
|
||||
uint32_t application_id;
|
||||
uint32_t line_instance;
|
||||
uint32_t call_id;
|
||||
uint32_t transaction_id;
|
||||
uint32_t data_length;
|
||||
uint32_t sequence_flag;
|
||||
uint32_t display_priority;
|
||||
uint32_t conference_id;
|
||||
uint32_t app_instance_id;
|
||||
uint32_t routing_id;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
/* DeviceToUserDataResponseVersion1Message */
|
||||
#define DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE 0x0042
|
||||
/* See struct PACKED extended_data_message */
|
||||
|
||||
/* RegisterAckMessage */
|
||||
#define REGISTER_ACK_MESSAGE 0x0081
|
||||
struct PACKED register_ack_message {
|
||||
@@ -479,6 +514,10 @@ struct PACKED dialed_number_message {
|
||||
uint32_t call_id;
|
||||
};
|
||||
|
||||
/* UserToDeviceDataMessage */
|
||||
#define USER_TO_DEVICE_DATA_MESSAGE 0x011E
|
||||
/* See struct PACKED data_message */
|
||||
|
||||
/* FeatureStatMessage */
|
||||
#define FEATURE_STAT_RES_MESSAGE 0x011F
|
||||
struct PACKED feature_stat_res_message {
|
||||
@@ -504,6 +543,10 @@ struct PACKED service_url_stat_res_message {
|
||||
char display_name[40];
|
||||
};
|
||||
|
||||
/* UserToDeviceDataVersion1Message */
|
||||
#define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F
|
||||
/* See struct PACKED extended_data_message */
|
||||
|
||||
/*****************************************************************************/
|
||||
/* SKINNY MESSAGE */
|
||||
/*****************************************************************************/
|
||||
@@ -512,6 +555,7 @@ struct PACKED service_url_stat_res_message {
|
||||
#define SKINNY_MESSAGE_MAXSIZE 1000
|
||||
|
||||
union skinny_data {
|
||||
/* no data for KEEP_ALIVE_MESSAGE */
|
||||
struct register_message reg;
|
||||
struct port_message port;
|
||||
struct keypad_button_message keypad_button;
|
||||
@@ -520,14 +564,25 @@ union skinny_data {
|
||||
struct on_hook_message on_hook;
|
||||
struct speed_dial_stat_req_message speed_dial_req;
|
||||
struct line_stat_req_message line_req;
|
||||
/* no data for CONFIG_STAT_REQ_MESSAGE */
|
||||
/* no data for TIME_DATE_REQ_MESSAGE */
|
||||
/* no data for BUTTON_TEMPLATE_REQ_MESSAGE */
|
||||
/* no data for VERSION_REQ_MESSAGE */
|
||||
struct capabilities_res_message cap_res;
|
||||
struct alarm_message alarm;
|
||||
struct open_receive_channel_ack_message open_receive_channel_ack;
|
||||
/* no data for SOFT_KEY_SET_REQ_MESSAGE */
|
||||
struct soft_key_event_message soft_key_event;
|
||||
struct service_url_stat_req_message service_url_req;
|
||||
struct feature_stat_req_message feature_req;
|
||||
/* no data for UNREGISTER_MESSAGE */
|
||||
/* no data for SOFT_KEY_TEMPLATE_REQ_MESSAGE */
|
||||
struct headset_status_message headset_status;
|
||||
struct register_available_lines_message reg_lines;
|
||||
/* see field "data" for DEVICE_TO_USER_DATA_MESSAGE */
|
||||
/* see field "data" for DEVICE_TO_USER_DATA_RESPONSE_MESSAGE */
|
||||
struct service_url_stat_req_message service_url_req;
|
||||
struct feature_stat_req_message feature_req;
|
||||
/* see field "extended_data" for DEVICE_TO_USER_DATA_VERSION1_MESSAGE */
|
||||
/* see field "extended_data" for DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE */
|
||||
struct register_ack_message reg_ack;
|
||||
struct start_tone_message start_tone;
|
||||
struct stop_tone_message stop_tone;
|
||||
@@ -543,8 +598,10 @@ union skinny_data {
|
||||
struct define_time_date_message define_time_date;
|
||||
struct button_template_message button_template;
|
||||
struct version_message version;
|
||||
/* no data for CAPABILITIES_REQ_MESSAGE */
|
||||
struct register_reject_message reg_rej;
|
||||
struct reset_message reset;
|
||||
/* no data for KEEP_ALIVE_ACK_MESSAGE */
|
||||
struct open_receive_channel_message open_receive_channel;
|
||||
struct close_receive_channel_message close_receive_channel;
|
||||
struct soft_key_template_res_message soft_key_template;
|
||||
@@ -557,9 +614,14 @@ union skinny_data {
|
||||
struct unregister_ack_message unregister_ack;
|
||||
struct back_space_req_message back_space_req;
|
||||
struct dialed_number_message dialed_number;
|
||||
/* see field "data" for USER_TO_DEVICE_DATA_MESSAGE */
|
||||
struct feature_stat_res_message feature_res;
|
||||
struct display_pri_notify_message display_pri_notify;
|
||||
struct service_url_stat_res_message service_url_res;
|
||||
/* see field "extended_data" for USER_TO_DEVICE_DATA_VERSION1_MESSAGE */
|
||||
|
||||
struct data_message data;
|
||||
struct extended_data_message extended_data;
|
||||
|
||||
uint16_t as_uint16;
|
||||
char as_char;
|
||||
@@ -777,6 +839,27 @@ switch_status_t send_display_pri_notify(listener_t *listener,
|
||||
switch_status_t send_reset(listener_t *listener,
|
||||
uint32_t reset_type);
|
||||
|
||||
switch_status_t send_data(listener_t *listener, uint32_t message_type,
|
||||
uint32_t application_id,
|
||||
uint32_t line_instance,
|
||||
uint32_t call_id,
|
||||
uint32_t transaction_id,
|
||||
uint32_t data_length,
|
||||
const char *data);
|
||||
|
||||
switch_status_t send_extended_data(listener_t *listener, uint32_t message_type,
|
||||
uint32_t application_id,
|
||||
uint32_t line_instance,
|
||||
uint32_t call_id,
|
||||
uint32_t transaction_id,
|
||||
uint32_t data_length,
|
||||
uint32_t sequence_flag,
|
||||
uint32_t display_priority,
|
||||
uint32_t conference_id,
|
||||
uint32_t app_instance_id,
|
||||
uint32_t routing_id,
|
||||
const char *data);
|
||||
|
||||
#endif /* _SKINNY_PROTOCOL_H */
|
||||
|
||||
/* For Emacs:
|
||||
|
||||
@@ -1864,6 +1864,33 @@ switch_status_t skinny_handle_register_available_lines_message(listener_t *liste
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t skinny_handle_data_message(listener_t *listener, skinny_message_t *request)
|
||||
{
|
||||
switch_event_t *event = NULL;
|
||||
char *tmp = NULL;
|
||||
skinny_check_data_length(request, sizeof(request->data.data));
|
||||
skinny_check_data_length(request, sizeof(request->data.data) + request->data.data.data_length - 1);
|
||||
|
||||
/* skinny::device_to_user event */
|
||||
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.data.application_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.data.line_instance);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.data.call_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.data.transaction_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.data.data_length);
|
||||
/* Ensure that the body is null-terminated */
|
||||
tmp = malloc(request->data.data.data_length + 1);
|
||||
memcpy(tmp, request->data.data.data, request->data.data.data_length);
|
||||
tmp[request->data.data.data_length] = '\0';
|
||||
switch_event_add_body(event, "%s", tmp);
|
||||
switch_safe_free(tmp);
|
||||
switch_event_fire(&event);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request)
|
||||
{
|
||||
skinny_message_t *message;
|
||||
@@ -1904,6 +1931,38 @@ switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny_message_t *request)
|
||||
{
|
||||
switch_event_t *event = NULL;
|
||||
char *tmp = NULL;
|
||||
skinny_check_data_length(request, sizeof(request->data.extended_data));
|
||||
skinny_check_data_length(request, sizeof(request->data.extended_data)+request->data.extended_data.data_length-1);
|
||||
|
||||
/* skinny::device_to_user event */
|
||||
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.extended_data.application_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.extended_data.line_instance);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.extended_data.call_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.extended_data.transaction_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.extended_data.data_length);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Sequence-Flag", "%d", request->data.extended_data.sequence_flag);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Display-Priority", "%d", request->data.extended_data.display_priority);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Conference-Id", "%d", request->data.extended_data.conference_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-App-Instance-Id", "%d", request->data.extended_data.app_instance_id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Routing-Id", "%d", request->data.extended_data.routing_id);
|
||||
/* Ensure that the body is null-terminated */
|
||||
tmp = malloc(request->data.data.data_length + 1);
|
||||
memcpy(tmp, request->data.data.data, request->data.data.data_length);
|
||||
tmp[request->data.data.data_length] = '\0';
|
||||
switch_event_add_body(event, "%s", tmp);
|
||||
switch_safe_free(tmp);
|
||||
switch_event_fire(&event);
|
||||
|
||||
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) {
|
||||
@@ -1961,10 +2020,18 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re
|
||||
return skinny_headset_status_message(listener, request);
|
||||
case REGISTER_AVAILABLE_LINES_MESSAGE:
|
||||
return skinny_handle_register_available_lines_message(listener, request);
|
||||
case DEVICE_TO_USER_DATA_MESSAGE:
|
||||
return skinny_handle_data_message(listener, request);
|
||||
case DEVICE_TO_USER_DATA_RESPONSE_MESSAGE:
|
||||
return skinny_handle_data_message(listener, request);
|
||||
case SERVICE_URL_STAT_REQ_MESSAGE:
|
||||
return skinny_handle_service_url_stat_request(listener, request);
|
||||
case FEATURE_STAT_REQ_MESSAGE:
|
||||
return skinny_handle_feature_stat_request(listener, request);
|
||||
case DEVICE_TO_USER_DATA_VERSION1_MESSAGE:
|
||||
return skinny_handle_extended_data_message(listener, request);
|
||||
case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE:
|
||||
return skinny_handle_extended_data_message(listener, request);
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
||||
"Unhandled request %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length);
|
||||
|
||||
@@ -55,10 +55,14 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
|
||||
{"SoftKeyEventMessage", SOFT_KEY_EVENT_MESSAGE},
|
||||
{"UnregisterMessage", UNREGISTER_MESSAGE},
|
||||
{"SoftKeyTemplateReqMessage", SOFT_KEY_TEMPLATE_REQ_MESSAGE},
|
||||
{"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE},
|
||||
{"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE},
|
||||
{"HeadsetStatusMessage", HEADSET_STATUS_MESSAGE},
|
||||
{"RegisterAvailableLinesMessage", REGISTER_AVAILABLE_LINES_MESSAGE},
|
||||
{"DeviceToUserDataMessage", DEVICE_TO_USER_DATA_MESSAGE},
|
||||
{"DeviceToUserDataResponseMessage", DEVICE_TO_USER_DATA_RESPONSE_MESSAGE},
|
||||
{"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE},
|
||||
{"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE},
|
||||
{"DeviceToUserDataVersion1Message", DEVICE_TO_USER_DATA_VERSION1_MESSAGE},
|
||||
{"DeviceToUserDataResponseVersion1Message", DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE},
|
||||
{"RegisterAckMessage", REGISTER_ACK_MESSAGE},
|
||||
{"StartToneMessage", START_TONE_MESSAGE},
|
||||
{"StopToneMessage", STOP_TONE_MESSAGE},
|
||||
@@ -90,9 +94,11 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
|
||||
{"UnregisterAckMessage", UNREGISTER_ACK_MESSAGE},
|
||||
{"BackSpaceReqMessage", BACK_SPACE_REQ_MESSAGE},
|
||||
{"DialedNumberMessage", DIALED_NUMBER_MESSAGE},
|
||||
{"UserToDeviceDataMessage", USER_TO_DEVICE_DATA_MESSAGE},
|
||||
{"FeatureResMessage", FEATURE_STAT_RES_MESSAGE},
|
||||
{"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE},
|
||||
{"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE},
|
||||
{"UserToDeviceDataVersion1Message", USER_TO_DEVICE_DATA_VERSION1_MESSAGE},
|
||||
{NULL, 0}
|
||||
};
|
||||
SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage")
|
||||
|
||||
@@ -87,7 +87,7 @@ uint32_t func(const char *str)\
|
||||
}
|
||||
|
||||
|
||||
extern struct skinny_table SKINNY_MESSAGE_TYPES[59];
|
||||
extern struct skinny_table SKINNY_MESSAGE_TYPES[65];
|
||||
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)
|
||||
|
||||
@@ -1238,7 +1238,12 @@ static void start_udptl(private_object_t *tech_pvt, switch_t38_options_t *t38_op
|
||||
|
||||
switch_rtp_udptl_mode(tech_pvt->rtp_session);
|
||||
|
||||
if (remote_host && remote_port && !strcmp(remote_host, t38_options->remote_ip) && remote_port == t38_options->remote_port) {
|
||||
if (!t38_options || !t38_options->remote_ip) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "No remote address\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (remote_host && remote_port && remote_port == t38_options->remote_port && !strcmp(remote_host, t38_options->remote_ip)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n",
|
||||
t38_options->remote_ip, t38_options->remote_port);
|
||||
return;
|
||||
@@ -1477,12 +1482,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
|
||||
{
|
||||
const char *pl =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
|
||||
" <media_control>\r\n"
|
||||
" <vc_primitive>\r\n"
|
||||
" <to_encoder>\r\n"
|
||||
" <picture_fast_update>\r\n" " </picture_fast_update>\r\n" " </to_encoder>\r\n" " </vc_primitive>\r\n" " </media_control>\r\n";
|
||||
const char *pl = "<media_control><vc_primitive><to_encoder><picture_fast_update/></to_encoder></vc_primitive></media_control>";
|
||||
|
||||
if (!zstr(msg->string_arg)) {
|
||||
pl = msg->string_arg;
|
||||
}
|
||||
|
||||
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
|
||||
|
||||
@@ -1771,7 +1775,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
nua_update(tech_pvt->nh,
|
||||
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
|
||||
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
|
||||
} else if ((ua && (switch_stristr("cisco", ua)))) {
|
||||
} else if ((ua && (switch_stristr("cisco/spa50", ua) || switch_stristr("cisco/spa525", ua)))) {
|
||||
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <sip:%s@%s>", name, number, tech_pvt->profile->sipip);
|
||||
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
|
||||
@@ -2011,6 +2015,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options");
|
||||
if (t38_options) {
|
||||
sofia_glue_set_image_sdp(tech_pvt, t38_options, 0);
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
||||
switch_rtp_udptl_mode(tech_pvt->rtp_session);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sofia_glue_tech_set_local_sdp(tech_pvt, sdp, SWITCH_TRUE);
|
||||
@@ -2096,6 +2103,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
status = sofia_answer_channel(session);
|
||||
if (switch_channel_test_flag(tech_pvt->channel, CF_VIDEO)) {
|
||||
sofia_glue_build_vid_refresh_message(session, NULL);
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
{
|
||||
@@ -2321,7 +2331,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam
|
||||
switch_time_t etime = atoi(argv[6]);
|
||||
switch_size_t retsize;
|
||||
|
||||
exp_secs = etime - now;
|
||||
exp_secs = (int)(etime - now);
|
||||
switch_time_exp_lt(&tm, switch_time_from_sec(etime));
|
||||
switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm);
|
||||
}
|
||||
@@ -2361,7 +2371,7 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum
|
||||
switch_time_t etime = atoi(argv[6]);
|
||||
switch_size_t retsize;
|
||||
|
||||
exp_secs = etime - now;
|
||||
exp_secs = (int)(etime - now);
|
||||
switch_time_exp_lt(&tm, switch_time_from_sec(etime));
|
||||
switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm);
|
||||
}
|
||||
@@ -2428,7 +2438,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
|
||||
ob_failed += gp->ob_failed_calls;
|
||||
ob += gp->ob_calls;
|
||||
|
||||
stream->write_function(stream, "%25s\t%32s\t%s\t%ld/%ld\t%ld/%ld",
|
||||
stream->write_function(stream, "%25s\t%32s\t%s\t%u/%u\t%u/%u",
|
||||
pkey, gp->register_to, sofia_state_names[gp->state],
|
||||
gp->ib_failed_calls, gp->ib_calls, gp->ob_failed_calls, gp->ob_calls);
|
||||
|
||||
@@ -2447,8 +2457,8 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
|
||||
}
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
stream->write_function(stream, "%s\n", line);
|
||||
stream->write_function(stream, "%d gateway%s: Inound(Failed/Total): %ld/%ld,"
|
||||
"Outbound(Failed/Total):%ld/%ld\n", c, c == 1 ? "" : "s", ib_failed, ib, ob_failed, ob);
|
||||
stream->write_function(stream, "%d gateway%s: Inbound(Failed/Total): %u/%u,"
|
||||
"Outbound(Failed/Total):%u/%u\n", c, c == 1 ? "" : "s", ib_failed, ib, ob_failed, ob);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -2477,10 +2487,10 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
|
||||
stream->write_function(stream, "PingState\t%d/%d/%d\n", gp->ping_min, gp->ping_count, gp->ping_max);
|
||||
stream->write_function(stream, "State \t%s\n", sofia_state_names[gp->state]);
|
||||
stream->write_function(stream, "Status \t%s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : "");
|
||||
stream->write_function(stream, "CallsIN \t%d\n", gp->ib_calls);
|
||||
stream->write_function(stream, "CallsOUT\t%d\n", gp->ob_calls);
|
||||
stream->write_function(stream, "FailedCallsIN\t%d\n", gp->ib_failed_calls);
|
||||
stream->write_function(stream, "FailedCallsOUT\t%d\n", gp->ob_failed_calls);
|
||||
stream->write_function(stream, "CallsIN \t%u\n", gp->ib_calls);
|
||||
stream->write_function(stream, "CallsOUT\t%u\n", gp->ob_calls);
|
||||
stream->write_function(stream, "FailedCallsIN\t%u\n", gp->ib_failed_calls);
|
||||
stream->write_function(stream, "FailedCallsOUT\t%u\n", gp->ob_failed_calls);
|
||||
stream->write_function(stream, "%s\n", line);
|
||||
sofia_reg_release_gateway(gp);
|
||||
} else {
|
||||
@@ -2489,7 +2499,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
|
||||
} else if (!strcasecmp(argv[0], "profile")) {
|
||||
struct cb_helper cb;
|
||||
char *sql = NULL;
|
||||
int x = 0;
|
||||
uint32_t x = 0;
|
||||
|
||||
cb.row_process = 0;
|
||||
|
||||
@@ -2554,10 +2564,10 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
|
||||
if (profile->max_registrations_perext > 0) {
|
||||
stream->write_function(stream, "MAX-REG-PEREXT \t%d\n", profile->max_registrations_perext);
|
||||
}
|
||||
stream->write_function(stream, "CALLS-IN \t%d\n", profile->ib_calls);
|
||||
stream->write_function(stream, "FAILED-CALLS-IN \t%d\n", profile->ib_failed_calls);
|
||||
stream->write_function(stream, "CALLS-OUT \t%d\n", profile->ob_calls);
|
||||
stream->write_function(stream, "FAILED-CALLS-OUT \t%d\n", profile->ob_failed_calls);
|
||||
stream->write_function(stream, "CALLS-IN \t%u\n", profile->ib_calls);
|
||||
stream->write_function(stream, "FAILED-CALLS-IN \t%u\n", profile->ib_failed_calls);
|
||||
stream->write_function(stream, "CALLS-OUT \t%u\n", profile->ob_calls);
|
||||
stream->write_function(stream, "FAILED-CALLS-OUT \t%u\n", profile->ob_failed_calls);
|
||||
}
|
||||
stream->write_function(stream, "\nRegistrations:\n%s\n", line);
|
||||
|
||||
@@ -2703,10 +2713,10 @@ static void xml_gateway_status(sofia_gateway_t *gp, switch_stream_handle_t *stre
|
||||
stream->write_function(stream, " <pingfreq>%d</pingfreq>\n", gp->ping_freq);
|
||||
stream->write_function(stream, " <state>%s</state>\n", sofia_state_names[gp->state]);
|
||||
stream->write_function(stream, " <status>%s%s</status>\n", status_names[gp->status], gp->pinging ? " (ping)" : "");
|
||||
stream->write_function(stream, " <calls-in>%d</calls-in>\n", gp->ib_calls);
|
||||
stream->write_function(stream, " <calls-out>%d</calls-out>\n", gp->ob_calls);
|
||||
stream->write_function(stream, " <failed-calls-in>%d</failed-calls-in>\n", gp->ib_failed_calls);
|
||||
stream->write_function(stream, " <failed-calls-out>%d</failed-calls-out>\n", gp->ob_failed_calls);
|
||||
stream->write_function(stream, " <calls-in>%u</calls-in>\n", gp->ib_calls);
|
||||
stream->write_function(stream, " <calls-out>%u</calls-out>\n", gp->ob_calls);
|
||||
stream->write_function(stream, " <failed-calls-in>%u</failed-calls-in>\n", gp->ib_failed_calls);
|
||||
stream->write_function(stream, " <failed-calls-out>%u</failed-calls-out>\n", gp->ob_failed_calls);
|
||||
|
||||
if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) {
|
||||
time_t now = switch_epoch_time_now(NULL);
|
||||
@@ -2769,7 +2779,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||
} else if (!strcasecmp(argv[0], "profile")) {
|
||||
struct cb_helper cb;
|
||||
char *sql = NULL;
|
||||
int x = 0;
|
||||
uint32_t x = 0;
|
||||
|
||||
cb.row_process = 0;
|
||||
|
||||
@@ -2825,10 +2835,10 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||
stream->write_function(stream, " <user-agent-filter>%s</user-agent-filter>\n", switch_str_nil(profile->user_agent_filter));
|
||||
stream->write_function(stream, " <max-registrations-per-extension>%d</max-registrations-per-extension>\n",
|
||||
profile->max_registrations_perext);
|
||||
stream->write_function(stream, " <calls-in>%d</calls-in>\n", profile->ib_calls);
|
||||
stream->write_function(stream, " <calls-out>%d</calls-out>\n", profile->ob_calls);
|
||||
stream->write_function(stream, " <failed-calls-in>%d</failed-calls-in>\n", profile->ib_failed_calls);
|
||||
stream->write_function(stream, " <failed-calls-out>%d</failed-calls-out>\n", profile->ob_failed_calls);
|
||||
stream->write_function(stream, " <calls-in>%u</calls-in>\n", profile->ib_calls);
|
||||
stream->write_function(stream, " <calls-out>%u</calls-out>\n", profile->ob_calls);
|
||||
stream->write_function(stream, " <failed-calls-in>%u</failed-calls-in>\n", profile->ib_failed_calls);
|
||||
stream->write_function(stream, " <failed-calls-out>%u</failed-calls-out>\n", profile->ob_failed_calls);
|
||||
stream->write_function(stream, " </profile-info>\n");
|
||||
}
|
||||
stream->write_function(stream, " <registrations>\n");
|
||||
@@ -3596,6 +3606,7 @@ SWITCH_STANDARD_API(sofia_function)
|
||||
"sofia status|xmlstatus gateway <name>\n"
|
||||
"sofia loglevel <all|default|tport|iptsec|nea|nta|nth_client|nth_server|nua|soa|sresolv|stun> [0-9]\n"
|
||||
"sofia tracelevel <console|alert|crit|err|warning|notice|info|debug>\n"
|
||||
"sofa global siptrace [on|off]\n"
|
||||
"--------------------------------------------------------------------------------\n";
|
||||
|
||||
if (session) {
|
||||
@@ -3651,6 +3662,26 @@ SWITCH_STANDARD_API(sofia_function)
|
||||
} else if (!strcasecmp(argv[0], "help")) {
|
||||
stream->write_function(stream, "%s", usage_string);
|
||||
goto done;
|
||||
} else if (!strcasecmp(argv[0], "global")) {
|
||||
int on = -1;
|
||||
|
||||
if (argc > 1) {
|
||||
if (!strcasecmp(argv[1], "siptrace")) {
|
||||
if (argc > 2) {
|
||||
on = switch_true(argv[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (on != -1) {
|
||||
sofia_glue_global_siptrace(on);
|
||||
stream->write_function(stream, "+OK Global siptrace %s", on ? "on" : "off");
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR Usage: siptrace on|off");
|
||||
}
|
||||
|
||||
goto done;
|
||||
|
||||
} else if (!strcasecmp(argv[0], "recover")) {
|
||||
if (argv[1] && !strcasecmp(argv[1], "flush")) {
|
||||
sofia_glue_recover(SWITCH_TRUE);
|
||||
@@ -4452,7 +4483,8 @@ static void general_event_handler(switch_event_t *event)
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
if (mod_sofia_globals.profile_hash) {
|
||||
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
||||
int rb = 0, x = 0;
|
||||
int rb = 0;
|
||||
uint32_t x = 0;
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
if ((profile = (sofia_profile_t *) val) && profile->auto_restart) {
|
||||
if (!strcmp(profile->sipip, old_ip4)) {
|
||||
@@ -4726,6 +4758,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
||||
switch_console_set_complete("add sofia loglevel ::[all:default:tport:iptsec:nea:nta:nth_client:nth_server:nua:soa:sresolv:stun ::[0:1:2:3:4:5:6:7:8:9");
|
||||
switch_console_set_complete("add sofia tracelevel ::[console:alert:crit:err:warning:notice:info:debug");
|
||||
|
||||
switch_console_set_complete("add sofia global siptrace ::[on:off");
|
||||
|
||||
switch_console_set_complete("add sofia profile");
|
||||
switch_console_set_complete("add sofia profile restart all");
|
||||
|
||||
|
||||
@@ -220,6 +220,7 @@ typedef enum {
|
||||
PFLAG_T38_PASSTHRU,
|
||||
PFLAG_CID_IN_1XX,
|
||||
PFLAG_IN_DIALOG_CHAT,
|
||||
PFLAG_DEL_SUBS_ON_REG,
|
||||
/* No new flags below this line */
|
||||
PFLAG_MAX
|
||||
} PFLAGS;
|
||||
@@ -577,6 +578,7 @@ struct private_object {
|
||||
switch_codec_t read_codec;
|
||||
switch_codec_t write_codec;
|
||||
uint32_t codec_ms;
|
||||
uint32_t bitrate;
|
||||
switch_caller_profile_t *caller_profile;
|
||||
uint32_t timestamp_send;
|
||||
switch_rtp_t *rtp_session;
|
||||
@@ -926,6 +928,7 @@ sofia_transport_t sofia_glue_str2transport(const char *str);
|
||||
|
||||
const char *sofia_glue_transport2str(const sofia_transport_t tp);
|
||||
char *sofia_glue_find_parameter(const char *str, const char *param);
|
||||
char *sofia_glue_find_parameter_value(switch_core_session_t *session, const char *str, const char *param);
|
||||
char *sofia_glue_create_via(switch_core_session_t *session, const char *ip, switch_port_t port, sofia_transport_t transport);
|
||||
char *sofia_glue_create_external_via(switch_core_session_t *session, sofia_profile_t *profile, sofia_transport_t transport);
|
||||
char *sofia_glue_strip_uri(const char *str);
|
||||
@@ -1012,3 +1015,7 @@ char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefi
|
||||
void sofia_glue_tech_simplify(private_object_t *tech_pvt);
|
||||
switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host);
|
||||
switch_bool_t sofia_glue_profile_exists(const char *key);
|
||||
void sofia_glue_global_siptrace(switch_bool_t on);
|
||||
void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp);
|
||||
switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt);
|
||||
void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl);
|
||||
@@ -785,7 +785,7 @@ int dig_addr(struct dig *dig,
|
||||
char const *tport2 = NULL;
|
||||
sres_record_t **answers1 = NULL, **answers2 = NULL;
|
||||
unsigned count1 = 0, count2 = 0, tcount = 0;
|
||||
int type1 = 0, type2 = 0, family1 = 0, family2 = 0;
|
||||
uint16_t type1 = 0, type2 = 0, family1 = 0, family2 = 0;
|
||||
|
||||
if (dig->ip6 > dig->ip4) {
|
||||
type1 = sres_type_aaaa, family1 = AF_INET6;
|
||||
|
||||
@@ -1268,7 +1268,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
|
||||
iterations++;
|
||||
|
||||
if (len + newlen + 10 > sql_len) {
|
||||
int new_mlen = len + newlen + 10 + 10240;
|
||||
switch_size_t new_mlen = len + newlen + 10 + 10240;
|
||||
|
||||
if (new_mlen < SQLLEN) {
|
||||
sql_len = new_mlen;
|
||||
@@ -2223,6 +2223,35 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((settings = switch_xml_child(cfg, "global_settings"))) {
|
||||
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
|
||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
if (!strcasecmp(var, "log-level")) {
|
||||
su_log_set_level(NULL, atoi(val));
|
||||
} else if (!strcasecmp(var, "tracelevel")) {
|
||||
mod_sofia_globals.tracelevel = switch_log_str2level(val);
|
||||
} else if (!strcasecmp(var, "debug-presence")) {
|
||||
mod_sofia_globals.debug_presence = atoi(val);
|
||||
} else if (!strcasecmp(var, "debug-sla")) {
|
||||
mod_sofia_globals.debug_sla = atoi(val);
|
||||
} else if (!strcasecmp(var, "auto-restart")) {
|
||||
mod_sofia_globals.auto_restart = switch_true(val);
|
||||
} else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
|
||||
if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) {
|
||||
/* old behaviour */
|
||||
mod_sofia_globals.rewrite_multicasted_fs_path = 1;
|
||||
} else if (!strcasecmp(val, "original_server_host")) {
|
||||
mod_sofia_globals.rewrite_multicasted_fs_path = 2;
|
||||
} else if (!strcasecmp(val, "original_hostname")) {
|
||||
mod_sofia_globals.rewrite_multicasted_fs_path = 3;
|
||||
} else {
|
||||
mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((profiles = switch_xml_child(cfg, "profiles"))) {
|
||||
for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
|
||||
char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name");
|
||||
@@ -2257,14 +2286,18 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
|
||||
profile->debug = atoi(val);
|
||||
} else if (!strcasecmp(var, "shutdown-on-fail")) {
|
||||
profile->shutdown_type = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "tracelevel")) {
|
||||
mod_sofia_globals.tracelevel = switch_log_str2level(val);
|
||||
} else if (!strcasecmp(var, "pass-callee-id")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID);
|
||||
}
|
||||
} else if (!strcasecmp(var, "delete-subs-on-register")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
|
||||
}
|
||||
} else if (!strcasecmp(var, "in-dialog-chat")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT);
|
||||
@@ -2312,12 +2345,6 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
|
||||
}
|
||||
} else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
|
||||
}
|
||||
} else if (!strcasecmp(var, "t38-passthru")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_T38_PASSTHRU);
|
||||
@@ -2444,7 +2471,7 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
|
||||
sofia_clear_pflag(profile, PFLAG_STUN_AUTO_DISABLE);
|
||||
}
|
||||
} else if (!strcasecmp(var, "apply-nat-acl")) {
|
||||
if (profile->acl_count < SOFIA_MAX_ACL) {
|
||||
if (profile->nat_acl_count < SOFIA_MAX_ACL) {
|
||||
if (!profile->extsipip && switch_check_network_list_ip(profile->sipip, val)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Not adding acl %s because it's the local network\n", val);
|
||||
} else {
|
||||
@@ -2817,6 +2844,8 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
if (!strcasecmp(var, "log-level")) {
|
||||
su_log_set_level(NULL, atoi(val));
|
||||
} else if (!strcasecmp(var, "tracelevel")) {
|
||||
mod_sofia_globals.tracelevel = switch_log_str2level(val);
|
||||
} else if (!strcasecmp(var, "debug-presence")) {
|
||||
mod_sofia_globals.debug_presence = atoi(val);
|
||||
} else if (!strcasecmp(var, "debug-sla")) {
|
||||
@@ -2933,6 +2962,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
|
||||
}
|
||||
} else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
|
||||
}
|
||||
} else if (!strcasecmp(var, "user-agent-string")) {
|
||||
profile->user_agent = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "auto-restart")) {
|
||||
@@ -2949,6 +2984,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT);
|
||||
}
|
||||
} else if (!strcasecmp(var, "delete-subs-on-register")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
|
||||
}
|
||||
} else if (!strcasecmp(var, "t38-passthru")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_T38_PASSTHRU);
|
||||
@@ -3431,7 +3472,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
||||
} else if (!strcasecmp(var, "context")) {
|
||||
profile->context = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "apply-nat-acl")) {
|
||||
if (profile->acl_count < SOFIA_MAX_ACL) {
|
||||
if (profile->nat_acl_count < SOFIA_MAX_ACL) {
|
||||
if (!profile->extsipip && profile->sipip && switch_check_network_list_ip(profile->sipip, val)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Not adding acl %s because it's the local network\n", val);
|
||||
} else {
|
||||
@@ -3933,6 +3974,23 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (status == 200 && switch_channel_test_flag(channel, CF_PROXY_MEDIA) &&
|
||||
sip->sip_payload && sip->sip_payload->pl_data && !strcasecmp(tech_pvt->iananame, "PROXY")) {
|
||||
switch_core_session_t *other_session;
|
||||
|
||||
sofia_glue_proxy_codec(session, sip->sip_payload->pl_data);
|
||||
|
||||
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
|
||||
if (switch_core_session_compare(session, other_session)) {
|
||||
sofia_glue_proxy_codec(other_session, sip->sip_payload->pl_data);
|
||||
}
|
||||
switch_core_session_rwunlock(other_session);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if ((status == 180 || status == 183 || status == 200)) {
|
||||
const char *x_freeswitch_support;
|
||||
|
||||
@@ -3959,7 +4017,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
|
||||
|
||||
}
|
||||
|
||||
if (channel && sip && (status == 300 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
sip_contact_t *p_contact = sip->sip_contact;
|
||||
int i = 0;
|
||||
char var_name[80];
|
||||
@@ -4138,6 +4196,36 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
|
||||
if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) {
|
||||
if (sip->sip_payload && sip->sip_payload->pl_data) {
|
||||
switch_t38_options_t *t38_options = sofia_glue_extract_t38_options(session, sip->sip_payload->pl_data);
|
||||
char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session);
|
||||
switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
|
||||
char tmp[32] = "";
|
||||
|
||||
tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, t38_options->remote_ip);
|
||||
tech_pvt->remote_sdp_audio_port = t38_options->remote_port;
|
||||
|
||||
if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) &&
|
||||
remote_port == tech_pvt->remote_sdp_audio_port) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
|
||||
"Audio params are unchanged for %s.\n",
|
||||
switch_channel_get_name(tech_pvt->channel));
|
||||
} else {
|
||||
const char *err = NULL;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
|
||||
"Audio params changed for %s from %s:%d to %s:%d\n",
|
||||
switch_channel_get_name(tech_pvt->channel),
|
||||
remote_host, remote_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port);
|
||||
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
|
||||
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
|
||||
if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip,
|
||||
tech_pvt->remote_sdp_audio_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (t38_options) {
|
||||
sofia_glue_copy_t38_options(t38_options, other_session);
|
||||
@@ -4167,14 +4255,11 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
|
||||
if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) {
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session) && switch_rtp_ready(other_tech_pvt->rtp_session)) {
|
||||
switch_rtp_udptl_mode(tech_pvt->rtp_session);
|
||||
switch_rtp_udptl_mode(other_tech_pvt->rtp_session);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating T38 Passthru\n");
|
||||
}
|
||||
switch_core_session_receive_message(other_session, msg);
|
||||
} else {
|
||||
switch_core_session_queue_message(other_session, msg);
|
||||
}
|
||||
|
||||
switch_core_session_queue_message(other_session, msg);
|
||||
|
||||
switch_core_session_rwunlock(other_session);
|
||||
}
|
||||
@@ -4394,7 +4479,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
|
||||
if (ss_state == nua_callstate_terminated) {
|
||||
|
||||
if ((status == 300 || status == 302 || status == 305) && session) {
|
||||
if ((status == 300 || status == 301 || status == 302 || status == 305) && session) {
|
||||
channel = switch_core_session_get_channel(session);
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
|
||||
@@ -4467,6 +4552,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
state_process:
|
||||
|
||||
switch ((enum nua_callstate) ss_state) {
|
||||
@@ -4945,6 +5032,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
|
||||
sofia_set_flag(tech_pvt, TFLAG_SDP);
|
||||
switch_channel_mark_answered(channel);
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
|
||||
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
|
||||
&& (other_session = switch_core_session_locate(uuid))) {
|
||||
@@ -4965,6 +5053,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_SDP);
|
||||
switch_channel_mark_answered(channel);
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
|
||||
if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) {
|
||||
goto done;
|
||||
@@ -5070,6 +5159,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
|
||||
if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) {
|
||||
sofia_glue_tech_simplify(tech_pvt);
|
||||
@@ -5221,7 +5311,6 @@ nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces)
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[])
|
||||
{
|
||||
/* Incoming refer */
|
||||
@@ -5794,7 +5883,17 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
|
||||
|
||||
if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
|
||||
sip->sip_payload && sip->sip_payload->pl_data) {
|
||||
if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) {
|
||||
if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) {
|
||||
switch_core_session_t *other_session;
|
||||
|
||||
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
|
||||
sofia_glue_build_vid_refresh_message(other_session, sip->sip_payload->pl_data);
|
||||
switch_core_session_rwunlock(other_session);
|
||||
} else {
|
||||
sofia_glue_build_vid_refresh_message(session, sip->sip_payload->pl_data);
|
||||
}
|
||||
|
||||
} else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) {
|
||||
/* Try and find signal information in the payload */
|
||||
if ((signal_ptr = switch_stristr("Signal=", sip->sip_payload->pl_data))) {
|
||||
int tmp;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -571,22 +571,22 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
||||
switch_safe_free(sql);
|
||||
|
||||
|
||||
sql = switch_mprintf("select sip_registrations.sip_user, sip_registrations.orig_server_host, sip_registrations.status, "
|
||||
sql = switch_mprintf("select sip_registrations.sip_user, sip_registrations.orig_hostname, sip_registrations.status, "
|
||||
"sip_registrations.rpid,'', sip_dialogs.uuid, sip_dialogs.state, sip_dialogs.direction, "
|
||||
"sip_dialogs.sip_to_user, sip_dialogs.sip_to_host, sip_presence.status,sip_presence.rpid,sip_presence.open_closed,"
|
||||
"'%q','%q' "
|
||||
|
||||
"from sip_registrations left join sip_dialogs on "
|
||||
"(sip_dialogs.sip_from_user = sip_registrations.sip_user "
|
||||
"and (sip_dialogs.sip_from_host = sip_registrations.orig_server_host or "
|
||||
"and (sip_dialogs.sip_from_host = sip_registrations.orig_hostname or "
|
||||
"sip_dialogs.sip_from_host = sip_registrations.sip_host) ) "
|
||||
|
||||
|
||||
"left join sip_presence on "
|
||||
"(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_server_host=sip_presence.sip_host and "
|
||||
"(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_hostname=sip_presence.sip_host and "
|
||||
"sip_registrations.profile_name=sip_presence.profile_name) "
|
||||
"where sip_registrations.sip_user='%q' and "
|
||||
"(sip_registrations.orig_server_host='%q' or sip_registrations.sip_host='%q' "
|
||||
"(sip_registrations.orig_hostname='%q' or sip_registrations.sip_host='%q' "
|
||||
"or sip_registrations.presence_hosts like '%%%q%%')",
|
||||
dh.status, dh.rpid, probe_euser, probe_host, probe_host, probe_host);
|
||||
switch_assert(sql);
|
||||
@@ -700,7 +700,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
||||
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
|
||||
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
|
||||
"sip_subscriptions.accept,sip_subscriptions.profile_name"
|
||||
",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q' "
|
||||
",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q',sip_subscriptions.version "
|
||||
"from sip_subscriptions "
|
||||
"left join sip_presence on "
|
||||
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
||||
@@ -743,6 +743,15 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
||||
|
||||
sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_presence_sub_callback, &helper);
|
||||
|
||||
|
||||
sql = switch_mprintf("update sip_subscriptions set version=version+1 where event='dialog' and sub_to_user='%q' "
|
||||
"and (sub_to_host='%q' or presence_hosts like '%%%q%%') "
|
||||
"and (profile_name = '%q' or presence_hosts != sub_to_host)",
|
||||
euser, host, host, profile->name);
|
||||
|
||||
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
||||
|
||||
|
||||
if (mod_sofia_globals.debug_presence > 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_SQL (%s)\n",
|
||||
event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
|
||||
@@ -1193,7 +1202,8 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
int kill_handle = 0;
|
||||
char expires_str[10] = "";
|
||||
char status_line[256] = "";
|
||||
|
||||
char *version = "0";
|
||||
|
||||
//int i;
|
||||
|
||||
//for(i = 0; i < argc; i++) {
|
||||
@@ -1213,6 +1223,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
if (argc > 20) {
|
||||
dialog_status = argv[20];
|
||||
dialog_rpid = argv[21];
|
||||
version = argv[22];
|
||||
}
|
||||
|
||||
in = helper->event && helper->event->event_id == SWITCH_EVENT_PRESENCE_IN;
|
||||
@@ -1317,8 +1328,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
}
|
||||
|
||||
if (is_dialog) {
|
||||
char *version = switch_event_get_header(helper->event, "event_count");
|
||||
if (!version) {
|
||||
if (zstr(version)) {
|
||||
version = "0";
|
||||
}
|
||||
|
||||
@@ -1983,12 +1993,20 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
is_nat = NULL;
|
||||
}
|
||||
|
||||
if (zstr(contact_host)) {
|
||||
is_nat = "No contact host";
|
||||
}
|
||||
|
||||
if (is_nat) {
|
||||
contact_host = network_ip;
|
||||
switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
|
||||
port = NULL;
|
||||
}
|
||||
|
||||
if (zstr(contact_host)) {
|
||||
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
|
||||
return;
|
||||
}
|
||||
|
||||
if (port) {
|
||||
switch_snprintf(new_port, sizeof(new_port), ":%s", port);
|
||||
|
||||
@@ -820,9 +820,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
switch_event_t *auth_params = NULL;
|
||||
int r = 0;
|
||||
long reg_count = 0;
|
||||
int delete_subs = 1;
|
||||
int delete_subs;
|
||||
const char *agent = "unknown";
|
||||
|
||||
delete_subs = sofia_test_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
|
||||
|
||||
/* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
|
||||
switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
|
||||
@@ -841,10 +842,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
|
||||
if (sip->sip_user_agent) {
|
||||
agent = sip->sip_user_agent->g_string;
|
||||
|
||||
if (switch_stristr("snom", agent)) {
|
||||
delete_subs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (from) {
|
||||
@@ -934,7 +931,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
|
||||
if (sip->sip_path) {
|
||||
path_val = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_path);
|
||||
path_encoded_len = (strlen(path_val) * 3) + 1;
|
||||
path_encoded_len = (int)(strlen(path_val) * 3) + 1;
|
||||
switch_zmalloc(path_encoded, path_encoded_len);
|
||||
switch_copy_string(path_encoded, ";fs_path=", 10);
|
||||
switch_url_encode(path_val, path_encoded + 9, path_encoded_len - 9);
|
||||
@@ -947,7 +944,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
||||
switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d", contact->m_url->url_user, url_ip, network_port);
|
||||
}
|
||||
|
||||
path_encoded_len = (strlen(my_contact_str) * 3) + 1;
|
||||
path_encoded_len = (int)(strlen(my_contact_str) * 3) + 1;
|
||||
|
||||
switch_zmalloc(path_encoded, path_encoded_len);
|
||||
switch_copy_string(path_encoded, ";fs_path=", 10);
|
||||
@@ -2126,7 +2123,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
|
||||
|
||||
if (auth_acl) {
|
||||
if (!switch_check_network_list_ip(ip, auth_acl)) {
|
||||
int network_ip_is_proxy = 0, x = 0;
|
||||
int network_ip_is_proxy = 0;
|
||||
uint32_t x = 0;
|
||||
char *last_acl = NULL;
|
||||
if (profile->proxy_acl_count == 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by user acl [%s] and no proxy acl present\n", ip, auth_acl);
|
||||
@@ -2223,7 +2221,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
|
||||
if (max_registrations_perext > 0 && (sip && sip->sip_contact && (sip->sip_contact->m_expires == NULL || atol(sip->sip_contact->m_expires) > 0))) {
|
||||
/* if expires is null still process */
|
||||
/* expires == 0 means the phone is going to unregiser, so don't count against max */
|
||||
int count = 0;
|
||||
uint32_t count = 0;
|
||||
|
||||
call_id = sip->sip_call_id->i_id;
|
||||
switch_assert(call_id);
|
||||
@@ -2498,7 +2496,7 @@ sofia_gateway_t *sofia_reg_find_gateway_by_realm__(const char *file, const char
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
for (hi = switch_hash_first(NULL, mod_sofia_globals.gateway_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
if ((gateway = (sofia_gateway_t *) val) && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) {
|
||||
if (key && (gateway = (sofia_gateway_t *) val) && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) {
|
||||
break;
|
||||
} else {
|
||||
gateway = NULL;
|
||||
|
||||
Reference in new issue
Block a user