File: | src/mod/endpoints/mod_skinny/skinny_server.c |
Location: | line 2508, column 3 |
Description: | Assigned value is garbage or undefined |
1 | /* | |||
2 | * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application | |||
3 | * Copyright (C) 2010, Mathieu Parent <math.parent@gmail.com> | |||
4 | * | |||
5 | * Version: MPL 1.1 | |||
6 | * | |||
7 | * The contents of this file are subject to the Mozilla Public License Version | |||
8 | * 1.1 (the "License"); you may not use this file except in compliance with | |||
9 | * the License. You may obtain a copy of the License at | |||
10 | * http://www.mozilla.org/MPL/ | |||
11 | * | |||
12 | * Software distributed under the License is distributed on an "AS IS" basis, | |||
13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |||
14 | * for the specific language governing rights and limitations under the | |||
15 | * License. | |||
16 | * | |||
17 | * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application | |||
18 | * | |||
19 | * The Initial Developer of the Original Code is | |||
20 | * Mathieu Parent <math.parent@gmail.com> | |||
21 | * Portions created by the Initial Developer are Copyright (C) | |||
22 | * the Initial Developer. All Rights Reserved. | |||
23 | * | |||
24 | * Contributor(s): | |||
25 | * | |||
26 | * Mathieu Parent <math.parent@gmail.com> | |||
27 | * | |||
28 | * | |||
29 | * skinny_server.c -- Skinny Call Control Protocol (SCCP) Endpoint Module | |||
30 | * | |||
31 | */ | |||
32 | #include <switch.h> | |||
33 | #include "mod_skinny.h" | |||
34 | #include "skinny_protocol.h" | |||
35 | #include "skinny_tables.h" | |||
36 | #include "skinny_server.h" | |||
37 | ||||
38 | uint32_t soft_key_template_default_textids[] = { | |||
39 | SKINNY_TEXTID_REDIAL, | |||
40 | SKINNY_TEXTID_NEWCALL, | |||
41 | SKINNY_TEXTID_HOLD, | |||
42 | SKINNY_TEXTID_TRANSFER, | |||
43 | SKINNY_TEXTID_CFWDALL, | |||
44 | SKINNY_TEXTID_CFWDBUSY, | |||
45 | SKINNY_TEXTID_CFWDNOANSWER, | |||
46 | SKINNY_TEXTID_BACKSPACE, | |||
47 | SKINNY_TEXTID_ENDCALL, | |||
48 | SKINNY_TEXTID_RESUME, | |||
49 | SKINNY_TEXTID_ANSWER, | |||
50 | SKINNY_TEXTID_INFO, | |||
51 | SKINNY_TEXTID_CONF, | |||
52 | SKINNY_TEXTID_PARK, | |||
53 | SKINNY_TEXTID_JOIN, | |||
54 | SKINNY_TEXTID_MEETME, | |||
55 | SKINNY_TEXTID_CALLPICKUP, | |||
56 | SKINNY_TEXTID_GRPCALLPICKUP, | |||
57 | SKINNY_TEXTID_DND, | |||
58 | SKINNY_TEXTID_IDIVERT | |||
59 | }; | |||
60 | ||||
61 | uint32_t soft_key_template_default_events[] = { | |||
62 | SOFTKEY_REDIAL, | |||
63 | SOFTKEY_NEWCALL, | |||
64 | SOFTKEY_HOLD, | |||
65 | SOFTKEY_TRANSFER, | |||
66 | SOFTKEY_CFWDALL, | |||
67 | SOFTKEY_CFWDBUSY, | |||
68 | SOFTKEY_CFWDNOANSWER, | |||
69 | SOFTKEY_BACKSPACE, | |||
70 | SOFTKEY_ENDCALL, | |||
71 | SOFTKEY_RESUME, | |||
72 | SOFTKEY_ANSWER, | |||
73 | SOFTKEY_INFO, | |||
74 | SOFTKEY_CONF, | |||
75 | SOFTKEY_PARK, | |||
76 | SOFTKEY_JOIN, | |||
77 | SOFTKEY_MEETME, | |||
78 | SOFTKEY_CALLPICKUP, | |||
79 | SOFTKEY_GRPCALLPICKUP, | |||
80 | SOFTKEY_DND, | |||
81 | SOFTKEY_IDIVERT | |||
82 | }; | |||
83 | ||||
84 | /*****************************************************************************/ | |||
85 | /* SESSION FUNCTIONS */ | |||
86 | /*****************************************************************************/ | |||
87 | switch_status_t skinny_create_incoming_session(listener_t *listener, uint32_t *line_instance_p, switch_core_session_t **session) | |||
88 | { | |||
89 | uint32_t line_instance; | |||
90 | switch_core_session_t *nsession; | |||
91 | switch_channel_t *channel; | |||
92 | private_t *tech_pvt; | |||
93 | char name[128]; | |||
94 | char *sql; | |||
95 | struct line_stat_res_message *button = NULL((void*)0); | |||
96 | ||||
97 | line_instance = *line_instance_p; | |||
98 | if((nsession = skinny_profile_find_session(listener->profile, listener, line_instance_p, 0))) { | |||
99 | if(skinny_line_get_state(listener, *line_instance_p, 0) == SKINNY_OFF_HOOK) { | |||
100 | /* Reuse existing session */ | |||
101 | *session = nsession; | |||
102 | return SWITCH_STATUS_SUCCESS; | |||
103 | } | |||
104 | switch_core_session_rwunlock(nsession); | |||
105 | } | |||
106 | *line_instance_p = line_instance; | |||
107 | if(*line_instance_p == 0) { | |||
108 | *line_instance_p = 1; | |||
109 | } | |||
110 | ||||
111 | skinny_hold_active_calls(listener); | |||
112 | ||||
113 | skinny_line_get(listener, *line_instance_p, &button); | |||
114 | ||||
115 | if (!button || !button->shortname[0]) { | |||
116 | skinny_log_l(listener, SWITCH_LOG_CRIT, "Line %d not found on device\n", *line_instance_p)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 116, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Line %d not found on device\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port, *line_instance_p); | |||
117 | goto error; | |||
118 | } | |||
119 | ||||
120 | if (!(nsession = switch_core_session_request(skinny_get_endpoint_interface(),switch_core_session_request_uuid(skinny_get_endpoint_interface (), SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, ((void*)0), ((void *)0)) | |||
121 | SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL)switch_core_session_request_uuid(skinny_get_endpoint_interface (), SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, ((void*)0), ((void *)0)))) { | |||
122 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Error Creating Session\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 122, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Error Creating Session\n", (_zstr(listener->device_name) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port); | |||
123 | goto error; | |||
124 | } | |||
125 | ||||
126 | if (!(tech_pvt = (struct private_object *) switch_core_session_alloc(nsession, sizeof(*tech_pvt))switch_core_perform_session_alloc(nsession, sizeof(*tech_pvt) , "skinny_server.c", (const char *)__func__, 126))) { | |||
127 | skinny_log_ls_msg(listener, nsession, SWITCH_LOG_CRIT, "Error Creating Session private object\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 127, (const char*)(nsession), SWITCH_LOG_CRIT , "[%s:%d @ %s:%d] " "Error Creating Session private object\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
128 | goto error; | |||
129 | } | |||
130 | ||||
131 | switch_core_session_add_stream(nsession, NULL((void*)0)); | |||
132 | ||||
133 | tech_init(tech_pvt, listener->profile, nsession); | |||
134 | ||||
135 | channel = switch_core_session_get_channel(nsession); | |||
136 | ||||
137 | snprintf(name, sizeof(name), "SKINNY/%s/%s:%d/%d", listener->profile->name, | |||
138 | listener->device_name, listener->device_instance, *line_instance_p); | |||
139 | switch_channel_set_name(channel, name); | |||
140 | ||||
141 | if (switch_core_session_thread_launch(nsession) != SWITCH_STATUS_SUCCESS) { | |||
142 | skinny_log_ls_msg(listener, nsession, SWITCH_LOG_CRIT, "Error Creating Session thread\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 142, (const char*)(nsession), SWITCH_LOG_CRIT , "[%s:%d @ %s:%d] " "Error Creating Session thread\n", (_zstr (listener->device_name) ? "_undef_" : listener->device_name ), listener->device_instance, (_zstr(listener->remote_ip ) ? "_undef_" : listener->remote_ip), listener->remote_port ); | |||
143 | goto error; | |||
144 | } | |||
145 | if (switch_core_session_read_lock(nsession) != SWITCH_STATUS_SUCCESS) { | |||
146 | skinny_log_ls_msg(listener, nsession, SWITCH_LOG_CRIT, "Error Locking Session\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 146, (const char*)(nsession), SWITCH_LOG_CRIT , "[%s:%d @ %s:%d] " "Error Locking Session\n", (_zstr(listener ->device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port); | |||
147 | goto error; | |||
148 | } | |||
149 | /* First create the caller profile in the patterns Dialplan */ | |||
150 | if (!(tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(nsession), | |||
151 | NULL((void*)0), listener->profile->patterns_dialplan, | |||
152 | button->displayname, button->shortname, | |||
153 | listener->remote_ip, NULL((void*)0), NULL((void*)0), NULL((void*)0), | |||
154 | "skinny" /* modname */, | |||
155 | listener->profile->patterns_context, | |||
156 | "")) != 0) { | |||
157 | skinny_log_ls_msg(listener, nsession, SWITCH_LOG_CRIT, "Error Creating Session caller profile\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 157, (const char*)(nsession), SWITCH_LOG_CRIT , "[%s:%d @ %s:%d] " "Error Creating Session caller profile\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
158 | goto error; | |||
159 | } | |||
160 | ||||
161 | switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); | |||
162 | ||||
163 | if ((sql = switch_mprintf( | |||
164 | "INSERT INTO skinny_active_lines " | |||
165 | "(device_name, device_instance, line_instance, channel_uuid, call_id, call_state) " | |||
166 | "SELECT device_name, device_instance, line_instance, '%q', %d, %d " | |||
167 | "FROM skinny_lines " | |||
168 | "WHERE value='%q'", | |||
169 | switch_core_session_get_uuid(nsession), tech_pvt->call_id, SKINNY_ON_HOOK, button->shortname | |||
170 | ))) { | |||
171 | skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); | |||
172 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
173 | } | |||
174 | skinny_session_set_variables(nsession, listener, *line_instance_p); | |||
175 | ||||
176 | send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, *line_instance_p, tech_pvt->call_id)perform_send_set_ringer(listener, "skinny_server.c", (const char *)__func__, 176, SKINNY_RING_OFF, SKINNY_RING_FOREVER, *line_instance_p , tech_pvt->call_id); | |||
177 | send_set_speaker_mode(listener, SKINNY_SPEAKER_ON)perform_send_set_speaker_mode(listener, "skinny_server.c", (const char *)__func__, 177, SKINNY_SPEAKER_ON); | |||
178 | send_set_lamp(listener, SKINNY_BUTTON_LINE, *line_instance_p, SKINNY_LAMP_ON)perform_send_set_lamp(listener, "skinny_server.c", (const char *)__func__, 178, SKINNY_BUTTON_LINE, *line_instance_p, SKINNY_LAMP_ON ); | |||
179 | skinny_line_set_state(listener, *line_instance_p, tech_pvt->call_id, SKINNY_OFF_HOOK)skinny_line_perform_set_state("skinny_server.c", (const char * )__func__, 179, listener, *line_instance_p, tech_pvt->call_id , SKINNY_OFF_HOOK); | |||
180 | send_select_soft_keys(listener, *line_instance_p, tech_pvt->call_id, SKINNY_KEY_SET_OFF_HOOK, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 180, *line_instance_p, tech_pvt->call_id , SKINNY_KEY_SET_OFF_HOOK, 0xffff); | |||
181 | ||||
182 | send_display_prompt_status_textid(listener, 0, SKINNY_TEXTID_ENTER_NUMBER, *line_instance_p, tech_pvt->call_id)perform_send_display_prompt_status_textid(listener, "skinny_server.c" , (const char *)__func__, 182, 0, SKINNY_TEXTID_ENTER_NUMBER, *line_instance_p, tech_pvt->call_id); | |||
183 | ||||
184 | send_activate_call_plane(listener, *line_instance_p)perform_send_activate_call_plane(listener, "skinny_server.c", (const char *)__func__, 184, *line_instance_p); | |||
185 | if (switch_channel_get_state(channel) == CS_NEW) { | |||
186 | switch_channel_set_state(channel, CS_HIBERNATE)switch_channel_perform_set_state(channel, "skinny_server.c", ( const char *)__func__, 186, CS_HIBERNATE); | |||
187 | } else { | |||
188 | skinny_log_ls_msg(listener, nsession, SWITCH_LOG_CRIT,switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 189, (const char*)(nsession), SWITCH_LOG_CRIT , "[%s:%d @ %s:%d] " "Wow! this channel should be in CS_NEW state, but it is not!\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port) | |||
189 | "Wow! this channel should be in CS_NEW state, but it is not!\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 189, (const char*)(nsession), SWITCH_LOG_CRIT , "[%s:%d @ %s:%d] " "Wow! this channel should be in CS_NEW state, but it is not!\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
190 | } | |||
191 | ||||
192 | goto done; | |||
193 | error: | |||
194 | skinny_log_l(listener, SWITCH_LOG_CRIT, "Failed to create incoming session for line instance %d", *line_instance_p)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 194, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Failed to create incoming session for line instance %d", (_zstr (listener->device_name) ? "_undef_" : listener->device_name ), listener->device_instance, (_zstr(listener->remote_ip ) ? "_undef_" : listener->remote_ip), listener->remote_port , *line_instance_p); | |||
195 | if (nsession) { | |||
196 | switch_core_session_destroy(&nsession)switch_core_session_perform_destroy(&nsession, "skinny_server.c" , (const char *)__func__, 196); | |||
197 | } | |||
198 | ||||
199 | listener->profile->ib_failed_calls++; | |||
200 | return SWITCH_STATUS_FALSE; | |||
201 | ||||
202 | done: | |||
203 | *session = nsession; | |||
204 | listener->profile->ib_calls++; | |||
205 | return SWITCH_STATUS_SUCCESS; | |||
206 | } | |||
207 | ||||
208 | skinny_action_t skinny_session_dest_match_pattern(switch_core_session_t *session, char **data) | |||
209 | { | |||
210 | skinny_action_t action = SKINNY_ACTION_DROP; | |||
211 | switch_channel_t *channel = NULL((void*)0); | |||
212 | private_t *tech_pvt = NULL((void*)0); | |||
213 | ||||
214 | switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "skinny_server.c" , 214, __PRETTY_FUNCTION__)); | |||
215 | ||||
216 | channel = switch_core_session_get_channel(session); | |||
217 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
218 | ||||
219 | /* this part of the code is similar to switch_core_standard_on_routing() */ | |||
220 | if (!zstr(tech_pvt->profile->patterns_dialplan)_zstr(tech_pvt->profile->patterns_dialplan)) { | |||
221 | switch_dialplan_interface_t *dialplan_interface = NULL((void*)0); | |||
222 | switch_caller_extension_t *extension = NULL((void*)0); | |||
223 | char *expanded = NULL((void*)0); | |||
224 | char *dpstr = NULL((void*)0); | |||
225 | char *dp[25]; | |||
226 | int argc, x; | |||
227 | ||||
228 | if ((dpstr = switch_core_session_strdup(session, tech_pvt->profile->patterns_dialplan)switch_core_perform_session_strdup(session, tech_pvt->profile ->patterns_dialplan, "skinny_server.c", (const char *)__func__ , 228))) { | |||
229 | expanded = switch_channel_expand_variables(channel, dpstr)switch_channel_expand_variables_check(channel, dpstr, ((void* )0), ((void*)0), 0); | |||
230 | argc = switch_separate_string(expanded, ',', dp, (sizeof(dp) / sizeof(dp[0]))); | |||
231 | for (x = 0; x < argc; x++) { | |||
232 | char *dpname = dp[x]; | |||
233 | char *dparg = NULL((void*)0); | |||
234 | ||||
235 | if (dpname) { | |||
236 | if ((dparg = strchr(dpname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p (dpname) && (':') == '\0' ? (char *) __rawmemchr (dpname , ':') : __builtin_strchr (dpname, ':'))))) { | |||
237 | *dparg++ = '\0'; | |||
238 | } | |||
239 | } else { | |||
240 | continue; | |||
241 | } | |||
242 | if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) { | |||
243 | continue; | |||
244 | } | |||
245 | ||||
246 | extension = dialplan_interface->hunt_function(session, dparg, NULL((void*)0)); | |||
247 | UNPROTECT_INTERFACE(dialplan_interface)if (dialplan_interface) {switch_mutex_lock(dialplan_interface ->reflock); switch_thread_rwlock_unlock(dialplan_interface ->rwlock); switch_thread_rwlock_unlock(dialplan_interface-> parent->rwlock); dialplan_interface->refs--; dialplan_interface ->parent->refs--; switch_mutex_unlock(dialplan_interface ->reflock);}; | |||
248 | ||||
249 | if (extension) { | |||
250 | goto found; | |||
251 | } | |||
252 | } | |||
253 | } | |||
254 | found: | |||
255 | while (extension && extension->current_application) { | |||
256 | switch_caller_application_t *current_application = extension->current_application; | |||
257 | ||||
258 | extension->current_application = extension->current_application->next; | |||
259 | ||||
260 | if (!strcmp(current_application->application_name, "skinny-route")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (current_application->application_name) && __builtin_constant_p ("skinny-route") && (__s1_len = __builtin_strlen (current_application ->application_name), __s2_len = __builtin_strlen ("skinny-route" ), (!((size_t)(const void *)((current_application->application_name ) + 1) - (size_t)(const void *)(current_application->application_name ) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("skinny-route") + 1) - (size_t)(const void *)("skinny-route" ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (current_application ->application_name, "skinny-route") : (__builtin_constant_p (current_application->application_name) && ((size_t )(const void *)((current_application->application_name) + 1 ) - (size_t)(const void *)(current_application->application_name ) == 1) && (__s1_len = __builtin_strlen (current_application ->application_name), __s1_len < 4) ? (__builtin_constant_p ("skinny-route") && ((size_t)(const void *)(("skinny-route" ) + 1) - (size_t)(const void *)("skinny-route") == 1) ? __builtin_strcmp (current_application->application_name, "skinny-route") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("skinny-route"); int __result = (((const unsigned char *) (const char *) (current_application->application_name ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (current_application ->application_name))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (current_application->application_name))[2] - __s2 [2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (current_application ->application_name))[3] - __s2[3]); } } __result; }))) : ( __builtin_constant_p ("skinny-route") && ((size_t)(const void *)(("skinny-route") + 1) - (size_t)(const void *)("skinny-route" ) == 1) && (__s2_len = __builtin_strlen ("skinny-route" ), __s2_len < 4) ? (__builtin_constant_p (current_application ->application_name) && ((size_t)(const void *)((current_application ->application_name) + 1) - (size_t)(const void *)(current_application ->application_name) == 1) ? __builtin_strcmp (current_application ->application_name, "skinny-route") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (current_application->application_name); int __result = (((const unsigned char *) (const char *) ("skinny-route"))[0 ] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("skinny-route" ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("skinny-route" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("skinny-route" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (current_application ->application_name, "skinny-route")))); }) || !strcmp(current_application->application_name, "skinny-process")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (current_application->application_name) && __builtin_constant_p ("skinny-process") && (__s1_len = __builtin_strlen ( current_application->application_name), __s2_len = __builtin_strlen ("skinny-process"), (!((size_t)(const void *)((current_application ->application_name) + 1) - (size_t)(const void *)(current_application ->application_name) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("skinny-process") + 1) - (size_t)(const void *)("skinny-process") == 1) || __s2_len >= 4)) ? __builtin_strcmp (current_application->application_name, "skinny-process") : (__builtin_constant_p (current_application->application_name ) && ((size_t)(const void *)((current_application-> application_name) + 1) - (size_t)(const void *)(current_application ->application_name) == 1) && (__s1_len = __builtin_strlen (current_application->application_name), __s1_len < 4) ? (__builtin_constant_p ("skinny-process") && ((size_t )(const void *)(("skinny-process") + 1) - (size_t)(const void *)("skinny-process") == 1) ? __builtin_strcmp (current_application ->application_name, "skinny-process") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("skinny-process"); int __result = (((const unsigned char *) (const char *) (current_application->application_name))[0 ] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (current_application ->application_name))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (current_application->application_name))[2] - __s2 [2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (current_application ->application_name))[3] - __s2[3]); } } __result; }))) : ( __builtin_constant_p ("skinny-process") && ((size_t)( const void *)(("skinny-process") + 1) - (size_t)(const void * )("skinny-process") == 1) && (__s2_len = __builtin_strlen ("skinny-process"), __s2_len < 4) ? (__builtin_constant_p (current_application->application_name) && ((size_t )(const void *)((current_application->application_name) + 1 ) - (size_t)(const void *)(current_application->application_name ) == 1) ? __builtin_strcmp (current_application->application_name , "skinny-process") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (current_application ->application_name); int __result = (((const unsigned char *) (const char *) ("skinny-process"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("skinny-process"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("skinny-process"))[2] - __s2 [2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("skinny-process")) [3] - __s2[3]); } } __result; })))) : __builtin_strcmp (current_application ->application_name, "skinny-process")))); })) { | |||
261 | action = SKINNY_ACTION_PROCESS; | |||
262 | } else if (!strcmp(current_application->application_name, "skinny-drop")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (current_application->application_name) && __builtin_constant_p ("skinny-drop") && (__s1_len = __builtin_strlen (current_application ->application_name), __s2_len = __builtin_strlen ("skinny-drop" ), (!((size_t)(const void *)((current_application->application_name ) + 1) - (size_t)(const void *)(current_application->application_name ) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("skinny-drop") + 1) - (size_t)(const void *)("skinny-drop" ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (current_application ->application_name, "skinny-drop") : (__builtin_constant_p (current_application->application_name) && ((size_t )(const void *)((current_application->application_name) + 1 ) - (size_t)(const void *)(current_application->application_name ) == 1) && (__s1_len = __builtin_strlen (current_application ->application_name), __s1_len < 4) ? (__builtin_constant_p ("skinny-drop") && ((size_t)(const void *)(("skinny-drop" ) + 1) - (size_t)(const void *)("skinny-drop") == 1) ? __builtin_strcmp (current_application->application_name, "skinny-drop") : ( __extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("skinny-drop"); int __result = (((const unsigned char *) (const char *) (current_application->application_name ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (current_application ->application_name))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (current_application->application_name))[2] - __s2 [2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (current_application ->application_name))[3] - __s2[3]); } } __result; }))) : ( __builtin_constant_p ("skinny-drop") && ((size_t)(const void *)(("skinny-drop") + 1) - (size_t)(const void *)("skinny-drop" ) == 1) && (__s2_len = __builtin_strlen ("skinny-drop" ), __s2_len < 4) ? (__builtin_constant_p (current_application ->application_name) && ((size_t)(const void *)((current_application ->application_name) + 1) - (size_t)(const void *)(current_application ->application_name) == 1) ? __builtin_strcmp (current_application ->application_name, "skinny-drop") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (current_application->application_name); int __result = ( ((const unsigned char *) (const char *) ("skinny-drop"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("skinny-drop"))[ 1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("skinny-drop" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("skinny-drop" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (current_application ->application_name, "skinny-drop")))); })) { | |||
263 | action = SKINNY_ACTION_DROP; | |||
264 | } else if (!strcmp(current_application->application_name, "skinny-wait")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (current_application->application_name) && __builtin_constant_p ("skinny-wait") && (__s1_len = __builtin_strlen (current_application ->application_name), __s2_len = __builtin_strlen ("skinny-wait" ), (!((size_t)(const void *)((current_application->application_name ) + 1) - (size_t)(const void *)(current_application->application_name ) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("skinny-wait") + 1) - (size_t)(const void *)("skinny-wait" ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (current_application ->application_name, "skinny-wait") : (__builtin_constant_p (current_application->application_name) && ((size_t )(const void *)((current_application->application_name) + 1 ) - (size_t)(const void *)(current_application->application_name ) == 1) && (__s1_len = __builtin_strlen (current_application ->application_name), __s1_len < 4) ? (__builtin_constant_p ("skinny-wait") && ((size_t)(const void *)(("skinny-wait" ) + 1) - (size_t)(const void *)("skinny-wait") == 1) ? __builtin_strcmp (current_application->application_name, "skinny-wait") : ( __extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("skinny-wait"); int __result = (((const unsigned char *) (const char *) (current_application->application_name ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (current_application ->application_name))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (current_application->application_name))[2] - __s2 [2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (current_application ->application_name))[3] - __s2[3]); } } __result; }))) : ( __builtin_constant_p ("skinny-wait") && ((size_t)(const void *)(("skinny-wait") + 1) - (size_t)(const void *)("skinny-wait" ) == 1) && (__s2_len = __builtin_strlen ("skinny-wait" ), __s2_len < 4) ? (__builtin_constant_p (current_application ->application_name) && ((size_t)(const void *)((current_application ->application_name) + 1) - (size_t)(const void *)(current_application ->application_name) == 1) ? __builtin_strcmp (current_application ->application_name, "skinny-wait") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (current_application->application_name); int __result = ( ((const unsigned char *) (const char *) ("skinny-wait"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("skinny-wait"))[ 1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("skinny-wait" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("skinny-wait" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (current_application ->application_name, "skinny-wait")))); })) { | |||
265 | action = SKINNY_ACTION_WAIT; | |||
266 | *data = switch_core_session_strdup(session, current_application->application_data)switch_core_perform_session_strdup(session, current_application ->application_data, "skinny_server.c", (const char *)__func__ , 266); | |||
267 | } else { | |||
268 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 268, (const char*)(session), SWITCH_LOG_WARNING, | |||
269 | "Unknown skinny dialplan application %s\n", current_application->application_name); | |||
270 | } | |||
271 | } | |||
272 | } | |||
273 | return action; | |||
274 | } | |||
275 | ||||
276 | ||||
277 | 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) | |||
278 | { | |||
279 | switch_channel_t *channel = NULL((void*)0); | |||
280 | private_t *tech_pvt = NULL((void*)0); | |||
281 | ||||
282 | switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "skinny_server.c" , 282, __PRETTY_FUNCTION__)); | |||
283 | switch_assert(listener)((listener) ? (void) (0) : __assert_fail ("listener", "skinny_server.c" , 283, __PRETTY_FUNCTION__)); | |||
284 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 284, __PRETTY_FUNCTION__)); | |||
285 | ||||
286 | channel = switch_core_session_get_channel(session); | |||
287 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
288 | ||||
289 | // get listener profile setting for ringdown/autodial | |||
290 | // if initial offhook - and we have a ringdown/autodial configured, just dial it in one shot | |||
291 | if (!dest && append_dest == '\0' && listener->ext_autodial ) { | |||
292 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 292, (const char*)(session), SWITCH_LOG_WARNING, | |||
293 | "triggering auto dial to (%s)\n", listener->ext_autodial); | |||
294 | ||||
295 | tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool, listener->ext_autodial)switch_core_perform_strdup(tech_pvt->caller_profile->pool , listener->ext_autodial, "skinny_server.c", (const char * )__func__, 295); | |||
296 | switch_set_flag_locked(tech_pvt, TFLAG_FORCE_ROUTE)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt->flag_mutex != ((void*)0)", "skinny_server.c", 296, __PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex );(tech_pvt)->flags |= (TFLAG_FORCE_ROUTE);switch_mutex_unlock (tech_pvt->flag_mutex);; | |||
297 | } else if (!dest) { | |||
298 | if (strlen(tech_pvt->caller_profile->destination_number) == 0) {/* no digit yet */ | |||
299 | send_start_tone(listener, SKINNY_TONE_DIALTONE, 0, line_instance, tech_pvt->call_id)perform_send_start_tone(listener, "skinny_server.c", (const char *)__func__, 299, SKINNY_TONE_DIALTONE, 0, line_instance, tech_pvt ->call_id); | |||
300 | } | |||
301 | if (backspace && strlen(tech_pvt->caller_profile->destination_number)) { /* backspace */ | |||
302 | tech_pvt->caller_profile->destination_number[strlen(tech_pvt->caller_profile->destination_number)-1] = '\0'; | |||
303 | if (strlen(tech_pvt->caller_profile->destination_number) == 0) { | |||
304 | send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_OFF_HOOK, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 304, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_OFF_HOOK , 0xffff); | |||
305 | } | |||
306 | send_back_space_request(listener, line_instance, tech_pvt->call_id)perform_send_back_space_request(listener, "skinny_server.c", ( const char *)__func__, 306, line_instance, tech_pvt->call_id ); | |||
307 | } | |||
308 | if (append_dest != '\0') {/* append digit */ | |||
309 | tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, | |||
310 | "%s%c", tech_pvt->caller_profile->destination_number, append_dest); | |||
311 | } | |||
312 | if (strlen(tech_pvt->caller_profile->destination_number) == 1) {/* first digit */ | |||
313 | if(!backspace) { | |||
314 | send_stop_tone(listener, line_instance, tech_pvt->call_id)perform_send_stop_tone(listener, "skinny_server.c", (const char *)__func__, 314, line_instance, tech_pvt->call_id); | |||
315 | } | |||
316 | send_select_soft_keys(listener, line_instance, tech_pvt->call_id,perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 317, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT , 0xffff) | |||
317 | SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 317, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT , 0xffff); | |||
318 | } | |||
319 | } else { | |||
320 | tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool, dest)switch_core_perform_strdup(tech_pvt->caller_profile->pool , dest, "skinny_server.c", (const char *)__func__, 320); | |||
321 | switch_set_flag_locked(tech_pvt, TFLAG_FORCE_ROUTE)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt->flag_mutex != ((void*)0)", "skinny_server.c", 321, __PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex );(tech_pvt)->flags |= (TFLAG_FORCE_ROUTE);switch_mutex_unlock (tech_pvt->flag_mutex);; | |||
322 | } | |||
323 | ||||
324 | switch_channel_set_state(channel, CS_ROUTING)switch_channel_perform_set_state(channel, "skinny_server.c", ( const char *)__func__, 324, CS_ROUTING); | |||
325 | ||||
326 | return SWITCH_STATUS_SUCCESS; | |||
327 | } | |||
328 | ||||
329 | switch_status_t skinny_session_send_call_info(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) | |||
330 | { | |||
331 | private_t *tech_pvt; | |||
332 | switch_channel_t *channel; | |||
333 | ||||
334 | const char *caller_party_name; | |||
335 | const char *caller_party_number; | |||
336 | const char *called_party_name; | |||
337 | const char *called_party_number; | |||
338 | uint32_t call_type = 0; | |||
339 | ||||
340 | channel = switch_core_session_get_channel(session); | |||
341 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
342 | ||||
343 | switch_assert(tech_pvt->caller_profile != NULL)((tech_pvt->caller_profile != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt->caller_profile != ((void*)0)", "skinny_server.c" , 343, __PRETTY_FUNCTION__)); | |||
344 | ||||
345 | /* Calling party */ | |||
346 | if (zstr((caller_party_name = switch_channel_get_variable(channel, "effective_caller_id_name")))_zstr((caller_party_name = switch_channel_get_variable_dup(channel , "effective_caller_id_name", SWITCH_TRUE, -1))) && | |||
347 | zstr((caller_party_name = switch_channel_get_variable(channel, "caller_id_name")))_zstr((caller_party_name = switch_channel_get_variable_dup(channel , "caller_id_name", SWITCH_TRUE, -1))) && | |||
348 | zstr((caller_party_name = switch_channel_get_variable_partner(channel, "effective_caller_id_name")))_zstr((caller_party_name = switch_channel_get_variable_partner (channel, "effective_caller_id_name"))) && | |||
349 | zstr((caller_party_name = switch_channel_get_variable_partner(channel, "caller_id_name")))_zstr((caller_party_name = switch_channel_get_variable_partner (channel, "caller_id_name")))) { | |||
350 | caller_party_name = SWITCH_DEFAULT_CLID_NAME""; | |||
351 | } | |||
352 | if (zstr((caller_party_number = switch_channel_get_variable(channel, "effective_caller_id_number")))_zstr((caller_party_number = switch_channel_get_variable_dup( channel, "effective_caller_id_number", SWITCH_TRUE, -1))) && | |||
353 | zstr((caller_party_number = switch_channel_get_variable(channel, "caller_id_number")))_zstr((caller_party_number = switch_channel_get_variable_dup( channel, "caller_id_number", SWITCH_TRUE, -1))) && | |||
354 | zstr((caller_party_number = switch_channel_get_variable_partner(channel, "effective_caller_id_number")))_zstr((caller_party_number = switch_channel_get_variable_partner (channel, "effective_caller_id_number"))) && | |||
355 | zstr((caller_party_number = switch_channel_get_variable_partner(channel, "caller_id_number")))_zstr((caller_party_number = switch_channel_get_variable_partner (channel, "caller_id_number")))) { | |||
356 | caller_party_number = SWITCH_DEFAULT_CLID_NUMBER"0000000000"; | |||
357 | } | |||
358 | /* Called party */ | |||
359 | if (zstr((called_party_name = switch_channel_get_variable(channel, "effective_callee_id_name")))_zstr((called_party_name = switch_channel_get_variable_dup(channel , "effective_callee_id_name", SWITCH_TRUE, -1))) && | |||
360 | zstr((called_party_name = switch_channel_get_variable(channel, "callee_id_name")))_zstr((called_party_name = switch_channel_get_variable_dup(channel , "callee_id_name", SWITCH_TRUE, -1))) && | |||
361 | zstr((called_party_name = switch_channel_get_variable_partner(channel, "effective_callee_id_name")))_zstr((called_party_name = switch_channel_get_variable_partner (channel, "effective_callee_id_name"))) && | |||
362 | zstr((called_party_name = switch_channel_get_variable_partner(channel, "callee_id_name")))_zstr((called_party_name = switch_channel_get_variable_partner (channel, "callee_id_name")))) { | |||
363 | called_party_name = SWITCH_DEFAULT_CLID_NAME""; | |||
364 | } | |||
365 | if (zstr((called_party_number = switch_channel_get_variable(channel, "effective_callee_id_number")))_zstr((called_party_number = switch_channel_get_variable_dup( channel, "effective_callee_id_number", SWITCH_TRUE, -1))) && | |||
366 | zstr((called_party_number = switch_channel_get_variable(channel, "callee_id_number")))_zstr((called_party_number = switch_channel_get_variable_dup( channel, "callee_id_number", SWITCH_TRUE, -1))) && | |||
367 | zstr((called_party_number = switch_channel_get_variable_partner(channel, "effective_callee_id_number")))_zstr((called_party_number = switch_channel_get_variable_partner (channel, "effective_callee_id_number"))) && | |||
368 | zstr((called_party_number = switch_channel_get_variable_partner(channel, "callee_id_number")))_zstr((called_party_number = switch_channel_get_variable_partner (channel, "callee_id_number"))) && | |||
369 | zstr((called_party_number = switch_channel_get_variable(channel, "destination_number")))_zstr((called_party_number = switch_channel_get_variable_dup( channel, "destination_number", SWITCH_TRUE, -1)))) { | |||
370 | called_party_number = SWITCH_DEFAULT_CLID_NUMBER"0000000000"; | |||
371 | } | |||
372 | if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { | |||
373 | call_type = SKINNY_INBOUND_CALL; | |||
374 | } else { | |||
375 | call_type = SKINNY_OUTBOUND_CALL; | |||
376 | } | |||
377 | send_call_info(listener,perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
378 | caller_party_name, /* char calling_party_name[40], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
379 | caller_party_number, /* char calling_party[24], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
380 | called_party_name, /* char called_party_name[40], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
381 | called_party_number, /* char called_party[24], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
382 | line_instance, /* uint32_t line_instance, */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
383 | tech_pvt->call_id, /* uint32_t call_id, */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
384 | call_type, /* uint32_t call_type, */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
385 | "", /* TODO char original_called_party_name[40], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
386 | "", /* TODO char original_called_party[24], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
387 | "", /* TODO char last_redirecting_party_name[40], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
388 | "", /* TODO char last_redirecting_party[24], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
389 | 0, /* TODO uint32_t original_called_party_redirect_reason, */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
390 | 0, /* TODO uint32_t last_redirecting_reason, */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
391 | "", /* TODO char calling_party_voice_mailbox[24], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
392 | "", /* TODO char called_party_voice_mailbox[24], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
393 | "", /* TODO char original_called_party_voice_mailbox[24], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
394 | "", /* TODO char last_redirecting_voice_mailbox[24], */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
395 | 1, /* uint32_t call_instance, */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
396 | 1, /* uint32_t call_security_status, */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
397 | 0 /* uint32_t party_pi_restriction_bits */perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0) | |||
398 | )perform_send_call_info(listener, "skinny_server.c", (const char *)__func__, 398, caller_party_name, caller_party_number, called_party_name , called_party_number, line_instance, tech_pvt->call_id, call_type , "", "", "", "", 0, 0, "", "", "", "", 1, 1, 0); | |||
399 | return SWITCH_STATUS_SUCCESS; | |||
400 | } | |||
401 | ||||
402 | struct skinny_session_send_call_info_all_helper { | |||
403 | private_t *tech_pvt; | |||
404 | }; | |||
405 | ||||
406 | int skinny_session_send_call_info_all_callback(void *pArg, int argc, char **argv, char **columnNames) | |||
407 | { | |||
408 | char *device_name = argv[0]; | |||
409 | uint32_t device_instance = atoi(argv[1]); | |||
410 | /* uint32_t position = atoi(argv[2]); */ | |||
411 | uint32_t line_instance = atoi(argv[3]); | |||
412 | /* char *label = argv[4]; */ | |||
413 | /* char *value = argv[5]; */ | |||
414 | /* char *caller_name = argv[6]; */ | |||
415 | /* uint32_t ring_on_idle = atoi(argv[7]); */ | |||
416 | /* uint32_t ring_on_active = atoi(argv[8]); */ | |||
417 | /* uint32_t busy_trigger = atoi(argv[9]); */ | |||
418 | /* char *forward_all = argv[10]; */ | |||
419 | /* char *forward_busy = argv[11]; */ | |||
420 | /* char *forward_noanswer = argv[12]; */ | |||
421 | /* uint32_t noanswer_duration = atoi(argv[13]); */ | |||
422 | /* char *channel_uuid = argv[14]; */ | |||
423 | /* uint32_t call_id = atoi(argv[15]); */ | |||
424 | /* uint32_t call_state = atoi(argv[16]); */ | |||
425 | ||||
426 | struct skinny_session_send_call_info_all_helper *helper = pArg; | |||
427 | listener_t *listener = NULL((void*)0); | |||
428 | ||||
429 | skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, | |||
430 | device_name, device_instance, &listener); | |||
431 | if(listener) { | |||
432 | skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance); | |||
433 | } | |||
434 | return 0; | |||
435 | } | |||
436 | ||||
437 | switch_status_t skinny_session_send_call_info_all(switch_core_session_t *session) | |||
438 | { | |||
439 | struct skinny_session_send_call_info_all_helper helper = {0}; | |||
440 | private_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
441 | ||||
442 | helper.tech_pvt = tech_pvt; | |||
443 | return skinny_session_walk_lines(tech_pvt->profile, | |||
444 | switch_core_session_get_uuid(tech_pvt->session), skinny_session_send_call_info_all_callback, &helper); | |||
445 | } | |||
446 | ||||
447 | struct skinny_session_set_variables_helper { | |||
448 | private_t *tech_pvt; | |||
449 | switch_channel_t *channel; | |||
450 | listener_t *listener; | |||
451 | uint32_t count; | |||
452 | }; | |||
453 | ||||
454 | int skinny_session_set_variables_callback(void *pArg, int argc, char **argv, char **columnNames) | |||
455 | { | |||
456 | char *device_name = argv[0]; | |||
457 | uint32_t device_instance = atoi(argv[1]); | |||
458 | uint32_t position = atoi(argv[2]); | |||
459 | uint32_t line_instance = atoi(argv[3]); | |||
460 | char *label = argv[4]; | |||
461 | char *value = argv[5]; | |||
462 | char *caller_name = argv[6]; | |||
463 | /* uint32_t ring_on_idle = atoi(argv[7]); */ | |||
464 | /* uint32_t ring_on_active = atoi(argv[8]); */ | |||
465 | /* uint32_t busy_trigger = atoi(argv[9]); */ | |||
466 | /* char *forward_all = argv[10]; */ | |||
467 | /* char *forward_busy = argv[11]; */ | |||
468 | /* char *forward_noanswer = argv[12]; */ | |||
469 | /* uint32_t noanswer_duration = atoi(argv[13]); */ | |||
470 | /* char *channel_uuid = argv[14]; */ | |||
471 | /* uint32_t call_id = atoi(argv[15]); */ | |||
472 | /* uint32_t call_state = atoi(argv[16]); */ | |||
473 | ||||
474 | struct skinny_session_set_variables_helper *helper = pArg; | |||
475 | char *tmp; | |||
476 | listener_t *listener; | |||
477 | ||||
478 | switch_xml_t xroot, xdomain, xuser, xvariables, xvariable; | |||
479 | ||||
480 | helper->count++; | |||
481 | switch_channel_set_variable_name_printf(helper->channel, device_name, "skinny_device_name_%d", helper->count); | |||
482 | if ((tmp = switch_mprintf("%d", device_instance))) { | |||
483 | switch_channel_set_variable_name_printf(helper->channel, tmp, "skinny_device_instance_%d", helper->count); | |||
484 | switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);}; | |||
485 | } | |||
486 | if ((tmp = switch_mprintf("%d", position))) { | |||
487 | switch_channel_set_variable_name_printf(helper->channel, tmp, "skinny_line_position_%d", helper->count); | |||
488 | switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);}; | |||
489 | } | |||
490 | if ((tmp = switch_mprintf("%d", line_instance))) { | |||
491 | switch_channel_set_variable_name_printf(helper->channel, tmp, "skinny_line_instance_%d", helper->count); | |||
492 | switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);}; | |||
493 | } | |||
494 | switch_channel_set_variable_name_printf(helper->channel, label, "skinny_line_label_%d", helper->count); | |||
495 | switch_channel_set_variable_name_printf(helper->channel, value, "skinny_line_value_%d", helper->count); | |||
496 | switch_channel_set_variable_name_printf(helper->channel, caller_name, "skinny_line_caller_name_%d", helper->count); | |||
497 | ||||
498 | listener = helper->listener; | |||
499 | ||||
500 | if ( ! listener ) { | |||
501 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 501, (const char*)(helper->tech_pvt->session), SWITCH_LOG_DEBUG, | |||
502 | "no defined listener on channel var setup, will not attempt to set variables\n"); | |||
503 | return(0); | |||
504 | } | |||
505 | ||||
506 | /* Process through and extract any variables from the user and set in the channel */ | |||
507 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 507, (const char*)(helper->tech_pvt->session), SWITCH_LOG_DEBUG, | |||
508 | "searching for user (id=%s) in profile %s in channel var setup\n", | |||
509 | listener->device_name, listener->profile->domain); | |||
510 | ||||
511 | if (switch_xml_locate_user("id", listener->device_name, listener->profile->domain, "", | |||
512 | &xroot, &xdomain, &xuser, NULL((void*)0), NULL((void*)0)) != SWITCH_STATUS_SUCCESS) { | |||
513 | ||||
514 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 514, (const char*)(helper->tech_pvt->session), SWITCH_LOG_WARNING, | |||
515 | "unable to find user (id=%s) in channel var setup\n", listener->device_name); | |||
516 | } | |||
517 | ||||
518 | if ( xuser ) { | |||
519 | char *uid = (char *) switch_xml_attr_soft(xuser, "id"); | |||
520 | ||||
521 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 521, (const char*)(helper->tech_pvt->session), SWITCH_LOG_DEBUG, | |||
522 | "found user (id=%s) in channel var setup\n", uid); | |||
523 | ||||
524 | if ((xvariables = switch_xml_child(xuser, "variables"))) { | |||
525 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 525, (const char*)(helper->tech_pvt->session), SWITCH_LOG_DEBUG, | |||
526 | "found variables section in user xml"); | |||
527 | ||||
528 | for (xvariable = switch_xml_child(xvariables, "variable"); xvariable; xvariable = xvariable->next) { | |||
529 | char *name = (char *) switch_xml_attr_soft(xvariable, "name"); | |||
530 | char *value = (char *) switch_xml_attr_soft(xvariable, "value"); | |||
531 | ||||
532 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 532, (const char*)(helper->tech_pvt->session), SWITCH_LOG_DEBUG, | |||
533 | "found variable (%s=%s) for user (%s) in channel var setup\n", name, value, listener->device_name); | |||
534 | ||||
535 | switch_channel_set_variable_name_printf(helper->channel, value, "%s", name); | |||
536 | } | |||
537 | } | |||
538 | } | |||
539 | ||||
540 | if ( xroot ) { | |||
541 | switch_xml_free(xroot); | |||
542 | } | |||
543 | ||||
544 | return 0; | |||
545 | } | |||
546 | ||||
547 | switch_status_t skinny_session_set_variables(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) | |||
548 | { | |||
549 | switch_status_t status; | |||
550 | struct skinny_session_set_variables_helper helper = {0}; | |||
551 | ||||
552 | helper.tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
553 | helper.channel = switch_core_session_get_channel(session); | |||
554 | helper.listener = listener; | |||
555 | helper.count = 0; | |||
556 | ||||
557 | switch_channel_set_variable(helper.channel, "skinny_profile_name", helper.tech_pvt->profile->name)switch_channel_set_variable_var_check(helper.channel, "skinny_profile_name" , helper.tech_pvt->profile->name, SWITCH_TRUE); | |||
558 | if (listener) { | |||
559 | switch_channel_set_variable(helper.channel, "skinny_device_name", listener->device_name)switch_channel_set_variable_var_check(helper.channel, "skinny_device_name" , listener->device_name, SWITCH_TRUE); | |||
560 | switch_channel_set_variable_printf(helper.channel, "skinny_device_instance", "%d", listener->device_instance); | |||
561 | switch_channel_set_variable_printf(helper.channel, "skinny_line_instance", "%d", line_instance); | |||
562 | } | |||
563 | status = skinny_session_walk_lines(helper.tech_pvt->profile, | |||
564 | switch_core_session_get_uuid(helper.tech_pvt->session), skinny_session_set_variables_callback, &helper); | |||
565 | ||||
566 | switch_channel_set_variable_printf(helper.channel, "skinny_lines_count", "%d", helper.count); | |||
567 | return status; | |||
568 | } | |||
569 | ||||
570 | struct skinny_ring_lines_helper { | |||
571 | private_t *tech_pvt; | |||
572 | switch_core_session_t *remote_session; | |||
573 | uint32_t lines_count; | |||
574 | }; | |||
575 | ||||
576 | int skinny_ring_lines_callback(void *pArg, int argc, char **argv, char **columnNames) | |||
577 | { | |||
578 | struct skinny_ring_lines_helper *helper = pArg; | |||
579 | char *tmp; | |||
580 | char *label; | |||
581 | ||||
582 | char *device_name = argv[0]; | |||
583 | uint32_t device_instance = atoi(argv[1]); | |||
584 | /* uint32_t position = atoi(argv[2]); */ | |||
585 | uint32_t line_instance = atoi(argv[3]); | |||
586 | /* char *label = argv[4]; */ | |||
587 | char *value = argv[5]; | |||
588 | char *caller_name = argv[6]; | |||
589 | uint32_t ring_on_idle = atoi(argv[7]); | |||
590 | uint32_t ring_on_active = atoi(argv[8]); | |||
591 | /* uint32_t busy_trigger = atoi(argv[9]); */ | |||
592 | /* char *forward_all = argv[10]; */ | |||
593 | /* char *forward_busy = argv[11]; */ | |||
594 | /* char *forward_noanswer = argv[12]; */ | |||
595 | /* uint32_t noanswer_duration = atoi(argv[13]); */ | |||
596 | /* char *channel_uuid = argv[14]; */ | |||
597 | /* uint32_t call_id = atoi(argv[15]); */ | |||
598 | /* uint32_t call_state = atoi(argv[16]); */ | |||
599 | ||||
600 | listener_t *listener = NULL((void*)0); | |||
601 | uint32_t active_calls = 0; | |||
602 | ||||
603 | skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, | |||
604 | device_name, device_instance, &listener); | |||
605 | if(listener && helper->tech_pvt->session && helper->remote_session) { | |||
606 | switch_channel_t *channel = switch_core_session_get_channel(helper->tech_pvt->session); | |||
607 | switch_channel_set_state(channel, CS_ROUTING)switch_channel_perform_set_state(channel, "skinny_server.c", ( const char *)__func__, 607, CS_ROUTING); | |||
608 | helper->lines_count++; | |||
609 | switch_channel_set_variable(channel, "effective_callee_id_number", value)switch_channel_set_variable_var_check(channel, "effective_callee_id_number" , value, SWITCH_TRUE); | |||
610 | switch_channel_set_variable(channel, "effective_callee_id_name", caller_name)switch_channel_set_variable_var_check(channel, "effective_callee_id_name" , caller_name, SWITCH_TRUE); | |||
611 | ||||
612 | active_calls = skinny_line_count_active(listener); | |||
613 | ||||
614 | skinny_log_l(listener, SWITCH_LOG_DEBUG,switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 616, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Ring Lines Callback with Callee Number (%s), Caller Name (%s), Dest Number (%s), Active Calls (%d)\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, value, caller_name, helper->tech_pvt->caller_profile ->destination_number, active_calls) | |||
615 | "Ring Lines Callback with Callee Number (%s), Caller Name (%s), Dest Number (%s), Active Calls (%d)\n",switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 616, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Ring Lines Callback with Callee Number (%s), Caller Name (%s), Dest Number (%s), Active Calls (%d)\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, value, caller_name, helper->tech_pvt->caller_profile ->destination_number, active_calls) | |||
616 | value, caller_name, helper->tech_pvt->caller_profile->destination_number, active_calls)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 616, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Ring Lines Callback with Callee Number (%s), Caller Name (%s), Dest Number (%s), Active Calls (%d)\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, value, caller_name, helper->tech_pvt->caller_profile ->destination_number, active_calls); | |||
617 | ||||
618 | if (helper->remote_session) { | |||
619 | switch_core_session_message_t msg = { 0 }; | |||
620 | msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY; | |||
621 | msg.string_array_arg[0] = switch_core_session_strdup(helper->remote_session, caller_name)switch_core_perform_session_strdup(helper->remote_session, caller_name, "skinny_server.c", (const char *)__func__, 621); | |||
622 | msg.string_array_arg[1] = switch_core_session_strdup(helper->remote_session, value)switch_core_perform_session_strdup(helper->remote_session, value, "skinny_server.c", (const char *)__func__, 622); | |||
623 | msg.from = __FILE__"skinny_server.c"; | |||
624 | ||||
625 | if (switch_core_session_receive_message(helper->remote_session, &msg)switch_core_session_perform_receive_message(helper->remote_session , &msg, "skinny_server.c", (const char *)__func__, 625) != SWITCH_STATUS_SUCCESS) { | |||
626 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 626, (const char*)(helper->tech_pvt->session), SWITCH_LOG_WARNING, | |||
627 | "Unable to send SWITCH_MESSAGE_INDICATE_DISPLAY message to channel %s\n", | |||
628 | switch_core_session_get_uuid(helper->remote_session)); | |||
629 | } | |||
630 | } | |||
631 | ||||
632 | skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_RING_IN)skinny_line_perform_set_state("skinny_server.c", (const char * )__func__, 632, listener, line_instance, helper->tech_pvt-> call_id, SKINNY_RING_IN); | |||
633 | send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, SKINNY_KEY_SET_RING_IN, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 633, line_instance, helper->tech_pvt-> call_id, SKINNY_KEY_SET_RING_IN, 0xffff); | |||
634 | ||||
635 | label = skinny_textid2raw(SKINNY_TEXTID_FROM)(SKINNY_TEXTID_FROM > 0 ? switch_mprintf("\200%c", SKINNY_TEXTID_FROM ) : switch_mprintf("")); | |||
636 | if ((tmp = switch_mprintf("%s%s", label, helper->tech_pvt->caller_profile->destination_number))) { | |||
637 | send_display_prompt_status(listener, 0, tmp, line_instance, helper->tech_pvt->call_id)perform_send_display_prompt_status(listener, "skinny_server.c" , (const char *)__func__, 637, 0, tmp, line_instance, helper-> tech_pvt->call_id); | |||
638 | switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);}; | |||
639 | } | |||
640 | switch_safe_free(label)if (label) {free(label);label=((void*)0);}; | |||
641 | ||||
642 | if ((tmp = switch_mprintf("\005\000\000\000%s", helper->tech_pvt->caller_profile->destination_number))) { | |||
643 | send_display_pri_notify(listener, 10 /* message_timeout */, 5 /* priority */, tmp)perform_send_display_pri_notify(listener, "skinny_server.c", ( const char *)__func__, 643, 10 , 5 , tmp); | |||
644 | switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);}; | |||
645 | } | |||
646 | skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance); | |||
647 | send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_BLINK)perform_send_set_lamp(listener, "skinny_server.c", (const char *)__func__, 647, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_BLINK ); | |||
648 | ||||
649 | if ( active_calls < 1 && ring_on_idle ) { | |||
650 | send_set_ringer(listener, SKINNY_RING_INSIDE, SKINNY_RING_FOREVER, line_instance, helper->tech_pvt->call_id)perform_send_set_ringer(listener, "skinny_server.c", (const char *)__func__, 650, SKINNY_RING_INSIDE, SKINNY_RING_FOREVER, line_instance , helper->tech_pvt->call_id); | |||
651 | } else if ( active_calls > 0 && ring_on_active ) { | |||
652 | send_start_tone(listener, SKINNY_TONE_CALLWAITTONE, 0, line_instance, helper->tech_pvt->call_id)perform_send_start_tone(listener, "skinny_server.c", (const char *)__func__, 652, SKINNY_TONE_CALLWAITTONE, 0, line_instance, helper->tech_pvt->call_id); | |||
653 | send_stop_tone(listener, line_instance, helper->tech_pvt->call_id)perform_send_stop_tone(listener, "skinny_server.c", (const char *)__func__, 653, line_instance, helper->tech_pvt->call_id ); | |||
654 | } else { | |||
655 | send_set_ringer(listener, SKINNY_RING_FLASHONLY, SKINNY_RING_FOREVER, line_instance, helper->tech_pvt->call_id)perform_send_set_ringer(listener, "skinny_server.c", (const char *)__func__, 655, SKINNY_RING_FLASHONLY, SKINNY_RING_FOREVER, line_instance, helper->tech_pvt->call_id); | |||
656 | } | |||
657 | switch_channel_ring_ready(channel)switch_channel_perform_ring_ready_value(channel, SWITCH_RING_READY_RINGING , "skinny_server.c", (const char *)__func__, 657); | |||
658 | } | |||
659 | return 0; | |||
660 | } | |||
661 | ||||
662 | switch_call_cause_t skinny_ring_lines(private_t *tech_pvt, switch_core_session_t *remote_session) | |||
663 | { | |||
664 | switch_status_t status; | |||
665 | struct skinny_ring_lines_helper helper = {0}; | |||
666 | ||||
667 | switch_assert(tech_pvt)((tech_pvt) ? (void) (0) : __assert_fail ("tech_pvt", "skinny_server.c" , 667, __PRETTY_FUNCTION__)); | |||
668 | switch_assert(tech_pvt->profile)((tech_pvt->profile) ? (void) (0) : __assert_fail ("tech_pvt->profile" , "skinny_server.c", 668, __PRETTY_FUNCTION__)); | |||
669 | switch_assert(tech_pvt->session)((tech_pvt->session) ? (void) (0) : __assert_fail ("tech_pvt->session" , "skinny_server.c", 669, __PRETTY_FUNCTION__)); | |||
670 | ||||
671 | helper.tech_pvt = tech_pvt; | |||
672 | helper.remote_session = remote_session; | |||
673 | helper.lines_count = 0; | |||
674 | ||||
675 | status = skinny_session_walk_lines(tech_pvt->profile, | |||
676 | switch_core_session_get_uuid(tech_pvt->session), skinny_ring_lines_callback, &helper); | |||
677 | skinny_session_set_variables(tech_pvt->session, NULL((void*)0), 0); | |||
678 | ||||
679 | if (status != SWITCH_STATUS_SUCCESS) { | |||
680 | return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; | |||
681 | } else if (helper.lines_count == 0) { | |||
682 | return SWITCH_CAUSE_UNALLOCATED_NUMBER; | |||
683 | } else { | |||
684 | return SWITCH_CAUSE_SUCCESS; | |||
685 | } | |||
686 | } | |||
687 | ||||
688 | switch_status_t skinny_session_ring_out(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) | |||
689 | { | |||
690 | private_t *tech_pvt = NULL((void*)0); | |||
691 | ||||
692 | switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "skinny_server.c" , 692, __PRETTY_FUNCTION__)); | |||
693 | switch_assert(listener)((listener) ? (void) (0) : __assert_fail ("listener", "skinny_server.c" , 693, __PRETTY_FUNCTION__)); | |||
694 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 694, __PRETTY_FUNCTION__)); | |||
695 | ||||
696 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
697 | ||||
698 | send_start_tone(listener, SKINNY_TONE_ALERT, 0, line_instance, tech_pvt->call_id)perform_send_start_tone(listener, "skinny_server.c", (const char *)__func__, 698, SKINNY_TONE_ALERT, 0, line_instance, tech_pvt ->call_id); | |||
699 | skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_RING_OUT)skinny_line_perform_set_state("skinny_server.c", (const char * )__func__, 699, listener, line_instance, tech_pvt->call_id , SKINNY_RING_OUT); | |||
700 | send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_RING_OUT, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 700, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_RING_OUT , 0xffff); | |||
701 | ||||
702 | send_display_prompt_status_textid(listener, 0, SKINNY_TEXTID_RING_OUT, line_instance, tech_pvt->call_id)perform_send_display_prompt_status_textid(listener, "skinny_server.c" , (const char *)__func__, 702, 0, SKINNY_TEXTID_RING_OUT, line_instance , tech_pvt->call_id); | |||
703 | ||||
704 | skinny_session_send_call_info(session, listener, line_instance); | |||
705 | ||||
706 | return SWITCH_STATUS_SUCCESS; | |||
707 | } | |||
708 | ||||
709 | ||||
710 | struct skinny_session_answer_helper { | |||
711 | private_t *tech_pvt; | |||
712 | listener_t *listener; | |||
713 | uint32_t line_instance; | |||
714 | }; | |||
715 | ||||
716 | int skinny_session_answer_callback(void *pArg, int argc, char **argv, char **columnNames) | |||
717 | { | |||
718 | struct skinny_session_answer_helper *helper = pArg; | |||
719 | listener_t *listener = NULL((void*)0); | |||
720 | ||||
721 | char *device_name = argv[0]; | |||
722 | uint32_t device_instance = atoi(argv[1]); | |||
723 | /* uint32_t position = atoi(argv[2]); */ | |||
724 | uint32_t line_instance = atoi(argv[3]); | |||
725 | /* char *label = argv[4]; */ | |||
726 | /* char *value = argv[5]; */ | |||
727 | /* char *caller_name = argv[6]; */ | |||
728 | /* uint32_t ring_on_idle = atoi(argv[7]); */ | |||
729 | /* uint32_t ring_on_active = atoi(argv[8]); */ | |||
730 | /* uint32_t busy_trigger = atoi(argv[9]); */ | |||
731 | /* char *forward_all = argv[10]; */ | |||
732 | /* char *forward_busy = argv[11]; */ | |||
733 | /* char *forward_noanswer = argv[12]; */ | |||
734 | /* uint32_t noanswer_duration = atoi(argv[13]); */ | |||
735 | /* char *channel_uuid = argv[14]; */ | |||
736 | /* uint32_t call_id = atoi(argv[15]); */ | |||
737 | /* uint32_t call_state = atoi(argv[16]); */ | |||
738 | ||||
739 | skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, device_name, device_instance, &listener); | |||
740 | if(listener) { | |||
741 | if(!strcmp(device_name, helper->listener->device_name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (device_name) && __builtin_constant_p (helper->listener ->device_name) && (__s1_len = __builtin_strlen (device_name ), __s2_len = __builtin_strlen (helper->listener->device_name ), (!((size_t)(const void *)((device_name) + 1) - (size_t)(const void *)(device_name) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)((helper->listener->device_name ) + 1) - (size_t)(const void *)(helper->listener->device_name ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (device_name , helper->listener->device_name) : (__builtin_constant_p (device_name) && ((size_t)(const void *)((device_name ) + 1) - (size_t)(const void *)(device_name) == 1) && (__s1_len = __builtin_strlen (device_name), __s1_len < 4) ? (__builtin_constant_p (helper->listener->device_name ) && ((size_t)(const void *)((helper->listener-> device_name) + 1) - (size_t)(const void *)(helper->listener ->device_name) == 1) ? __builtin_strcmp (device_name, helper ->listener->device_name) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (helper-> listener->device_name); int __result = (((const unsigned char *) (const char *) (device_name))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (device_name))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (device_name))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (device_name))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (helper->listener->device_name ) && ((size_t)(const void *)((helper->listener-> device_name) + 1) - (size_t)(const void *)(helper->listener ->device_name) == 1) && (__s2_len = __builtin_strlen (helper->listener->device_name), __s2_len < 4) ? (__builtin_constant_p (device_name) && ((size_t)(const void *)((device_name ) + 1) - (size_t)(const void *)(device_name) == 1) ? __builtin_strcmp (device_name, helper->listener->device_name) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (device_name); int __result = (((const unsigned char *) (const char *) (helper->listener->device_name))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (helper->listener ->device_name))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (helper->listener->device_name))[2] - __s2[2]) ; if (__s2_len > 2 && __result == 0) __result = (( (const unsigned char *) (const char *) (helper->listener-> device_name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (device_name, helper->listener->device_name)))); }) | |||
742 | && (device_instance == helper->listener->device_instance) | |||
743 | && (line_instance == helper->line_instance)) {/* the answering line */ | |||
744 | /* nothing */ | |||
745 | skinny_log_l_msg(listener, SWITCH_LOG_DEBUG, "Session Answer Callback - matched helper\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 745, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Session Answer Callback - matched helper\n", (_zstr(listener ->device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port); | |||
746 | } else { | |||
747 | skinny_log_l_msg(listener, SWITCH_LOG_DEBUG, "Session Answer Callback\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 747, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Session Answer Callback\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port); | |||
748 | ||||
749 | send_define_current_time_date(listener)perform_send_define_current_time_date(listener, "skinny_server.c" , (const char *)__func__, 749); | |||
750 | send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON)perform_send_set_lamp(listener, "skinny_server.c", (const char *)__func__, 750, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON ); | |||
751 | skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_IN_USE_REMOTELY)skinny_line_perform_set_state("skinny_server.c", (const char * )__func__, 751, listener, line_instance, helper->tech_pvt-> call_id, SKINNY_IN_USE_REMOTELY); | |||
752 | send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, 10, 0x0002)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 752, line_instance, helper->tech_pvt-> call_id, 10, 0x0002); | |||
753 | ||||
754 | send_display_prompt_status_textid(listener, 0, SKINNY_TEXTID_IN_USE_REMOTE, line_instance, helper->tech_pvt->call_id)perform_send_display_prompt_status_textid(listener, "skinny_server.c" , (const char *)__func__, 754, 0, SKINNY_TEXTID_IN_USE_REMOTE , line_instance, helper->tech_pvt->call_id); | |||
755 | ||||
756 | send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, line_instance, helper->tech_pvt->call_id)perform_send_set_ringer(listener, "skinny_server.c", (const char *)__func__, 756, SKINNY_RING_OFF, SKINNY_RING_FOREVER, line_instance , helper->tech_pvt->call_id); | |||
757 | } | |||
758 | } | |||
759 | return 0; | |||
760 | } | |||
761 | ||||
762 | switch_status_t skinny_session_answer(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) | |||
763 | { | |||
764 | struct skinny_session_answer_helper helper = {0}; | |||
765 | switch_channel_t *channel = NULL((void*)0); | |||
766 | private_t *tech_pvt = NULL((void*)0); | |||
767 | ||||
768 | switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "skinny_server.c" , 768, __PRETTY_FUNCTION__)); | |||
769 | switch_assert(listener)((listener) ? (void) (0) : __assert_fail ("listener", "skinny_server.c" , 769, __PRETTY_FUNCTION__)); | |||
770 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 770, __PRETTY_FUNCTION__)); | |||
771 | ||||
772 | skinny_hold_active_calls(listener); | |||
773 | ||||
774 | channel = switch_core_session_get_channel(session); | |||
775 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
776 | ||||
777 | send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, line_instance, tech_pvt->call_id)perform_send_set_ringer(listener, "skinny_server.c", (const char *)__func__, 777, SKINNY_RING_OFF, SKINNY_RING_FOREVER, line_instance , tech_pvt->call_id); | |||
778 | send_set_speaker_mode(listener, SKINNY_SPEAKER_ON)perform_send_set_speaker_mode(listener, "skinny_server.c", (const char *)__func__, 778, SKINNY_SPEAKER_ON); | |||
779 | send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON)perform_send_set_lamp(listener, "skinny_server.c", (const char *)__func__, 779, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON ); | |||
780 | skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_OFF_HOOK)skinny_line_perform_set_state("skinny_server.c", (const char * )__func__, 780, listener, line_instance, tech_pvt->call_id , SKINNY_OFF_HOOK); | |||
781 | send_activate_call_plane(listener, line_instance)perform_send_activate_call_plane(listener, "skinny_server.c", (const char *)__func__, 781, line_instance); | |||
782 | ||||
783 | helper.tech_pvt = tech_pvt; | |||
784 | helper.listener = listener; | |||
785 | helper.line_instance = line_instance; | |||
786 | ||||
787 | skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_answer_callback, &helper); | |||
788 | ||||
789 | if (switch_channel_get_state(channel) == CS_INIT) { | |||
790 | switch_channel_set_state(channel, CS_ROUTING)switch_channel_perform_set_state(channel, "skinny_server.c", ( const char *)__func__, 790, CS_ROUTING); | |||
791 | } | |||
792 | skinny_session_start_media(session, listener, line_instance); | |||
793 | ||||
794 | return SWITCH_STATUS_SUCCESS; | |||
795 | } | |||
796 | ||||
797 | switch_status_t skinny_session_start_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) | |||
798 | { | |||
799 | switch_channel_t *channel = NULL((void*)0); | |||
800 | private_t *tech_pvt = NULL((void*)0); | |||
801 | ||||
802 | switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "skinny_server.c" , 802, __PRETTY_FUNCTION__)); | |||
803 | switch_assert(listener)((listener) ? (void) (0) : __assert_fail ("listener", "skinny_server.c" , 803, __PRETTY_FUNCTION__)); | |||
804 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 804, __PRETTY_FUNCTION__)); | |||
805 | ||||
806 | channel = switch_core_session_get_channel(session); | |||
807 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
808 | ||||
809 | if (!switch_channel_test_flag(channel, CF_EARLY_MEDIA)) { | |||
810 | send_stop_tone(listener, line_instance, tech_pvt->call_id)perform_send_stop_tone(listener, "skinny_server.c", (const char *)__func__, 810, line_instance, tech_pvt->call_id); | |||
811 | send_open_receive_channel(listener,perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
812 | tech_pvt->call_id, /* uint32_t conference_id, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
813 | tech_pvt->call_id, /* uint32_t pass_thru_party_id, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
814 | SKINNY_PTIME, /* uint32_t ms_per_packet, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
815 | SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
816 | 0, /* uint32_t echo_cancel_type, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
817 | 0, /* uint32_t g723_bitrate, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
818 | tech_pvt->call_id, /* uint32_t conference_id2, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
819 | 0 /* uint32_t reserved[10] */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
820 | )perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 820, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0); | |||
821 | } | |||
822 | if (!switch_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)((tech_pvt)->flags & TFLAG_EARLY_MEDIA)) { | |||
823 | skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_CONNECTED)skinny_line_perform_set_state("skinny_server.c", (const char * )__func__, 823, listener, line_instance, tech_pvt->call_id , SKINNY_CONNECTED); | |||
824 | send_select_soft_keys(listener, line_instance, tech_pvt->call_id,perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 825, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_CONNECTED , 0xffff) | |||
825 | SKINNY_KEY_SET_CONNECTED, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 825, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_CONNECTED , 0xffff); | |||
826 | ||||
827 | send_display_prompt_status_textid(listener, 0, SKINNY_TEXTID_CONNECTED, line_instance, tech_pvt->call_id)perform_send_display_prompt_status_textid(listener, "skinny_server.c" , (const char *)__func__, 827, 0, SKINNY_TEXTID_CONNECTED, line_instance , tech_pvt->call_id); | |||
828 | } | |||
829 | skinny_session_send_call_info(session, listener, line_instance); | |||
830 | ||||
831 | return SWITCH_STATUS_SUCCESS; | |||
832 | } | |||
833 | ||||
834 | switch_status_t skinny_session_hold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) | |||
835 | { | |||
836 | private_t *tech_pvt = NULL((void*)0); | |||
837 | ||||
838 | switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "skinny_server.c" , 838, __PRETTY_FUNCTION__)); | |||
839 | switch_assert(listener)((listener) ? (void) (0) : __assert_fail ("listener", "skinny_server.c" , 839, __PRETTY_FUNCTION__)); | |||
840 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 840, __PRETTY_FUNCTION__)); | |||
841 | ||||
842 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
843 | ||||
844 | skinny_session_stop_media(session, listener, line_instance); | |||
845 | switch_ivr_hold(session, NULL((void*)0), 1); | |||
846 | ||||
847 | send_define_current_time_date(listener)perform_send_define_current_time_date(listener, "skinny_server.c" , (const char *)__func__, 847); | |||
848 | send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_WINK)perform_send_set_lamp(listener, "skinny_server.c", (const char *)__func__, 848, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_WINK ); | |||
849 | skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_HOLD)skinny_line_perform_set_state("skinny_server.c", (const char * )__func__, 849, listener, line_instance, tech_pvt->call_id , SKINNY_HOLD); | |||
850 | send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_ON_HOLD, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 850, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_ON_HOLD , 0xffff); | |||
851 | ||||
852 | send_display_prompt_status_textid(listener, 0, SKINNY_TEXTID_HOLD, line_instance, tech_pvt->call_id)perform_send_display_prompt_status_textid(listener, "skinny_server.c" , (const char *)__func__, 852, 0, SKINNY_TEXTID_HOLD, line_instance , tech_pvt->call_id); | |||
853 | ||||
854 | skinny_session_send_call_info(tech_pvt->session, listener, line_instance); | |||
855 | send_set_speaker_mode(listener, SKINNY_SPEAKER_OFF)perform_send_set_speaker_mode(listener, "skinny_server.c", (const char *)__func__, 855, SKINNY_SPEAKER_OFF); | |||
856 | send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, line_instance, tech_pvt->call_id)perform_send_set_ringer(listener, "skinny_server.c", (const char *)__func__, 856, SKINNY_RING_OFF, SKINNY_RING_FOREVER, line_instance , tech_pvt->call_id); | |||
857 | ||||
858 | return SWITCH_STATUS_SUCCESS; | |||
859 | } | |||
860 | ||||
861 | switch_status_t skinny_session_unhold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) | |||
862 | { | |||
863 | private_t *tech_pvt = NULL((void*)0); | |||
864 | ||||
865 | switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "skinny_server.c" , 865, __PRETTY_FUNCTION__)); | |||
866 | switch_assert(listener)((listener) ? (void) (0) : __assert_fail ("listener", "skinny_server.c" , 866, __PRETTY_FUNCTION__)); | |||
867 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 867, __PRETTY_FUNCTION__)); | |||
868 | ||||
869 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
870 | ||||
871 | skinny_hold_active_calls(listener); | |||
872 | send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, line_instance, tech_pvt->call_id)perform_send_set_ringer(listener, "skinny_server.c", (const char *)__func__, 872, SKINNY_RING_OFF, SKINNY_RING_FOREVER, line_instance , tech_pvt->call_id); | |||
873 | send_set_speaker_mode(listener, SKINNY_SPEAKER_ON)perform_send_set_speaker_mode(listener, "skinny_server.c", (const char *)__func__, 873, SKINNY_SPEAKER_ON); | |||
874 | send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_RING_OUT, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 874, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_RING_OUT , 0xffff); | |||
875 | ||||
876 | send_stop_tone(listener, line_instance, tech_pvt->call_id)perform_send_stop_tone(listener, "skinny_server.c", (const char *)__func__, 876, line_instance, tech_pvt->call_id); | |||
877 | send_open_receive_channel(listener,perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
878 | tech_pvt->call_id, /* uint32_t conference_id, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
879 | tech_pvt->call_id, /* uint32_t pass_thru_party_id, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
880 | SKINNY_PTIME, /* uint32_t ms_per_packet, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
881 | SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
882 | 0, /* uint32_t echo_cancel_type, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
883 | 0, /* uint32_t g723_bitrate, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
884 | tech_pvt->call_id, /* uint32_t conference_id2, */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
885 | 0 /* uint32_t reserved[10] */perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0) | |||
886 | )perform_send_open_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 886, tech_pvt->call_id, tech_pvt ->call_id, 20, SKINNY_CODEC_ULAW_64K, 0, 0, tech_pvt->call_id , 0); | |||
887 | ||||
888 | skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_CONNECTED)skinny_line_perform_set_state("skinny_server.c", (const char * )__func__, 888, listener, line_instance, tech_pvt->call_id , SKINNY_CONNECTED); | |||
889 | send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_CONNECTED, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 889, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_CONNECTED , 0xffff); | |||
890 | ||||
891 | send_display_prompt_status_textid(listener, 0, SKINNY_TEXTID_CONNECTED, line_instance, tech_pvt->call_id)perform_send_display_prompt_status_textid(listener, "skinny_server.c" , (const char *)__func__, 891, 0, SKINNY_TEXTID_CONNECTED, line_instance , tech_pvt->call_id); | |||
892 | skinny_session_send_call_info(session, listener, line_instance); | |||
893 | ||||
894 | return SWITCH_STATUS_SUCCESS; | |||
895 | } | |||
896 | ||||
897 | switch_status_t skinny_session_transfer(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) | |||
898 | { | |||
899 | switch_status_t status = SWITCH_STATUS_SUCCESS; | |||
900 | private_t *tech_pvt = NULL((void*)0); | |||
901 | switch_channel_t *channel = NULL((void*)0); | |||
902 | switch_channel_t *channel2 = NULL((void*)0); | |||
903 | const char *local_uuid = NULL((void*)0); | |||
904 | const char *local_uuid2 = NULL((void*)0); | |||
905 | const char *remote_uuid = NULL((void*)0); | |||
906 | const char *remote_uuid2 = NULL((void*)0); | |||
907 | switch_core_session_t *session2 = NULL((void*)0); | |||
908 | switch_core_session_t *rsession = NULL((void*)0); | |||
909 | private_t *tech_pvt2 = NULL((void*)0); | |||
910 | ||||
911 | switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "skinny_server.c" , 911, __PRETTY_FUNCTION__)); | |||
912 | switch_assert(listener)((listener) ? (void) (0) : __assert_fail ("listener", "skinny_server.c" , 912, __PRETTY_FUNCTION__)); | |||
913 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 913, __PRETTY_FUNCTION__)); | |||
914 | ||||
915 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
916 | channel = switch_core_session_get_channel(session); | |||
917 | local_uuid = switch_channel_get_uuid(channel); | |||
918 | remote_uuid = switch_channel_get_partner_uuid(channel); | |||
919 | ||||
920 | if ( switch_core_session_get_partner(session, &rsession)switch_core_session_perform_get_partner(session, &rsession , "skinny_server.c", (const char *)__func__, 920) == SWITCH_STATUS_SUCCESS ) | |||
921 | { | |||
922 | switch_channel_t *rchannel = NULL((void*)0); | |||
923 | rchannel = switch_core_session_get_channel(rsession); | |||
924 | ||||
925 | skinny_log_l_msg(listener, SWITCH_LOG_INFO, "SST: setting uuid bridge continue flag on remote channel\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 925, ((void*)0), SWITCH_LOG_INFO, "[%s:%d @ %s:%d] " "SST: setting uuid bridge continue flag on remote channel\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
926 | ||||
927 | switch_channel_set_variable(rchannel, "uuid_bridge_continue_on_cancel", "true")switch_channel_set_variable_var_check(rchannel, "uuid_bridge_continue_on_cancel" , "true", SWITCH_TRUE); | |||
928 | switch_core_session_rwunlock(rsession); | |||
929 | } | |||
930 | ||||
931 | skinny_log_l(listener, SWITCH_LOG_INFO, "SST: local_uuid=%s remote_uuid=%s\n", local_uuid, remote_uuid)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 931, ((void*)0), SWITCH_LOG_INFO, "[%s:%d @ %s:%d] " "SST: local_uuid=%s remote_uuid=%s\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port, local_uuid, remote_uuid); | |||
932 | ||||
933 | if (tech_pvt->transfer_from_call_id) { | |||
934 | skinny_log_l_msg(listener, SWITCH_LOG_INFO, "SST: transfer_from_call_id\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 934, ((void*)0), SWITCH_LOG_INFO, "[%s:%d @ %s:%d] " "SST: transfer_from_call_id\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port); | |||
935 | ||||
936 | if((session2 = skinny_profile_find_session(listener->profile, listener, &line_instance, tech_pvt->transfer_from_call_id))) { | |||
937 | channel2 = switch_core_session_get_channel(session2); | |||
938 | local_uuid2 = switch_channel_get_uuid(channel2); | |||
939 | remote_uuid2 = switch_channel_get_partner_uuid(channel2); | |||
940 | skinny_log_ls(listener, session2, SWITCH_LOG_INFO, "SST: tx from session - local_uuid=%s remote_uuid=%s local_uuid2=%s remote_uuid2=%s\n",switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 941, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: tx from session - local_uuid=%s remote_uuid=%s local_uuid2=%s remote_uuid2=%s\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, local_uuid, remote_uuid, local_uuid2, remote_uuid2 ) | |||
941 | local_uuid, remote_uuid, local_uuid2, remote_uuid2)switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 941, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: tx from session - local_uuid=%s remote_uuid=%s local_uuid2=%s remote_uuid2=%s\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, local_uuid, remote_uuid, local_uuid2, remote_uuid2 ); | |||
942 | ||||
943 | skinny_log_ls(listener, session2, SWITCH_LOG_INFO, "SST: attempting ivr bridge from (%s) to (%s)\n", remote_uuid, remote_uuid2)switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 943, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: attempting ivr bridge from (%s) to (%s)\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, remote_uuid, remote_uuid2); | |||
944 | ||||
945 | if (switch_ivr_uuid_bridge(remote_uuid2, remote_uuid) == SWITCH_STATUS_SUCCESS) { | |||
946 | skinny_log_ls_msg(listener, session2, SWITCH_LOG_INFO, "SST: success on uuid bridge\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 946, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: success on uuid bridge\n", (_zstr( listener->device_name) ? "_undef_" : listener->device_name ), listener->device_instance, (_zstr(listener->remote_ip ) ? "_undef_" : listener->remote_ip), listener->remote_port ); | |||
947 | ||||
948 | switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(channel, "skinny_server.c", (const char *)__func__, 948, SWITCH_CAUSE_NORMAL_CLEARING); | |||
949 | switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(channel2, "skinny_server.c", (const char *)__func__, 949, SWITCH_CAUSE_NORMAL_CLEARING); | |||
950 | } else { | |||
951 | skinny_log_ls_msg(listener, session2, SWITCH_LOG_INFO, "SST: failure on uuid bridge\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 951, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: failure on uuid bridge\n", (_zstr( listener->device_name) ? "_undef_" : listener->device_name ), listener->device_instance, (_zstr(listener->remote_ip ) ? "_undef_" : listener->remote_ip), listener->remote_port ); | |||
952 | /* TODO: How to inform the user that the bridge is not possible? */ | |||
953 | } | |||
954 | switch_core_session_rwunlock(session2); | |||
955 | } | |||
956 | } else { | |||
957 | skinny_log_l_msg(listener, SWITCH_LOG_INFO, "SST: !transfer_from_call_id\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 957, ((void*)0), SWITCH_LOG_INFO, "[%s:%d @ %s:%d] " "SST: !transfer_from_call_id\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port); | |||
958 | ||||
959 | if(remote_uuid) { | |||
960 | skinny_log_ls_msg(listener, session2, SWITCH_LOG_INFO, "SST: found remote_uuid\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 960, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: found remote_uuid\n", (_zstr(listener ->device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port); | |||
961 | ||||
962 | /* TODO CallSelectStat */ | |||
963 | skinny_log_ls_msg(listener, session2, SWITCH_LOG_INFO, "SST: creating incoming session\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 963, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: creating incoming session\n", (_zstr (listener->device_name) ? "_undef_" : listener->device_name ), listener->device_instance, (_zstr(listener->remote_ip ) ? "_undef_" : listener->remote_ip), listener->remote_port ); | |||
964 | status = skinny_create_incoming_session(listener, &line_instance, &session2); | |||
965 | if ( ! session2 ) { | |||
966 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "SST: Unable to create incoming session for transfer.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 966, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "SST: Unable to create incoming session for transfer.\n", (_zstr (listener->device_name) ? "_undef_" : listener->device_name ), listener->device_instance, (_zstr(listener->remote_ip ) ? "_undef_" : listener->remote_ip), listener->remote_port ); | |||
967 | return SWITCH_STATUS_FALSE; | |||
968 | } | |||
969 | tech_pvt2 = switch_core_session_get_private(session2)switch_core_session_get_private_class(session2, SWITCH_PVT_PRIMARY ); | |||
970 | tech_pvt2->transfer_from_call_id = tech_pvt->call_id; | |||
971 | tech_pvt->transfer_to_call_id = tech_pvt2->call_id; | |||
972 | skinny_log_ls(listener, session2, SWITCH_LOG_INFO, "SST: transfer_to_call_id=%d transfer_from_call_id=%d\n", tech_pvt2->call_id,switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 973, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: transfer_to_call_id=%d transfer_from_call_id=%d\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, tech_pvt2->call_id, tech_pvt->call_id) | |||
973 | tech_pvt->call_id)switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 973, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: transfer_to_call_id=%d transfer_from_call_id=%d\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, tech_pvt2->call_id, tech_pvt->call_id); | |||
974 | skinny_log_ls_msg(listener, session2, SWITCH_LOG_INFO, "SST: triggering dial on incoming session\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 974, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: triggering dial on incoming session\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
975 | skinny_session_process_dest(session2, listener, line_instance, NULL((void*)0), '\0', 0); | |||
976 | ||||
977 | channel2 = switch_core_session_get_channel(session2); | |||
978 | local_uuid2 = switch_channel_get_uuid(channel2); | |||
979 | remote_uuid2 = switch_channel_get_partner_uuid(channel2); | |||
980 | skinny_log_ls(listener, session2, SWITCH_LOG_INFO, "SST: new session - local_uuid2=%s remote_uuid2=%s\n", local_uuid2, remote_uuid2)switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 980, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: new session - local_uuid2=%s remote_uuid2=%s\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, local_uuid2, remote_uuid2); | |||
981 | ||||
982 | switch_core_session_rwunlock(session2); | |||
983 | } else { | |||
984 | skinny_log_ls_msg(listener, session2, SWITCH_LOG_INFO, "SST: could not find remote_uuid\n")switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "skinny_server.c" , (const char *)__func__, 984, (const char*)(session2), SWITCH_LOG_INFO , "[%s:%d @ %s:%d] " "SST: could not find remote_uuid\n", (_zstr (listener->device_name) ? "_undef_" : listener->device_name ), listener->device_instance, (_zstr(listener->remote_ip ) ? "_undef_" : listener->remote_ip), listener->remote_port ); | |||
985 | ||||
986 | /* TODO: How to inform the user that the bridge is not possible? */ | |||
987 | } | |||
988 | } | |||
989 | return status; | |||
990 | } | |||
991 | ||||
992 | switch_status_t skinny_session_stop_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) | |||
993 | { | |||
994 | private_t *tech_pvt = NULL((void*)0); | |||
995 | ||||
996 | switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "skinny_server.c" , 996, __PRETTY_FUNCTION__)); | |||
997 | switch_assert(listener)((listener) ? (void) (0) : __assert_fail ("listener", "skinny_server.c" , 997, __PRETTY_FUNCTION__)); | |||
998 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 998, __PRETTY_FUNCTION__)); | |||
999 | ||||
1000 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
1001 | ||||
1002 | switch_clear_flag_locked(tech_pvt, TFLAG_IO)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags &= ~(TFLAG_IO); switch_mutex_unlock(tech_pvt->flag_mutex );; | |||
1003 | ||||
1004 | send_close_receive_channel(listener,perform_send_close_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 1008, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id) | |||
1005 | tech_pvt->call_id, /* uint32_t conference_id, */perform_send_close_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 1008, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id) | |||
1006 | tech_pvt->party_id, /* uint32_t pass_thru_party_id, */perform_send_close_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 1008, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id) | |||
1007 | tech_pvt->call_id /* uint32_t conference_id2, */perform_send_close_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 1008, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id) | |||
1008 | )perform_send_close_receive_channel(listener, "skinny_server.c" , (const char *)__func__, 1008, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id); | |||
1009 | send_stop_media_transmission(listener,perform_send_stop_media_transmission(listener, "skinny_server.c" , (const char *)__func__, 1013, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id) | |||
1010 | tech_pvt->call_id, /* uint32_t conference_id, */perform_send_stop_media_transmission(listener, "skinny_server.c" , (const char *)__func__, 1013, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id) | |||
1011 | tech_pvt->party_id, /* uint32_t pass_thru_party_id, */perform_send_stop_media_transmission(listener, "skinny_server.c" , (const char *)__func__, 1013, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id) | |||
1012 | tech_pvt->call_id /* uint32_t conference_id2, */perform_send_stop_media_transmission(listener, "skinny_server.c" , (const char *)__func__, 1013, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id) | |||
1013 | )perform_send_stop_media_transmission(listener, "skinny_server.c" , (const char *)__func__, 1013, tech_pvt->call_id, tech_pvt ->party_id, tech_pvt->call_id); | |||
1014 | ||||
1015 | return SWITCH_STATUS_SUCCESS; | |||
1016 | } | |||
1017 | ||||
1018 | struct skinny_hold_active_calls_helper { | |||
1019 | listener_t *listener; | |||
1020 | }; | |||
1021 | ||||
1022 | int skinny_hold_active_calls_callback(void *pArg, int argc, char **argv, char **columnNames) | |||
1023 | { | |||
1024 | struct skinny_hold_active_calls_helper *helper = pArg; | |||
1025 | switch_core_session_t *session; | |||
1026 | ||||
1027 | /* char *device_name = argv[0]; */ | |||
1028 | /* uint32_t device_instance = atoi(argv[1]); */ | |||
1029 | /* uint32_t position = atoi(argv[2]); */ | |||
1030 | uint32_t line_instance = atoi(argv[3]); | |||
1031 | /* char *label = argv[4]; */ | |||
1032 | /* char *value = argv[5]; */ | |||
1033 | /* char *caller_name = argv[6]; */ | |||
1034 | /* uint32_t ring_on_idle = atoi(argv[7]); */ | |||
1035 | /* uint32_t ring_on_active = atoi(argv[8]); */ | |||
1036 | /* uint32_t busy_trigger = atoi(argv[9]); */ | |||
1037 | /* char *forward_all = argv[10]; */ | |||
1038 | /* char *forward_busy = argv[11]; */ | |||
1039 | /* char *forward_noanswer = argv[12]; */ | |||
1040 | /* uint32_t noanswer_duration = atoi(argv[13]); */ | |||
1041 | /* char *channel_uuid = argv[14]; */ | |||
1042 | uint32_t call_id = atoi(argv[15]); | |||
1043 | /* uint32_t call_state = atoi(argv[16]); */ | |||
1044 | ||||
1045 | session = skinny_profile_find_session(helper->listener->profile, helper->listener, &line_instance, call_id); | |||
1046 | ||||
1047 | if(session) { | |||
1048 | skinny_session_hold_line(session, helper->listener, line_instance); | |||
1049 | switch_core_session_rwunlock(session); | |||
1050 | } | |||
1051 | ||||
1052 | return 0; | |||
1053 | } | |||
1054 | ||||
1055 | switch_status_t skinny_hold_active_calls(listener_t *listener) | |||
1056 | { | |||
1057 | struct skinny_hold_active_calls_helper helper = {0}; | |||
1058 | char *sql; | |||
1059 | ||||
1060 | helper.listener = listener; | |||
1061 | ||||
1062 | if ((sql = switch_mprintf( | |||
1063 | "SELECT skinny_lines.*, channel_uuid, call_id, call_state " | |||
1064 | "FROM skinny_active_lines " | |||
1065 | "INNER JOIN skinny_lines " | |||
1066 | "ON skinny_active_lines.device_name = skinny_lines.device_name " | |||
1067 | "AND skinny_active_lines.device_instance = skinny_lines.device_instance " | |||
1068 | "AND skinny_active_lines.line_instance = skinny_lines.line_instance " | |||
1069 | "WHERE skinny_lines.device_name='%s' AND skinny_lines.device_instance=%d AND (call_state=%d OR call_state=%d)", | |||
1070 | listener->device_name, listener->device_instance, SKINNY_PROCEED, SKINNY_CONNECTED))) { | |||
1071 | skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_hold_active_calls_callback, &helper); | |||
1072 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
1073 | } | |||
1074 | ||||
1075 | return SWITCH_STATUS_SUCCESS; | |||
1076 | } | |||
1077 | ||||
1078 | /*****************************************************************************/ | |||
1079 | /* SKINNY MESSAGE HANDLERS */ | |||
1080 | /*****************************************************************************/ | |||
1081 | switch_status_t skinny_handle_keep_alive_message(listener_t *listener, skinny_message_t *request) | |||
1082 | { | |||
1083 | keepalive_listener(listener, NULL((void*)0)); | |||
1084 | ||||
1085 | send_keep_alive_ack(listener)perform_send_keep_alive_ack(listener, "skinny_server.c", (const char *)__func__, 1085);; | |||
1086 | ||||
1087 | return SWITCH_STATUS_SUCCESS; | |||
1088 | } | |||
1089 | ||||
1090 | switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *request) | |||
1091 | { | |||
1092 | switch_status_t status = SWITCH_STATUS_FALSE; | |||
1093 | skinny_profile_t *profile; | |||
1094 | switch_event_t *event = NULL((void*)0); | |||
1095 | switch_event_t *params = NULL((void*)0); | |||
1096 | switch_xml_t xroot, xdomain, xgroup, xuser, xskinny, xparams, xparam, xbuttons, xbutton; | |||
1097 | listener_t *listener2 = NULL((void*)0); | |||
1098 | char *sql; | |||
1099 | assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 1099, __PRETTY_FUNCTION__)); | |||
1100 | profile = listener->profile; | |||
1101 | ||||
1102 | skinny_check_data_length(request, sizeof(request->data.reg))if (request->length < sizeof(request->data.reg)+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1102, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.reg)+4 ); return SWITCH_STATUS_FALSE; }; | |||
1103 | ||||
1104 | if (!zstr(listener->device_name)_zstr(listener->device_name)) { | |||
1105 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 1105, ((void*)0), SWITCH_LOG_ERROR, | |||
1106 | "A device is already registered on this listener.\n"); | |||
1107 | send_register_reject(listener, "A device is already registered on this listener")perform_send_register_reject(listener, "skinny_server.c", (const char *)__func__, 1107, "A device is already registered on this listener" ); | |||
1108 | return SWITCH_STATUS_FALSE; | |||
1109 | } | |||
1110 | ||||
1111 | /* Check directory */ | |||
1112 | skinny_device_event(listener, ¶ms, SWITCH_EVENT_REQUEST_PARAMS, SWITCH_EVENT_SUBCLASS_ANY((void*)0)); | |||
1113 | switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "skinny-auth"); | |||
1114 | ||||
1115 | /* clean up all traces before adding to database */ | |||
1116 | skinny_clean_device_from_db(listener, request->data.reg.device_name); | |||
1117 | ||||
1118 | if (switch_xml_locate_user("id", request->data.reg.device_name, profile->domain, "", &xroot, &xdomain, &xuser, &xgroup, params) != SWITCH_STATUS_SUCCESS) { | |||
1119 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 1119, ((void*)0), SWITCH_LOG_WARNING, "Can't find device [%s@%s]\n" | |||
1120 | "You must define a domain called '%s' in your directory and add a user with id=\"%s\".\n" | |||
1121 | , request->data.reg.device_name, profile->domain, profile->domain, request->data.reg.device_name); | |||
1122 | send_register_reject(listener, "Device not found")perform_send_register_reject(listener, "skinny_server.c", (const char *)__func__, 1122, "Device not found"); | |||
1123 | status = SWITCH_STATUS_FALSE; | |||
1124 | goto end; | |||
1125 | } | |||
1126 | ||||
1127 | /* we clean up device above, so this below block will never trigger. I don't | |||
1128 | know the full details of why there would be multiple listeners with | |||
1129 | the same device - maybe a VGC or similar? Not really high priority for | |||
1130 | support at the moment, but may need to revisit this later */ | |||
1131 | ||||
1132 | skinny_profile_find_listener_by_device_name_and_instance(listener->profile, | |||
1133 | request->data.reg.device_name, request->data.reg.instance, &listener2); | |||
1134 | if (listener2) { | |||
1135 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 1135, ((void*)0), SWITCH_LOG_ERROR, | |||
1136 | "Device %s:%d is already registered on another listener.\n", | |||
1137 | request->data.reg.device_name, request->data.reg.instance); | |||
1138 | send_register_reject(listener, "Device is already registered on another listener")perform_send_register_reject(listener, "skinny_server.c", (const char *)__func__, 1138, "Device is already registered on another listener" ); | |||
1139 | status = SWITCH_STATUS_FALSE; | |||
1140 | goto end; | |||
1141 | } | |||
1142 | ||||
1143 | if ((sql = switch_mprintf( | |||
1144 | "INSERT INTO skinny_devices " | |||
1145 | "(name, user_id, instance, ip, type, max_streams, codec_string) " | |||
1146 | "VALUES ('%q','%d','%d', '%q', '%d', '%d', '%q')", | |||
1147 | request->data.reg.device_name, | |||
1148 | request->data.reg.user_id, | |||
1149 | request->data.reg.instance, | |||
1150 | inet_ntoa(request->data.reg.ip), | |||
1151 | request->data.reg.device_type, | |||
1152 | request->data.reg.max_streams, | |||
1153 | "" /* codec_string */ | |||
1154 | ))) { | |||
1155 | skinny_execute_sql(profile, sql, profile->sql_mutex); | |||
1156 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
1157 | } | |||
1158 | ||||
1159 | ||||
1160 | switch_copy_string(listener->device_name, request->data.reg.device_name, 16); | |||
1161 | listener->device_instance = request->data.reg.instance; | |||
1162 | listener->device_type = request->data.reg.device_type; | |||
1163 | ||||
1164 | xskinny = switch_xml_child(xuser, "skinny"); | |||
1165 | if (xskinny) { | |||
1166 | if ((xparams = switch_xml_child(xskinny, "params"))) { | |||
1167 | for (xparam = switch_xml_child(xparams, "param"); xparam; xparam = xparam->next) { | |||
1168 | const char *name = switch_xml_attr_soft(xparam, "name"); | |||
1169 | const char *value = switch_xml_attr_soft(xparam, "value"); | |||
1170 | if (!strcasecmp(name, "skinny-firmware-version")) { | |||
1171 | switch_copy_string(listener->firmware_version, value, 16); | |||
1172 | } else if (!strcasecmp(name, "skinny-soft-key-set-set")) { | |||
1173 | listener->soft_key_set_set = switch_core_strdup(profile->pool, value)switch_core_perform_strdup(profile->pool, value, "skinny_server.c" , (const char *)__func__, 1173); | |||
1174 | } else if (!strcasecmp(name, "ext-voicemail")) { | |||
1175 | if (!listener->ext_voicemail || strcmp(value,listener->ext_voicemail)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (value) && __builtin_constant_p (listener->ext_voicemail ) && (__s1_len = __builtin_strlen (value), __s2_len = __builtin_strlen (listener->ext_voicemail), (!((size_t)(const void *)((value) + 1) - (size_t)(const void *)(value) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((listener ->ext_voicemail) + 1) - (size_t)(const void *)(listener-> ext_voicemail) == 1) || __s2_len >= 4)) ? __builtin_strcmp (value, listener->ext_voicemail) : (__builtin_constant_p ( value) && ((size_t)(const void *)((value) + 1) - (size_t )(const void *)(value) == 1) && (__s1_len = __builtin_strlen (value), __s1_len < 4) ? (__builtin_constant_p (listener-> ext_voicemail) && ((size_t)(const void *)((listener-> ext_voicemail) + 1) - (size_t)(const void *)(listener->ext_voicemail ) == 1) ? __builtin_strcmp (value, listener->ext_voicemail ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (listener->ext_voicemail); int __result = (((const unsigned char *) (const char *) (value))[0] - __s2 [0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[1] - __s2 [1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[2] - __s2 [2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (value))[3] - __s2[ 3]); } } __result; }))) : (__builtin_constant_p (listener-> ext_voicemail) && ((size_t)(const void *)((listener-> ext_voicemail) + 1) - (size_t)(const void *)(listener->ext_voicemail ) == 1) && (__s2_len = __builtin_strlen (listener-> ext_voicemail), __s2_len < 4) ? (__builtin_constant_p (value ) && ((size_t)(const void *)((value) + 1) - (size_t)( const void *)(value) == 1) ? __builtin_strcmp (value, listener ->ext_voicemail) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (value); int __result = (((const unsigned char *) (const char *) (listener->ext_voicemail ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (listener ->ext_voicemail))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (listener->ext_voicemail))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (listener->ext_voicemail))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (value, listener ->ext_voicemail)))); })) { | |||
1176 | listener->ext_voicemail = switch_core_strdup(profile->pool, value)switch_core_perform_strdup(profile->pool, value, "skinny_server.c" , (const char *)__func__, 1176); | |||
1177 | } | |||
1178 | } else if (!strcasecmp(name, "ext-redial")) { | |||
1179 | if (!listener->ext_redial || strcmp(value,listener->ext_redial)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (value) && __builtin_constant_p (listener->ext_redial ) && (__s1_len = __builtin_strlen (value), __s2_len = __builtin_strlen (listener->ext_redial), (!((size_t)(const void *)((value) + 1) - (size_t)(const void *)(value) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((listener ->ext_redial) + 1) - (size_t)(const void *)(listener->ext_redial ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (value, listener ->ext_redial) : (__builtin_constant_p (value) && ( (size_t)(const void *)((value) + 1) - (size_t)(const void *)( value) == 1) && (__s1_len = __builtin_strlen (value), __s1_len < 4) ? (__builtin_constant_p (listener->ext_redial ) && ((size_t)(const void *)((listener->ext_redial ) + 1) - (size_t)(const void *)(listener->ext_redial) == 1 ) ? __builtin_strcmp (value, listener->ext_redial) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (listener->ext_redial); int __result = (((const unsigned char *) (const char *) (value))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (value))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (listener->ext_redial) && ( (size_t)(const void *)((listener->ext_redial) + 1) - (size_t )(const void *)(listener->ext_redial) == 1) && (__s2_len = __builtin_strlen (listener->ext_redial), __s2_len < 4 ) ? (__builtin_constant_p (value) && ((size_t)(const void *)((value) + 1) - (size_t)(const void *)(value) == 1) ? __builtin_strcmp (value, listener->ext_redial) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (value); int __result = (((const unsigned char *) (const char *) (listener->ext_redial))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (listener->ext_redial))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (listener->ext_redial))[2 ] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (listener->ext_redial ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (value , listener->ext_redial)))); })) { | |||
1180 | listener->ext_redial = switch_core_strdup(profile->pool, value)switch_core_perform_strdup(profile->pool, value, "skinny_server.c" , (const char *)__func__, 1180); | |||
1181 | } | |||
1182 | } else if (!strcasecmp(name, "ext-meetme")) { | |||
1183 | if (!listener->ext_meetme || strcmp(value,listener->ext_meetme)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (value) && __builtin_constant_p (listener->ext_meetme ) && (__s1_len = __builtin_strlen (value), __s2_len = __builtin_strlen (listener->ext_meetme), (!((size_t)(const void *)((value) + 1) - (size_t)(const void *)(value) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((listener ->ext_meetme) + 1) - (size_t)(const void *)(listener->ext_meetme ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (value, listener ->ext_meetme) : (__builtin_constant_p (value) && ( (size_t)(const void *)((value) + 1) - (size_t)(const void *)( value) == 1) && (__s1_len = __builtin_strlen (value), __s1_len < 4) ? (__builtin_constant_p (listener->ext_meetme ) && ((size_t)(const void *)((listener->ext_meetme ) + 1) - (size_t)(const void *)(listener->ext_meetme) == 1 ) ? __builtin_strcmp (value, listener->ext_meetme) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (listener->ext_meetme); int __result = (((const unsigned char *) (const char *) (value))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (value))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (listener->ext_meetme) && ( (size_t)(const void *)((listener->ext_meetme) + 1) - (size_t )(const void *)(listener->ext_meetme) == 1) && (__s2_len = __builtin_strlen (listener->ext_meetme), __s2_len < 4 ) ? (__builtin_constant_p (value) && ((size_t)(const void *)((value) + 1) - (size_t)(const void *)(value) == 1) ? __builtin_strcmp (value, listener->ext_meetme) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (value); int __result = (((const unsigned char *) (const char *) (listener->ext_meetme))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (listener->ext_meetme))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (listener->ext_meetme))[2 ] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (listener->ext_meetme ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (value , listener->ext_meetme)))); })) { | |||
1184 | listener->ext_meetme = switch_core_strdup(profile->pool, value)switch_core_perform_strdup(profile->pool, value, "skinny_server.c" , (const char *)__func__, 1184); | |||
1185 | } | |||
1186 | } else if (!strcasecmp(name, "ext-pickup")) { | |||
1187 | if (!listener->ext_pickup || strcmp(value,listener->ext_pickup)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (value) && __builtin_constant_p (listener->ext_pickup ) && (__s1_len = __builtin_strlen (value), __s2_len = __builtin_strlen (listener->ext_pickup), (!((size_t)(const void *)((value) + 1) - (size_t)(const void *)(value) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((listener ->ext_pickup) + 1) - (size_t)(const void *)(listener->ext_pickup ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (value, listener ->ext_pickup) : (__builtin_constant_p (value) && ( (size_t)(const void *)((value) + 1) - (size_t)(const void *)( value) == 1) && (__s1_len = __builtin_strlen (value), __s1_len < 4) ? (__builtin_constant_p (listener->ext_pickup ) && ((size_t)(const void *)((listener->ext_pickup ) + 1) - (size_t)(const void *)(listener->ext_pickup) == 1 ) ? __builtin_strcmp (value, listener->ext_pickup) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (listener->ext_pickup); int __result = (((const unsigned char *) (const char *) (value))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (value))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (listener->ext_pickup) && ( (size_t)(const void *)((listener->ext_pickup) + 1) - (size_t )(const void *)(listener->ext_pickup) == 1) && (__s2_len = __builtin_strlen (listener->ext_pickup), __s2_len < 4 ) ? (__builtin_constant_p (value) && ((size_t)(const void *)((value) + 1) - (size_t)(const void *)(value) == 1) ? __builtin_strcmp (value, listener->ext_pickup) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (value); int __result = (((const unsigned char *) (const char *) (listener->ext_pickup))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (listener->ext_pickup))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (listener->ext_pickup))[2 ] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (listener->ext_pickup ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (value , listener->ext_pickup)))); })) { | |||
1188 | listener->ext_pickup = switch_core_strdup(profile->pool, value)switch_core_perform_strdup(profile->pool, value, "skinny_server.c" , (const char *)__func__, 1188); | |||
1189 | } | |||
1190 | } else if (!strcasecmp(name, "ext-cfwdall")) { | |||
1191 | if (!listener->ext_cfwdall || strcmp(value,listener->ext_cfwdall)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (value) && __builtin_constant_p (listener->ext_cfwdall ) && (__s1_len = __builtin_strlen (value), __s2_len = __builtin_strlen (listener->ext_cfwdall), (!((size_t)(const void *)((value) + 1) - (size_t)(const void *)(value) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((listener ->ext_cfwdall) + 1) - (size_t)(const void *)(listener-> ext_cfwdall) == 1) || __s2_len >= 4)) ? __builtin_strcmp ( value, listener->ext_cfwdall) : (__builtin_constant_p (value ) && ((size_t)(const void *)((value) + 1) - (size_t)( const void *)(value) == 1) && (__s1_len = __builtin_strlen (value), __s1_len < 4) ? (__builtin_constant_p (listener-> ext_cfwdall) && ((size_t)(const void *)((listener-> ext_cfwdall) + 1) - (size_t)(const void *)(listener->ext_cfwdall ) == 1) ? __builtin_strcmp (value, listener->ext_cfwdall) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (listener->ext_cfwdall); int __result = (((const unsigned char *) (const char *) (value))[0] - __s2 [0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[1] - __s2 [1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[2] - __s2 [2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (value))[3] - __s2[ 3]); } } __result; }))) : (__builtin_constant_p (listener-> ext_cfwdall) && ((size_t)(const void *)((listener-> ext_cfwdall) + 1) - (size_t)(const void *)(listener->ext_cfwdall ) == 1) && (__s2_len = __builtin_strlen (listener-> ext_cfwdall), __s2_len < 4) ? (__builtin_constant_p (value ) && ((size_t)(const void *)((value) + 1) - (size_t)( const void *)(value) == 1) ? __builtin_strcmp (value, listener ->ext_cfwdall) : (- (__extension__ ({ const unsigned char * __s2 = (const unsigned char *) (const char *) (value); int __result = (((const unsigned char *) (const char *) (listener->ext_cfwdall ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (listener ->ext_cfwdall))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (listener->ext_cfwdall))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (listener->ext_cfwdall))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (value, listener ->ext_cfwdall)))); })) { | |||
1192 | listener->ext_cfwdall = switch_core_strdup(profile->pool, value)switch_core_perform_strdup(profile->pool, value, "skinny_server.c" , (const char *)__func__, 1192); | |||
1193 | } | |||
1194 | } else if (!strcasecmp(name, "ext-autodial")) { | |||
1195 | if (!listener->ext_autodial || strcmp(value,listener->ext_autodial)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (value) && __builtin_constant_p (listener->ext_autodial ) && (__s1_len = __builtin_strlen (value), __s2_len = __builtin_strlen (listener->ext_autodial), (!((size_t)(const void *)((value) + 1) - (size_t)(const void *)(value) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((listener ->ext_autodial) + 1) - (size_t)(const void *)(listener-> ext_autodial) == 1) || __s2_len >= 4)) ? __builtin_strcmp ( value, listener->ext_autodial) : (__builtin_constant_p (value ) && ((size_t)(const void *)((value) + 1) - (size_t)( const void *)(value) == 1) && (__s1_len = __builtin_strlen (value), __s1_len < 4) ? (__builtin_constant_p (listener-> ext_autodial) && ((size_t)(const void *)((listener-> ext_autodial) + 1) - (size_t)(const void *)(listener->ext_autodial ) == 1) ? __builtin_strcmp (value, listener->ext_autodial) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (listener->ext_autodial); int __result = (((const unsigned char *) (const char *) (value))[0] - __s2 [0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[1] - __s2 [1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (value))[2] - __s2 [2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (value))[3] - __s2[ 3]); } } __result; }))) : (__builtin_constant_p (listener-> ext_autodial) && ((size_t)(const void *)((listener-> ext_autodial) + 1) - (size_t)(const void *)(listener->ext_autodial ) == 1) && (__s2_len = __builtin_strlen (listener-> ext_autodial), __s2_len < 4) ? (__builtin_constant_p (value ) && ((size_t)(const void *)((value) + 1) - (size_t)( const void *)(value) == 1) ? __builtin_strcmp (value, listener ->ext_autodial) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (value); int __result = (((const unsigned char *) (const char *) (listener->ext_autodial ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (listener ->ext_autodial))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (listener->ext_autodial))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (listener->ext_autodial))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (value, listener ->ext_autodial)))); })) { | |||
1196 | listener->ext_autodial = switch_core_strdup(profile->pool, value)switch_core_perform_strdup(profile->pool, value, "skinny_server.c" , (const char *)__func__, 1196); | |||
1197 | } | |||
1198 | } | |||
1199 | } | |||
1200 | } | |||
1201 | if ((xbuttons = switch_xml_child(xskinny, "buttons"))) { | |||
1202 | uint32_t line_instance = 1; | |||
1203 | char *network_ip = inet_ntoa(request->data.reg.ip); | |||
1204 | int network_port = 0; | |||
1205 | char network_port_c[6]; | |||
1206 | snprintf(network_port_c, sizeof(network_port_c), "%d", network_port); | |||
1207 | for (xbutton = switch_xml_child(xbuttons, "button"); xbutton; xbutton = xbutton->next) { | |||
1208 | uint32_t position = atoi(switch_xml_attr_soft(xbutton, "position")); | |||
1209 | uint32_t type = skinny_str2button(switch_xml_attr_soft(xbutton, "type")); | |||
1210 | const char *label = switch_xml_attr_soft(xbutton, "label"); | |||
1211 | const char *value = switch_xml_attr_soft(xbutton, "value"); | |||
1212 | if(type == SKINNY_BUTTON_LINE) { | |||
1213 | const char *caller_name = switch_xml_attr_soft(xbutton, "caller-name"); | |||
1214 | const char *reg_metadata = switch_xml_attr_soft(xbutton, "registration-metadata"); | |||
1215 | uint32_t ring_on_idle = 1; | |||
1216 | uint32_t ring_on_active = 1; | |||
1217 | uint32_t busy_trigger = atoi(switch_xml_attr_soft(xbutton, "busy-trigger")); | |||
1218 | const char *forward_all = switch_xml_attr_soft(xbutton, "forward-all"); | |||
1219 | const char *forward_busy = switch_xml_attr_soft(xbutton, "forward-busy"); | |||
1220 | const char *forward_noanswer = switch_xml_attr_soft(xbutton, "forward-noanswer"); | |||
1221 | uint32_t noanswer_duration = atoi(switch_xml_attr_soft(xbutton, "noanswer-duration")); | |||
1222 | const char *tmp; | |||
1223 | ||||
1224 | tmp = switch_xml_attr_soft(xbutton, "ring-on-active"); | |||
1225 | if ( !zstr(tmp)_zstr(tmp) ) { | |||
1226 | ring_on_active = atoi(tmp); | |||
1227 | } | |||
1228 | ||||
1229 | tmp = switch_xml_attr_soft(xbutton, "ring-on-idle"); | |||
1230 | if ( !zstr(tmp)_zstr(tmp) ) { | |||
1231 | ring_on_idle = atoi(tmp); | |||
1232 | } | |||
1233 | ||||
1234 | if ((sql = switch_mprintf( | |||
1235 | "INSERT INTO skinny_lines " | |||
1236 | "(device_name, device_instance, position, line_instance, " | |||
1237 | "label, value, caller_name, " | |||
1238 | "ring_on_idle, ring_on_active, busy_trigger, " | |||
1239 | "forward_all, forward_busy, forward_noanswer, noanswer_duration) " | |||
1240 | "VALUES('%q', %d, %d, %d, '%q', '%q', '%q', %d, %d, %d, '%q', '%q', '%q', %d)", | |||
1241 | request->data.reg.device_name, request->data.reg.instance, position, line_instance, | |||
1242 | label, value, caller_name, | |||
1243 | ring_on_idle, ring_on_active, busy_trigger, | |||
1244 | forward_all, forward_busy, forward_noanswer, noanswer_duration))) { | |||
1245 | char *token, *url; | |||
1246 | skinny_execute_sql(profile, sql, profile->sql_mutex); | |||
1247 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
1248 | token = switch_mprintf("skinny/%q/%q/%q:%d", profile->name, value, request->data.reg.device_name, request->data.reg.instance); | |||
1249 | url = switch_mprintf("skinny/%q/%q", profile->name, value); | |||
1250 | switch_core_add_registration(value, profile->domain, token, url, 0, network_ip, network_port_c, "tcp", reg_metadata); | |||
1251 | switch_safe_free(token)if (token) {free(token);token=((void*)0);}; | |||
1252 | switch_safe_free(url)if (url) {free(url);url=((void*)0);}; | |||
1253 | } | |||
1254 | if (line_instance == 1) { | |||
1255 | switch_event_t *message_query_event = NULL((void*)0); | |||
1256 | if (switch_event_create(&message_query_event, SWITCH_EVENT_MESSAGE_QUERY)switch_event_create_subclass_detailed("skinny_server.c", (const char * )(const char *)__func__, 1256, &message_query_event , SWITCH_EVENT_MESSAGE_QUERY, ((void*)0)) == SWITCH_STATUS_SUCCESS) { | |||
1257 | switch_event_add_header(message_query_event, SWITCH_STACK_BOTTOM, "Message-Account", "skinny:%s@%s", value, profile->domain); | |||
1258 | switch_event_add_header_string(message_query_event, SWITCH_STACK_BOTTOM, "VM-Skinny-Profile", profile->name); | |||
1259 | switch_event_fire(&message_query_event)switch_event_fire_detailed("skinny_server.c", (const char * ) (const char *)__func__, 1259, &message_query_event, ((void *)0)); | |||
1260 | } | |||
1261 | } | |||
1262 | line_instance++; | |||
1263 | } else { | |||
1264 | const char *settings = switch_xml_attr_soft(xbutton, "settings"); | |||
1265 | if ((sql = switch_mprintf( | |||
1266 | "INSERT INTO skinny_buttons " | |||
1267 | "(device_name, device_instance, position, type, label, value, settings) " | |||
1268 | "VALUES('%q', %d, %d, %d, '%q', '%q', '%q')", | |||
1269 | request->data.reg.device_name, | |||
1270 | request->data.reg.instance, | |||
1271 | position, | |||
1272 | type, | |||
1273 | label, | |||
1274 | value, | |||
1275 | settings))) { | |||
1276 | skinny_execute_sql(profile, sql, profile->sql_mutex); | |||
1277 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
1278 | } | |||
1279 | } | |||
1280 | } | |||
1281 | } | |||
1282 | } | |||
1283 | if (xroot) { | |||
1284 | switch_xml_free(xroot); | |||
1285 | } | |||
1286 | ||||
1287 | status = SWITCH_STATUS_SUCCESS; | |||
1288 | ||||
1289 | /* Reply with RegisterAckMessage */ | |||
1290 | send_register_ack(listener, profile->keep_alive, profile->date_format, "", profile->keep_alive, "")perform_send_register_ack(listener, "skinny_server.c", (const char *)__func__, 1290, profile->keep_alive, profile->date_format , "", profile->keep_alive, ""); | |||
1291 | ||||
1292 | /* Send CapabilitiesReqMessage */ | |||
1293 | send_capabilities_req(listener)perform_send_capabilities_req(listener, "skinny_server.c", (const char *)__func__, 1293); | |||
1294 | ||||
1295 | /* skinny::register event */ | |||
1296 | skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_REGISTER"skinny::register"); | |||
1297 | switch_event_fire(&event)switch_event_fire_detailed("skinny_server.c", (const char * ) (const char *)__func__, 1297, &event, ((void*)0)); | |||
1298 | ||||
1299 | keepalive_listener(listener, NULL((void*)0)); | |||
1300 | ||||
1301 | end: | |||
1302 | if(params) { | |||
1303 | switch_event_destroy(¶ms); | |||
1304 | } | |||
1305 | ||||
1306 | return status; | |||
1307 | } | |||
1308 | ||||
1309 | switch_status_t skinny_handle_port_message(listener_t *listener, skinny_message_t *request) | |||
1310 | { | |||
1311 | char *sql; | |||
1312 | skinny_profile_t *profile; | |||
1313 | ||||
1314 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 1314, __PRETTY_FUNCTION__)); | |||
1315 | switch_assert(listener->device_name)((listener->device_name) ? (void) (0) : __assert_fail ("listener->device_name" , "skinny_server.c", 1315, __PRETTY_FUNCTION__)); | |||
1316 | ||||
1317 | profile = listener->profile; | |||
1318 | ||||
1319 | skinny_check_data_length(request, sizeof(request->data.as_uint16))if (request->length < sizeof(request->data.as_uint16 )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 1319, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.as_uint16 )+4); return SWITCH_STATUS_FALSE; }; | |||
1320 | ||||
1321 | if ((sql = switch_mprintf( | |||
1322 | "UPDATE skinny_devices SET port=%d WHERE name='%q' and instance=%d", | |||
1323 | request->data.port.port, | |||
1324 | listener->device_name, | |||
1325 | listener->device_instance | |||
1326 | ))) { | |||
1327 | skinny_execute_sql(profile, sql, profile->sql_mutex); | |||
1328 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
1329 | } | |||
1330 | return SWITCH_STATUS_SUCCESS; | |||
1331 | } | |||
1332 | ||||
1333 | switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny_message_t *request) | |||
1334 | { | |||
1335 | uint32_t line_instance = 1; | |||
1336 | uint32_t call_id = 0; | |||
1337 | switch_core_session_t *session = NULL((void*)0); | |||
1338 | ||||
1339 | skinny_check_data_length(request, sizeof(request->data.keypad_button.button))if (request->length < sizeof(request->data.keypad_button .button)+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 1339, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.keypad_button .button)+4); return SWITCH_STATUS_FALSE; }; | |||
1340 | ||||
1341 | if(skinny_check_data_length_soft(request, sizeof(request->data.keypad_button))(request->length >= sizeof(request->data.keypad_button )+4)) { | |||
1342 | if (request->data.keypad_button.line_instance > 0) { | |||
1343 | line_instance = request->data.keypad_button.line_instance; | |||
1344 | } | |||
1345 | call_id = request->data.keypad_button.call_id; | |||
1346 | } | |||
1347 | ||||
1348 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
1349 | if ( !session ) | |||
1350 | { | |||
1351 | line_instance = 0; | |||
1352 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, 0); | |||
1353 | } | |||
1354 | ||||
1355 | if(session) { | |||
1356 | switch_channel_t *channel = NULL((void*)0); | |||
1357 | private_t *tech_pvt = NULL((void*)0); | |||
1358 | char digit = '\0'; | |||
1359 | ||||
1360 | channel = switch_core_session_get_channel(session); | |||
1361 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
1362 | ||||
1363 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 1363, (const char*)(session), SWITCH_LOG_DEBUG, "SEND DTMF ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); | |||
1364 | ||||
1365 | if (request->data.keypad_button.button == 14) { | |||
1366 | digit = '*'; | |||
1367 | } else if (request->data.keypad_button.button == 15) { | |||
1368 | digit = '#'; | |||
1369 | } else if (request->data.keypad_button.button <= 9) { /* unsigned, so guaranteed to be >= 0 */ | |||
1370 | digit = '0' + request->data.keypad_button.button; | |||
1371 | } else { | |||
1372 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 1372, (const char*)(session), SWITCH_LOG_WARNING, "UNKNOW DTMF RECEIVED ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); | |||
1373 | } | |||
1374 | ||||
1375 | /* TODO check call_id and line */ | |||
1376 | ||||
1377 | if((skinny_line_get_state(listener, line_instance, tech_pvt->call_id) == SKINNY_OFF_HOOK)) { | |||
1378 | ||||
1379 | skinny_session_process_dest(session, listener, line_instance, NULL((void*)0), digit, 0); | |||
1380 | } else { | |||
1381 | if(digit != '\0') { | |||
1382 | switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0)}; | |||
1383 | dtmf.digit = digit; | |||
1384 | switch_channel_queue_dtmf(channel, &dtmf); | |||
1385 | } | |||
1386 | } | |||
1387 | } | |||
1388 | ||||
1389 | if(session) { | |||
1390 | switch_core_session_rwunlock(session); | |||
1391 | } | |||
1392 | ||||
1393 | return SWITCH_STATUS_SUCCESS; | |||
1394 | } | |||
1395 | ||||
1396 | switch_status_t skinny_handle_enbloc_call_message(listener_t *listener, skinny_message_t *request) | |||
1397 | { | |||
1398 | uint32_t line_instance = 1; | |||
1399 | switch_core_session_t *session = NULL((void*)0); | |||
1400 | ||||
1401 | skinny_check_data_length(request, sizeof(request->data.enbloc_call.called_party))if (request->length < sizeof(request->data.enbloc_call .called_party)+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 1401, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.enbloc_call .called_party)+4); return SWITCH_STATUS_FALSE; }; | |||
1402 | ||||
1403 | if(skinny_check_data_length_soft(request, sizeof(request->data.enbloc_call))(request->length >= sizeof(request->data.enbloc_call )+4)) { | |||
1404 | if (request->data.enbloc_call.line_instance > 0) { | |||
1405 | line_instance = request->data.enbloc_call.line_instance; | |||
1406 | } | |||
1407 | } | |||
1408 | ||||
1409 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, 0); | |||
1410 | ||||
1411 | if(session) { | |||
1412 | skinny_session_process_dest(session, listener, line_instance, request->data.enbloc_call.called_party, '\0', 0); | |||
1413 | switch_core_session_rwunlock(session); | |||
1414 | } | |||
1415 | ||||
1416 | return SWITCH_STATUS_SUCCESS; | |||
1417 | } | |||
1418 | ||||
1419 | switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request) | |||
1420 | { | |||
1421 | switch_status_t status = SWITCH_STATUS_SUCCESS; | |||
1422 | uint32_t line_instance = 0; | |||
1423 | uint32_t call_id = 0; | |||
1424 | switch_core_session_t *session = NULL((void*)0); | |||
1425 | struct speed_dial_stat_res_message *button_speed_dial = NULL((void*)0); | |||
1426 | struct line_stat_res_message *button_line = NULL((void*)0); | |||
1427 | uint32_t line_state; | |||
1428 | ||||
1429 | switch_channel_t *channel = NULL((void*)0); | |||
1430 | ||||
1431 | skinny_check_data_length(request, sizeof(request->data.stimulus)-sizeof(request->data.stimulus.call_id))if (request->length < sizeof(request->data.stimulus) -sizeof(request->data.stimulus.call_id)+4) { switch_log_printf (SWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 1431, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.stimulus )-sizeof(request->data.stimulus.call_id)+4); return SWITCH_STATUS_FALSE ; }; | |||
1432 | ||||
1433 | if(skinny_check_data_length_soft(request, sizeof(request->data.stimulus))(request->length >= sizeof(request->data.stimulus)+4 )) { | |||
1434 | call_id = request->data.stimulus.call_id; | |||
1435 | } | |||
1436 | ||||
1437 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Received stimulus message of type (%s)\n",switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1438, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Received stimulus message of type (%s)\n", (_zstr(listener-> device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, skinny_button2str (request->data.stimulus.instance_type)) | |||
1438 | skinny_button2str(request->data.stimulus.instance_type))switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1438, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Received stimulus message of type (%s)\n", (_zstr(listener-> device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, skinny_button2str (request->data.stimulus.instance_type)); | |||
1439 | ||||
1440 | switch(request->data.stimulus.instance_type) { | |||
1441 | case SKINNY_BUTTON_LAST_NUMBER_REDIAL: | |||
1442 | skinny_create_incoming_session(listener, &line_instance, &session); | |||
1443 | if ( ! session ) { | |||
1444 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle last number redial stimulus message, couldn't create incoming session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1444, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle last number redial stimulus message, couldn't create incoming session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
1445 | return SWITCH_STATUS_FALSE; | |||
1446 | } | |||
1447 | skinny_session_process_dest(session, listener, line_instance, | |||
1448 | empty_null2(listener->ext_redial,listener->profile->ext_redial)((listener->ext_redial)?(listener->ext_redial):((listener ->profile->ext_redial)?(listener->profile->ext_redial ):((void*)0))), '\0', 0); | |||
1449 | break; | |||
1450 | case SKINNY_BUTTON_SPEED_DIAL: | |||
1451 | skinny_speed_dial_get(listener, request->data.stimulus.instance, &button_speed_dial); | |||
1452 | ||||
1453 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, 0); | |||
1454 | if(strlen(button_speed_dial->line) > 0) { | |||
1455 | if ( !session ) { | |||
1456 | skinny_create_incoming_session(listener, &line_instance, &session); | |||
1457 | } | |||
1458 | if ( !session ) { | |||
1459 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle speed dial stimulus message, couldn't create incoming session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1459, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle speed dial stimulus message, couldn't create incoming session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
1460 | return SWITCH_STATUS_FALSE; | |||
1461 | } | |||
1462 | skinny_session_process_dest(session, listener, line_instance, button_speed_dial->line, '\0', 0); | |||
1463 | } | |||
1464 | break; | |||
1465 | case SKINNY_BUTTON_HOLD: | |||
1466 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
1467 | ||||
1468 | if(session) { | |||
1469 | status = skinny_session_hold_line(session, listener, line_instance); | |||
1470 | } | |||
1471 | break; | |||
1472 | case SKINNY_BUTTON_TRANSFER: | |||
1473 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
1474 | ||||
1475 | if(session) { | |||
1476 | status = skinny_session_transfer(session, listener, line_instance); | |||
1477 | } | |||
1478 | break; | |||
1479 | case SKINNY_BUTTON_VOICEMAIL: | |||
1480 | skinny_create_incoming_session(listener, &line_instance, &session); | |||
1481 | if ( ! session ) { | |||
1482 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle stimulus message, couldn't create incoming session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1482, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle stimulus message, couldn't create incoming session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
1483 | return SWITCH_STATUS_FALSE; | |||
1484 | } | |||
1485 | skinny_session_process_dest(session, listener, line_instance, | |||
1486 | empty_null2(listener->ext_voicemail, listener->profile->ext_voicemail)((listener->ext_voicemail)?(listener->ext_voicemail):(( listener->profile->ext_voicemail)?(listener->profile ->ext_voicemail):((void*)0))), '\0', 0); | |||
1487 | break; | |||
1488 | ||||
1489 | case SKINNY_BUTTON_LINE: | |||
1490 | // Get the button data | |||
1491 | skinny_line_get(listener, request->data.stimulus.instance, &button_line); | |||
1492 | ||||
1493 | // Set the button and try to open the incoming session with this | |||
1494 | line_instance = button_line->number; | |||
1495 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
1496 | ||||
1497 | // If session and line match, answer the call | |||
1498 | if ( session && line_instance == button_line->number ) { | |||
1499 | line_state = skinny_line_get_state(listener, line_instance, call_id); | |||
1500 | ||||
1501 | if(line_state == SKINNY_OFF_HOOK) { | |||
1502 | channel = switch_core_session_get_channel(session); | |||
1503 | if (switch_channel_test_flag(channel, CF_HOLD)) { | |||
1504 | switch_ivr_unhold(session); | |||
1505 | } | |||
1506 | ||||
1507 | switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(channel, "skinny_server.c", (const char *)__func__, 1507, SWITCH_CAUSE_NORMAL_CLEARING); | |||
1508 | } | |||
1509 | else { | |||
1510 | status = skinny_session_answer(session, listener, line_instance); | |||
1511 | } | |||
1512 | } | |||
1513 | else { | |||
1514 | if(skinny_check_data_length_soft(request, sizeof(request->data.soft_key_event))(request->length >= sizeof(request->data.soft_key_event )+4)) { | |||
1515 | line_instance = request->data.soft_key_event.line_instance; | |||
1516 | } | |||
1517 | ||||
1518 | skinny_create_incoming_session(listener, &line_instance, &session); | |||
1519 | if ( ! session ) { | |||
1520 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle stimulus message, couldn't create incoming session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1520, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle stimulus message, couldn't create incoming session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
1521 | return SWITCH_STATUS_FALSE; | |||
1522 | } | |||
1523 | skinny_session_process_dest(session, listener, line_instance, NULL((void*)0), '\0', 0); | |||
1524 | } | |||
1525 | break; | |||
1526 | ||||
1527 | default: | |||
1528 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 1528, ((void*)0), SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type); | |||
1529 | } | |||
1530 | ||||
1531 | if(session) { | |||
1532 | switch_core_session_rwunlock(session); | |||
1533 | } | |||
1534 | ||||
1535 | return status; | |||
1536 | } | |||
1537 | ||||
1538 | switch_status_t skinny_handle_off_hook_message(listener_t *listener, skinny_message_t *request) | |||
1539 | { | |||
1540 | uint32_t line_instance = 1; | |||
1541 | uint32_t call_id = 0; | |||
1542 | switch_core_session_t *session = NULL((void*)0); | |||
1543 | private_t *tech_pvt = NULL((void*)0); | |||
1544 | uint32_t line_state; | |||
1545 | ||||
1546 | if(skinny_check_data_length_soft(request, sizeof(request->data.off_hook))(request->length >= sizeof(request->data.off_hook)+4 )) { | |||
1547 | if (request->data.off_hook.line_instance > 0) { | |||
1548 | line_instance = request->data.off_hook.line_instance; | |||
1549 | } | |||
1550 | call_id = request->data.off_hook.call_id; | |||
1551 | } | |||
1552 | ||||
1553 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
1554 | ||||
1555 | line_state = skinny_line_get_state(listener, line_instance, call_id); | |||
1556 | ||||
1557 | if(session && line_state == SKINNY_RING_IN ) { /*answering a call */ | |||
1558 | skinny_session_answer(session, listener, line_instance); | |||
1559 | } else { /* start a new call */ | |||
1560 | skinny_create_incoming_session(listener, &line_instance, &session); | |||
1561 | if ( ! session ) { | |||
1562 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle off hook message, could not create session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1562, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle off hook message, could not create session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
1563 | return SWITCH_STATUS_FALSE; | |||
1564 | } | |||
1565 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
1566 | assert(tech_pvt != NULL)((tech_pvt != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt != ((void*)0)" , "skinny_server.c", 1566, __PRETTY_FUNCTION__)); | |||
1567 | ||||
1568 | skinny_session_process_dest(session, listener, line_instance, NULL((void*)0), '\0', 0); | |||
1569 | } | |||
1570 | ||||
1571 | if(session) { | |||
1572 | switch_core_session_rwunlock(session); | |||
1573 | } | |||
1574 | ||||
1575 | return SWITCH_STATUS_SUCCESS; | |||
1576 | } | |||
1577 | ||||
1578 | switch_status_t skinny_handle_on_hook_message(listener_t *listener, skinny_message_t *request) | |||
1579 | { | |||
1580 | switch_status_t status = SWITCH_STATUS_SUCCESS; | |||
1581 | uint32_t line_instance = 0; | |||
1582 | uint32_t call_id = 0; | |||
1583 | switch_core_session_t *session = NULL((void*)0); | |||
1584 | ||||
1585 | if(skinny_check_data_length_soft(request, sizeof(request->data.on_hook))(request->length >= sizeof(request->data.on_hook)+4)) { | |||
1586 | line_instance = request->data.on_hook.line_instance; | |||
1587 | call_id = request->data.on_hook.call_id; | |||
1588 | } | |||
1589 | ||||
1590 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
1591 | ||||
1592 | if(session) { | |||
1593 | switch_channel_t *channel = NULL((void*)0); | |||
1594 | private_t *tech_pvt = NULL((void*)0); | |||
1595 | ||||
1596 | channel = switch_core_session_get_channel(session); | |||
1597 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
1598 | ||||
1599 | if (tech_pvt->transfer_from_call_id) { /* blind transfer */ | |||
1600 | status = skinny_session_transfer(session, listener, line_instance); | |||
1601 | } else { | |||
1602 | if (skinny_line_get_state(listener, line_instance, call_id) != SKINNY_IN_USE_REMOTELY) { | |||
1603 | switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(channel, "skinny_server.c", (const char *)__func__, 1603, SWITCH_CAUSE_NORMAL_CLEARING); | |||
1604 | } | |||
1605 | } | |||
1606 | } | |||
1607 | ||||
1608 | if(session) { | |||
1609 | switch_core_session_rwunlock(session); | |||
1610 | } | |||
1611 | ||||
1612 | return status; | |||
1613 | } | |||
1614 | switch_status_t skinny_handle_forward_stat_req_message(listener_t *listener, skinny_message_t *request) | |||
1615 | { | |||
1616 | skinny_message_t *message; | |||
1617 | ||||
1618 | skinny_check_data_length(request, sizeof(request->data.forward_stat_req))if (request->length < sizeof(request->data.forward_stat_req )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 1618, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.forward_stat_req )+4); return SWITCH_STATUS_FALSE; }; | |||
1619 | ||||
1620 | skinny_create_message(message, FORWARD_STAT_MESSAGE, forward_stat)message = calloc(1, 12 + sizeof(message->data.forward_stat )); message->type = 0x0090; message->length = 4 + sizeof (message->data.forward_stat); | |||
1621 | ||||
1622 | message->data.forward_stat.line_instance = request->data.forward_stat_req.line_instance; | |||
1623 | ||||
1624 | if ( listener->profile->debug >= 9 ) { | |||
1625 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Handle Forward Stat Req Message with Line Instance (%d)\n",switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1626, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Handle Forward Stat Req Message with Line Instance (%d)\n", (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, request->data.forward_stat_req.line_instance) | |||
1626 | request->data.forward_stat_req.line_instance)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1626, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Handle Forward Stat Req Message with Line Instance (%d)\n", (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, request->data.forward_stat_req.line_instance); | |||
1627 | } | |||
1628 | skinny_send_reply_quiet(listener, message, SWITCH_TRUE)skinny_perform_send_reply_quiet(listener, "skinny_server.c", ( const char *)__func__, 1628, message, SWITCH_TRUE); | |||
1629 | ||||
1630 | return SWITCH_STATUS_SUCCESS; | |||
1631 | } | |||
1632 | ||||
1633 | switch_status_t skinny_handle_speed_dial_stat_request(listener_t *listener, skinny_message_t *request) | |||
1634 | { | |||
1635 | struct speed_dial_stat_res_message *button = NULL((void*)0); | |||
1636 | ||||
1637 | skinny_check_data_length(request, sizeof(request->data.speed_dial_req))if (request->length < sizeof(request->data.speed_dial_req )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 1637, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.speed_dial_req )+4); return SWITCH_STATUS_FALSE; }; | |||
1638 | ||||
1639 | if ( listener->profile->debug >= 9 ) { | |||
1640 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Handle Speed Dial Stat Request for Number (%d)\n", request->data.speed_dial_req.number)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1640, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Handle Speed Dial Stat Request for Number (%d)\n", (_zstr(listener ->device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, request ->data.speed_dial_req.number); | |||
1641 | } | |||
1642 | ||||
1643 | skinny_speed_dial_get(listener, request->data.speed_dial_req.number, &button); | |||
1644 | ||||
1645 | send_speed_dial_stat_res(listener, request->data.speed_dial_req.number, button->line, button->label)perform_send_speed_dial_stat_res(listener, "skinny_server.c", (const char *)__func__, 1645, request->data.speed_dial_req .number, button->line, button->label); | |||
1646 | ||||
1647 | return SWITCH_STATUS_SUCCESS; | |||
1648 | } | |||
1649 | ||||
1650 | switch_status_t skinny_handle_line_stat_request(listener_t *listener, skinny_message_t *request) | |||
1651 | { | |||
1652 | skinny_message_t *message; | |||
1653 | struct line_stat_res_message *button = NULL((void*)0); | |||
1654 | ||||
1655 | skinny_check_data_length(request, sizeof(request->data.line_req))if (request->length < sizeof(request->data.line_req) +4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 1655, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.line_req )+4); return SWITCH_STATUS_FALSE; }; | |||
1656 | ||||
1657 | skinny_create_message(message, LINE_STAT_RES_MESSAGE, line_res)message = calloc(1, 12 + sizeof(message->data.line_res)); message ->type = 0x0092; message->length = 4 + sizeof(message-> data.line_res); | |||
1658 | ||||
1659 | skinny_line_get(listener, request->data.line_req.number, &button); | |||
1660 | ||||
1661 | memcpy(&message->data.line_res, button, sizeof(struct line_stat_res_message)); | |||
1662 | ||||
1663 | skinny_send_reply(listener, message, SWITCH_TRUE)skinny_perform_send_reply(listener, "skinny_server.c", (const char *)__func__, 1663, message, SWITCH_TRUE); | |||
1664 | ||||
1665 | return SWITCH_STATUS_SUCCESS; | |||
1666 | } | |||
1667 | ||||
1668 | int skinny_config_stat_res_callback(void *pArg, int argc, char **argv, char **columnNames) | |||
1669 | { | |||
1670 | skinny_message_t *message = pArg; | |||
1671 | char *device_name = argv[0]; | |||
1672 | int user_id = atoi(argv[1]); | |||
1673 | int instance = atoi(argv[2]); | |||
1674 | char *user_name = argv[3]; | |||
1675 | char *server_name = argv[4]; | |||
1676 | int number_lines = atoi(argv[5]); | |||
1677 | int number_speed_dials = atoi(argv[6]); | |||
1678 | ||||
1679 | switch_copy_string(message->data.config_res.device_name, device_name, 16); | |||
1680 | message->data.config_res.user_id = user_id; | |||
1681 | message->data.config_res.instance = instance; | |||
1682 | switch_copy_string(message->data.config_res.user_name, user_name, 40); | |||
1683 | switch_copy_string(message->data.config_res.server_name, server_name, 40); | |||
1684 | message->data.config_res.number_lines = number_lines; | |||
1685 | message->data.config_res.number_speed_dials = number_speed_dials; | |||
1686 | ||||
1687 | return 0; | |||
1688 | } | |||
1689 | ||||
1690 | switch_status_t skinny_handle_config_stat_request(listener_t *listener, skinny_message_t *request) | |||
1691 | { | |||
1692 | char *sql; | |||
1693 | skinny_message_t *message; | |||
1694 | skinny_profile_t *profile; | |||
1695 | ||||
1696 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 1696, __PRETTY_FUNCTION__)); | |||
1697 | switch_assert(listener->device_name)((listener->device_name) ? (void) (0) : __assert_fail ("listener->device_name" , "skinny_server.c", 1697, __PRETTY_FUNCTION__)); | |||
1698 | ||||
1699 | profile = listener->profile; | |||
1700 | ||||
1701 | skinny_create_message(message, CONFIG_STAT_RES_MESSAGE, config_res)message = calloc(1, 12 + sizeof(message->data.config_res)) ; message->type = 0x0093; message->length = 4 + sizeof( message->data.config_res); | |||
1702 | ||||
1703 | if ((sql = switch_mprintf( | |||
1704 | "SELECT name, user_id, instance, '' AS user_name, '' AS server_name, " | |||
1705 | "(SELECT COUNT(*) FROM skinny_lines WHERE device_name='%s' AND device_instance=%d) AS number_lines, " | |||
1706 | "(SELECT COUNT(*) FROM skinny_buttons WHERE device_name='%s' AND device_instance=%d AND type=%d) AS number_speed_dials " | |||
1707 | "FROM skinny_devices WHERE name='%s' ", | |||
1708 | listener->device_name, | |||
1709 | listener->device_instance, | |||
1710 | listener->device_name, | |||
1711 | listener->device_instance, | |||
1712 | SKINNY_BUTTON_SPEED_DIAL, | |||
1713 | listener->device_name | |||
1714 | ))) { | |||
1715 | skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_config_stat_res_callback, message); | |||
1716 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
1717 | } | |||
1718 | skinny_send_reply(listener, message, SWITCH_TRUE)skinny_perform_send_reply(listener, "skinny_server.c", (const char *)__func__, 1718, message, SWITCH_TRUE); | |||
1719 | ||||
1720 | return SWITCH_STATUS_SUCCESS; | |||
1721 | } | |||
1722 | ||||
1723 | switch_status_t skinny_handle_time_date_request(listener_t *listener, skinny_message_t *request) | |||
1724 | { | |||
1725 | return send_define_current_time_date(listener)perform_send_define_current_time_date(listener, "skinny_server.c" , (const char *)__func__, 1725); | |||
1726 | } | |||
1727 | ||||
1728 | struct button_template_helper { | |||
1729 | skinny_message_t *message; | |||
1730 | int count[SKINNY_BUTTON_UNDEFINED+1]; | |||
1731 | int max_position; | |||
1732 | }; | |||
1733 | ||||
1734 | int skinny_handle_button_template_request_callback(void *pArg, int argc, char **argv, char **columnNames) | |||
1735 | { | |||
1736 | struct button_template_helper *helper = pArg; | |||
1737 | skinny_message_t *message = helper->message; | |||
1738 | /* char *device_name = argv[0]; */ | |||
1739 | /* uint32_t device_instance = argv[1]; */ | |||
1740 | int position = atoi(argv[2]); | |||
1741 | uint32_t type = atoi(argv[3]); | |||
1742 | /* int relative_position = atoi(argv[4]); */ | |||
1743 | ||||
1744 | message->data.button_template.btn[position-1].instance_number = ++helper->count[type]; | |||
1745 | message->data.button_template.btn[position-1].button_definition = type; | |||
1746 | ||||
1747 | message->data.button_template.button_count++; | |||
1748 | message->data.button_template.total_button_count++; | |||
1749 | if(position > helper->max_position) { | |||
1750 | helper->max_position = position; | |||
1751 | } | |||
1752 | ||||
1753 | return 0; | |||
1754 | } | |||
1755 | ||||
1756 | switch_status_t skinny_handle_button_template_request(listener_t *listener, skinny_message_t *request) | |||
1757 | { | |||
1758 | skinny_message_t *message; | |||
1759 | struct button_template_helper helper = {0}; | |||
1760 | skinny_profile_t *profile; | |||
1761 | char *sql; | |||
1762 | int i; | |||
1763 | ||||
1764 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 1764, __PRETTY_FUNCTION__)); | |||
1765 | switch_assert(listener->device_name)((listener->device_name) ? (void) (0) : __assert_fail ("listener->device_name" , "skinny_server.c", 1765, __PRETTY_FUNCTION__)); | |||
1766 | ||||
1767 | profile = listener->profile; | |||
1768 | ||||
1769 | skinny_create_message(message, BUTTON_TEMPLATE_RES_MESSAGE, button_template)message = calloc(1, 12 + sizeof(message->data.button_template )); message->type = 0x0097; message->length = 4 + sizeof (message->data.button_template); | |||
1770 | ||||
1771 | message->data.button_template.button_offset = 0; | |||
1772 | message->data.button_template.button_count = 0; | |||
1773 | message->data.button_template.total_button_count = 0; | |||
1774 | ||||
1775 | helper.message = message; | |||
1776 | ||||
1777 | /* Add buttons */ | |||
1778 | if ((sql = switch_mprintf( | |||
1779 | "SELECT device_name, device_instance, position, type " | |||
1780 | "FROM skinny_buttons " | |||
1781 | "WHERE device_name='%s' AND device_instance=%d " | |||
1782 | "ORDER BY position", | |||
1783 | listener->device_name, listener->device_instance | |||
1784 | ))) { | |||
1785 | skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_handle_button_template_request_callback, &helper); | |||
1786 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
1787 | } | |||
1788 | ||||
1789 | /* Add lines */ | |||
1790 | if ((sql = switch_mprintf( | |||
1791 | "SELECT device_name, device_instance, position, %d AS type " | |||
1792 | "FROM skinny_lines " | |||
1793 | "WHERE device_name='%s' AND device_instance=%d " | |||
1794 | "ORDER BY position", | |||
1795 | SKINNY_BUTTON_LINE, | |||
1796 | listener->device_name, listener->device_instance | |||
1797 | ))) { | |||
1798 | skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_handle_button_template_request_callback, &helper); | |||
1799 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
1800 | } | |||
1801 | ||||
1802 | /* Fill remaining buttons with Undefined */ | |||
1803 | for(i = 0; i+1 < helper.max_position; i++) { | |||
1804 | if(message->data.button_template.btn[i].button_definition == SKINNY_BUTTON_UNKNOWN) { | |||
1805 | message->data.button_template.btn[i].instance_number = ++helper.count[SKINNY_BUTTON_UNDEFINED]; | |||
1806 | message->data.button_template.btn[i].button_definition = SKINNY_BUTTON_UNDEFINED; | |||
1807 | message->data.button_template.button_count++; | |||
1808 | message->data.button_template.total_button_count++; | |||
1809 | } | |||
1810 | } | |||
1811 | ||||
1812 | return skinny_send_reply(listener, message, SWITCH_TRUE)skinny_perform_send_reply(listener, "skinny_server.c", (const char *)__func__, 1812, message, SWITCH_TRUE); | |||
1813 | } | |||
1814 | ||||
1815 | switch_status_t skinny_handle_version_request(listener_t *listener, skinny_message_t *request) | |||
1816 | { | |||
1817 | int saw_entry = 0; | |||
1818 | ||||
1819 | if (zstr(listener->firmware_version)_zstr(listener->firmware_version)) { | |||
1820 | char *id_str; | |||
1821 | skinny_device_type_params_t *params; | |||
1822 | id_str = switch_mprintf("%d", listener->device_type); | |||
1823 | params = (skinny_device_type_params_t *) switch_core_hash_find(listener->profile->device_type_params_hash, id_str); | |||
1824 | if (params) { | |||
1825 | saw_entry = 1; | |||
1826 | ||||
1827 | if (!zstr(params->firmware_version)_zstr(params->firmware_version)) { | |||
1828 | switch_copy_string(listener->firmware_version, params->firmware_version, 16); | |||
1829 | } | |||
1830 | } | |||
1831 | } | |||
1832 | ||||
1833 | if (!zstr(listener->firmware_version)_zstr(listener->firmware_version)) { | |||
1834 | return send_version(listener, listener->firmware_version)perform_send_version(listener, "skinny_server.c", (const char *)__func__, 1834, listener->firmware_version); | |||
1835 | } else if (saw_entry) { | |||
1836 | /* found entry with an empty string */ | |||
1837 | return send_version(listener, "")perform_send_version(listener, "skinny_server.c", (const char *)__func__, 1837, ""); | |||
1838 | } else { | |||
1839 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 1839, ((void*)0), SWITCH_LOG_WARNING, | |||
1840 | "Device %s:%d is requesting for firmware version, but none is set.\n", | |||
1841 | listener->device_name, listener->device_instance); | |||
1842 | ||||
1843 | /* CCM sends back an answer, but with all nulls */ | |||
1844 | return send_version(listener, "")perform_send_version(listener, "skinny_server.c", (const char *)__func__, 1844, ""); | |||
1845 | } | |||
1846 | } | |||
1847 | ||||
1848 | switch_status_t skinny_handle_capabilities_response(listener_t *listener, skinny_message_t *request) | |||
1849 | { | |||
1850 | char *sql; | |||
1851 | skinny_profile_t *profile; | |||
1852 | ||||
1853 | uint32_t i = 0; | |||
1854 | uint32_t n = 0; | |||
1855 | char *codec_order[SWITCH_MAX_CODECS50]; | |||
1856 | char *codec_string; | |||
1857 | ||||
1858 | size_t string_len, string_pos, pos; | |||
1859 | ||||
1860 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 1860, __PRETTY_FUNCTION__)); | |||
1861 | switch_assert(listener->device_name)((listener->device_name) ? (void) (0) : __assert_fail ("listener->device_name" , "skinny_server.c", 1861, __PRETTY_FUNCTION__)); | |||
1862 | ||||
1863 | profile = listener->profile; | |||
1864 | ||||
1865 | skinny_check_data_length(request, sizeof(request->data.cap_res.count))if (request->length < sizeof(request->data.cap_res.count )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 1865, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.cap_res .count)+4); return SWITCH_STATUS_FALSE; }; | |||
1866 | ||||
1867 | n = request->data.cap_res.count; | |||
1868 | if (n > SWITCH_MAX_CODECS50) { | |||
1869 | n = SWITCH_MAX_CODECS50; | |||
1870 | } | |||
1871 | string_len = -1; | |||
1872 | ||||
1873 | skinny_check_data_length(request, sizeof(request->data.cap_res.count) + n * sizeof(request->data.cap_res.caps[0]))if (request->length < sizeof(request->data.cap_res.count ) + n * sizeof(request->data.cap_res.caps[0])+4) { switch_log_printf (SWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 1873, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.cap_res .count) + n * sizeof(request->data.cap_res.caps[0])+4); return SWITCH_STATUS_FALSE; }; | |||
1874 | ||||
1875 | for (i = 0; i < n; i++) { | |||
1876 | char *codec = skinny_codec2string(request->data.cap_res.caps[i].codec); | |||
1877 | codec_order[i] = codec; | |||
1878 | string_len += strlen(codec)+1; | |||
1879 | } | |||
1880 | i = 0; | |||
1881 | pos = 0; | |||
1882 | ||||
1883 | if ( string_len > SKINNY_MAX_STRING16384 ) { | |||
1884 | skinny_log_l_msg(listener, SWITCH_LOG_ERROR, "Codec string list too long.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1884, ((void*)0), SWITCH_LOG_ERROR, "[%s:%d @ %s:%d] " "Codec string list too long.\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port); | |||
1885 | return SWITCH_STATUS_FALSE; | |||
1886 | } | |||
1887 | ||||
1888 | codec_string = calloc(string_len+1,1); | |||
1889 | if ( !codec_string ) { | |||
1890 | skinny_log_l_msg(listener, SWITCH_LOG_ERROR, "Unable to allocate memory for codec string.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1890, ((void*)0), SWITCH_LOG_ERROR, "[%s:%d @ %s:%d] " "Unable to allocate memory for codec string.\n", (_zstr(listener ->device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port); | |||
1891 | return SWITCH_STATUS_FALSE; | |||
1892 | } | |||
1893 | for (string_pos = 0; string_pos < string_len; string_pos++) { | |||
1894 | char *codec = codec_order[i]; | |||
1895 | switch_assert(i < n)((i < n) ? (void) (0) : __assert_fail ("i < n", "skinny_server.c" , 1895, __PRETTY_FUNCTION__)); | |||
1896 | if(pos == strlen(codec)) { | |||
1897 | codec_string[string_pos] = ','; | |||
1898 | i++; | |||
1899 | pos = 0; | |||
1900 | } else { | |||
1901 | codec_string[string_pos] = codec[pos++]; | |||
1902 | } | |||
1903 | } | |||
1904 | codec_string[string_len] = '\0'; | |||
1905 | if ((sql = switch_mprintf( | |||
1906 | "UPDATE skinny_devices SET codec_string='%q' WHERE name='%s'", | |||
1907 | codec_string, | |||
1908 | listener->device_name | |||
1909 | ))) { | |||
1910 | skinny_execute_sql(profile, sql, profile->sql_mutex); | |||
1911 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
1912 | } | |||
1913 | if ( listener->profile->debug >= 9 ) { | |||
1914 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Codecs %s supported.\n", codec_string)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1914, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Codecs %s supported.\n", (_zstr(listener->device_name) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port, codec_string); | |||
1915 | } | |||
1916 | switch_safe_free(codec_string)if (codec_string) {free(codec_string);codec_string=((void*)0) ;}; | |||
1917 | return SWITCH_STATUS_SUCCESS; | |||
1918 | } | |||
1919 | ||||
1920 | switch_status_t skinny_handle_alarm(listener_t *listener, skinny_message_t *request) | |||
1921 | { | |||
1922 | switch_event_t *event = NULL((void*)0); | |||
1923 | ||||
1924 | skinny_check_data_length(request, sizeof(request->data.alarm))if (request->length < sizeof(request->data.alarm)+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 1924, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.alarm) +4); return SWITCH_STATUS_FALSE; }; | |||
1925 | ||||
1926 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n",switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1928, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, request->data.alarm.alarm_severity, request-> data.alarm.display_message, request->data.alarm.alarm_param1 , request->data.alarm.alarm_param2) | |||
1927 | request->data.alarm.alarm_severity, request->data.alarm.display_message,switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1928, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, request->data.alarm.alarm_severity, request-> data.alarm.display_message, request->data.alarm.alarm_param1 , request->data.alarm.alarm_param2) | |||
1928 | request->data.alarm.alarm_param1, request->data.alarm.alarm_param2)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 1928, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, request->data.alarm.alarm_severity, request-> data.alarm.display_message, request->data.alarm.alarm_param1 , request->data.alarm.alarm_param2); | |||
1929 | ||||
1930 | /* skinny::alarm event */ | |||
1931 | skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_ALARM"skinny::alarm"); | |||
1932 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Severity", "%d", request->data.alarm.alarm_severity); | |||
1933 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-DisplayMessage", "%s", request->data.alarm.display_message); | |||
1934 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param1", "%d", request->data.alarm.alarm_param1); | |||
1935 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param2", "%d", request->data.alarm.alarm_param2); | |||
1936 | switch_event_fire(&event)switch_event_fire_detailed("skinny_server.c", (const char * ) (const char *)__func__, 1936, &event, ((void*)0)); | |||
1937 | ||||
1938 | return SWITCH_STATUS_SUCCESS; | |||
1939 | } | |||
1940 | ||||
1941 | switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *listener, skinny_message_t *request) | |||
1942 | { | |||
1943 | switch_status_t status = SWITCH_STATUS_SUCCESS; | |||
1944 | uint32_t line_instance = 0; | |||
1945 | switch_core_session_t *session; | |||
1946 | ||||
1947 | skinny_check_data_length(request, sizeof(request->data.open_receive_channel_ack))if (request->length < sizeof(request->data.open_receive_channel_ack )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 1947, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.open_receive_channel_ack )+4); return SWITCH_STATUS_FALSE; }; | |||
1948 | ||||
1949 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.open_receive_channel_ack.pass_thru_party_id); | |||
1950 | ||||
1951 | if(session) { | |||
1952 | const char *err = NULL((void*)0); | |||
1953 | private_t *tech_pvt = NULL((void*)0); | |||
1954 | switch_channel_t *channel = NULL((void*)0); | |||
1955 | struct in_addr addr; | |||
1956 | switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0}; | |||
1957 | ||||
1958 | tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY ); | |||
1959 | channel = switch_core_session_get_channel(session); | |||
1960 | ||||
1961 | /* Codec */ | |||
1962 | tech_pvt->iananame = "PCMU"; /* TODO */ | |||
1963 | tech_pvt->codec_ms = SKINNY_PTIME20; /* TODO */ | |||
1964 | tech_pvt->rm_rate = 8000; /* TODO */ | |||
1965 | tech_pvt->rm_fmtp = NULL((void*)0); /* TODO */ | |||
1966 | tech_pvt->agreed_pt = (switch_payload_t) 0; /* TODO */ | |||
1967 | tech_pvt->rm_encoding = switch_core_strdup(switch_core_session_get_pool(session), "")switch_core_perform_strdup(switch_core_session_get_pool(session ), "", "skinny_server.c", (const char *)__func__, 1967); | |||
1968 | skinny_tech_set_codec(tech_pvt, 0); | |||
1969 | if ((status = skinny_tech_set_codec(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) { | |||
1970 | goto end; | |||
1971 | } | |||
1972 | ||||
1973 | tech_pvt->local_sdp_audio_ip = listener->local_ip; | |||
1974 | /* Request a local port from the core's allocator */ | |||
1975 | if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(tech_pvt->local_sdp_audio_ip))) { | |||
1976 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 1976, (const char*)(tech_pvt->session), SWITCH_LOG_CRIT, "No RTP ports available!\n"); | |||
1977 | return SWITCH_STATUS_FALSE; | |||
1978 | } | |||
1979 | ||||
1980 | tech_pvt->remote_sdp_audio_ip = inet_ntoa(request->data.open_receive_channel_ack.ip); | |||
1981 | tech_pvt->remote_sdp_audio_port = request->data.open_receive_channel_ack.port; | |||
1982 | ||||
1983 | tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip, | |||
1984 | tech_pvt->local_sdp_audio_port, | |||
1985 | tech_pvt->remote_sdp_audio_ip, | |||
1986 | tech_pvt->remote_sdp_audio_port, | |||
1987 | tech_pvt->agreed_pt, | |||
1988 | tech_pvt->read_impl.samples_per_packet, | |||
1989 | tech_pvt->codec_ms * 1000, | |||
1990 | flags, "soft", &err, | |||
1991 | switch_core_session_get_pool(session)); | |||
1992 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "skinny_server.c", (const char *)__func__ , 1992, (const char*)(tech_pvt->session), SWITCH_LOG_DEBUG, | |||
1993 | "AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n", | |||
1994 | switch_channel_get_name(channel), | |||
1995 | tech_pvt->local_sdp_audio_ip, | |||
1996 | tech_pvt->local_sdp_audio_port, | |||
1997 | tech_pvt->remote_sdp_audio_ip, | |||
1998 | tech_pvt->remote_sdp_audio_port, | |||
1999 | tech_pvt->agreed_pt, | |||
2000 | tech_pvt->read_impl.microseconds_per_packet / 1000, | |||
2001 | switch_rtp_ready(tech_pvt->rtp_session) ? "SUCCESS" : err); | |||
2002 | #ifdef WIN32 | |||
2003 | addr.s_addr = inet_addr(tech_pvt->local_sdp_audio_ip); | |||
2004 | #else | |||
2005 | inet_aton(tech_pvt->local_sdp_audio_ip, &addr); | |||
2006 | #endif | |||
2007 | send_start_media_transmission(listener,perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2008 | tech_pvt->call_id, /* uint32_t conference_id, */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2009 | tech_pvt->party_id, /* uint32_t pass_thru_party_id, */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2010 | addr.s_addr, /* uint32_t remote_ip, */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2011 | tech_pvt->local_sdp_audio_port, /* uint32_t remote_port, */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2012 | SKINNY_PTIME, /* uint32_t ms_per_packet, */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2013 | SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2014 | 184, /* uint32_t precedence, */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2015 | 0, /* uint32_t silence_suppression, */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2016 | 0, /* uint16_t max_frames_per_packet, */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2017 | 0 /* uint32_t g723_bitrate */perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0) | |||
2018 | )perform_send_start_media_transmission(listener,"skinny_server.c" , (const char *)__func__, 2018,tech_pvt->call_id, tech_pvt ->party_id, addr.s_addr, tech_pvt->local_sdp_audio_port , 20, SKINNY_CODEC_ULAW_64K, 184, 0, 0, 0); | |||
2019 | ||||
2020 | switch_set_flag_locked(tech_pvt, TFLAG_IO)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt->flag_mutex != ((void*)0)", "skinny_server.c", 2020, __PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex );(tech_pvt)->flags |= (TFLAG_IO);switch_mutex_unlock(tech_pvt ->flag_mutex);; | |||
2021 | if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { | |||
2022 | switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "skinny_server.c" , (const char *)__func__, 2022); | |||
2023 | } | |||
2024 | if (switch_channel_test_flag(channel, CF_HOLD)) { | |||
2025 | switch_ivr_unhold(session); | |||
2026 | send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON)perform_send_set_lamp(listener, "skinny_server.c", (const char *)__func__, 2026, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON ); | |||
2027 | } | |||
2028 | } else { | |||
2029 | skinny_log_l(listener, SWITCH_LOG_WARNING, "Unable to find session for call id=%d.\n",switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2030, ((void*)0), SWITCH_LOG_WARNING, "[%s:%d @ %s:%d] " "Unable to find session for call id=%d.\n", (_zstr(listener-> device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, request ->data.open_receive_channel_ack.pass_thru_party_id) | |||
2030 | request->data.open_receive_channel_ack.pass_thru_party_id)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2030, ((void*)0), SWITCH_LOG_WARNING, "[%s:%d @ %s:%d] " "Unable to find session for call id=%d.\n", (_zstr(listener-> device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, request ->data.open_receive_channel_ack.pass_thru_party_id); | |||
2031 | } | |||
2032 | end: | |||
2033 | if(session) { | |||
2034 | switch_core_session_rwunlock(session); | |||
2035 | } | |||
2036 | return status; | |||
2037 | } | |||
2038 | ||||
2039 | switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_message_t *request) | |||
2040 | { | |||
2041 | skinny_message_t *message = NULL((void*)0); | |||
2042 | ||||
2043 | if (listener->soft_key_set_set) { | |||
2044 | message = switch_core_hash_find(listener->profile->soft_key_set_sets_hash, listener->soft_key_set_set); | |||
2045 | if ( listener->profile->debug >= 9 ) { | |||
2046 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Handle Soft Key Set Request with Set (%s)\n", listener->soft_key_set_set)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2046, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Handle Soft Key Set Request with Set (%s)\n", (_zstr(listener ->device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, listener ->soft_key_set_set); | |||
2047 | } | |||
2048 | } | |||
2049 | if (!message) { | |||
2050 | message = switch_core_hash_find(listener->profile->soft_key_set_sets_hash, "default"); | |||
2051 | if ( listener->profile->debug >= 9 ) { | |||
2052 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Handle Soft Key Set Request with Set (%s)\n", "default")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2052, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Handle Soft Key Set Request with Set (%s)\n", (_zstr(listener ->device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, "default" ); | |||
2053 | } | |||
2054 | } | |||
2055 | if (message) { | |||
2056 | skinny_send_reply_quiet(listener, message, SWITCH_FALSE)skinny_perform_send_reply_quiet(listener, "skinny_server.c", ( const char *)__func__, 2056, message, SWITCH_FALSE); | |||
2057 | } else { | |||
2058 | skinny_log_l(listener, SWITCH_LOG_ERROR, "Profile %s doesn't have a default <soft-key-set-set>.\n",switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2059, ((void*)0), SWITCH_LOG_ERROR, "[%s:%d @ %s:%d] " "Profile %s doesn't have a default <soft-key-set-set>.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, listener->profile->name) | |||
2059 | listener->profile->name)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2059, ((void*)0), SWITCH_LOG_ERROR, "[%s:%d @ %s:%d] " "Profile %s doesn't have a default <soft-key-set-set>.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, listener->profile->name); | |||
2060 | } | |||
2061 | ||||
2062 | /* Init the states */ | |||
2063 | send_select_soft_keys(listener, 0, 0, SKINNY_KEY_SET_ON_HOOK, 0xffff)perform_send_select_soft_keys(listener, "skinny_server.c", (const char *)__func__, 2063, 0, 0, SKINNY_KEY_SET_ON_HOOK, 0xffff); | |||
2064 | ||||
2065 | return SWITCH_STATUS_SUCCESS; | |||
2066 | } | |||
2067 | ||||
2068 | switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinny_message_t *request) | |||
2069 | { | |||
2070 | switch_status_t status = SWITCH_STATUS_SUCCESS; | |||
2071 | uint32_t line_instance = 0; | |||
2072 | uint32_t call_id = 0; | |||
2073 | switch_core_session_t *session = NULL((void*)0); | |||
2074 | switch_channel_t *channel = NULL((void*)0); | |||
2075 | ||||
2076 | skinny_check_data_length(request, sizeof(request->data.soft_key_event.event))if (request->length < sizeof(request->data.soft_key_event .event)+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2076, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.soft_key_event .event)+4); return SWITCH_STATUS_FALSE; }; | |||
2077 | ||||
2078 | if(skinny_check_data_length_soft(request, sizeof(request->data.soft_key_event))(request->length >= sizeof(request->data.soft_key_event )+4)) { | |||
2079 | line_instance = request->data.soft_key_event.line_instance; | |||
2080 | call_id = request->data.soft_key_event.call_id; | |||
2081 | } | |||
2082 | ||||
2083 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Soft Key Event (%s) with Line Instance (%d), Call ID (%d)\n",switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2084, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Soft Key Event (%s) with Line Instance (%d), Call ID (%d)\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, skinny_soft_key_event2str(request->data.soft_key_event .event), line_instance, call_id) | |||
2084 | skinny_soft_key_event2str(request->data.soft_key_event.event), line_instance, call_id)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2084, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Soft Key Event (%s) with Line Instance (%d), Call ID (%d)\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, skinny_soft_key_event2str(request->data.soft_key_event .event), line_instance, call_id); | |||
2085 | ||||
2086 | switch(request->data.soft_key_event.event) { | |||
2087 | case SOFTKEY_REDIAL: | |||
2088 | status = skinny_create_incoming_session(listener, &line_instance, &session); | |||
2089 | if ( ! session ) { | |||
2090 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle soft key event, could not create incoming session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2090, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle soft key event, could not create incoming session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
2091 | return SWITCH_STATUS_FALSE; | |||
2092 | } | |||
2093 | skinny_session_process_dest(session, listener, line_instance, | |||
2094 | empty_null2(listener->ext_redial,listener->profile->ext_redial)((listener->ext_redial)?(listener->ext_redial):((listener ->profile->ext_redial)?(listener->profile->ext_redial ):((void*)0))), '\0', 0); | |||
2095 | break; | |||
2096 | case SOFTKEY_NEWCALL: | |||
2097 | status = skinny_create_incoming_session(listener, &line_instance, &session); | |||
2098 | if ( ! session ) { | |||
2099 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle soft key event, could not create incoming session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2099, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle soft key event, could not create incoming session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
2100 | return SWITCH_STATUS_FALSE; | |||
2101 | } | |||
2102 | skinny_session_process_dest(session, listener, line_instance, NULL((void*)0), '\0', 0); | |||
2103 | break; | |||
2104 | case SOFTKEY_HOLD: | |||
2105 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
2106 | if(session) { | |||
2107 | status = skinny_session_hold_line(session, listener, line_instance); | |||
2108 | } | |||
2109 | break; | |||
2110 | case SOFTKEY_TRANSFER: | |||
2111 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
2112 | ||||
2113 | if(session) { | |||
2114 | status = skinny_session_transfer(session, listener, line_instance); | |||
2115 | } | |||
2116 | break; | |||
2117 | case SOFTKEY_BACKSPACE: | |||
2118 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
2119 | if(session) { | |||
2120 | skinny_session_process_dest(session, listener, line_instance, NULL((void*)0), '\0', 1); | |||
2121 | } | |||
2122 | break; | |||
2123 | case SOFTKEY_ENDCALL: | |||
2124 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
2125 | if(session) { | |||
2126 | channel = switch_core_session_get_channel(session); | |||
2127 | if (switch_channel_test_flag(channel, CF_HOLD)) { | |||
2128 | switch_ivr_unhold(session); | |||
2129 | } | |||
2130 | switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(channel, "skinny_server.c", (const char *)__func__, 2130, SWITCH_CAUSE_NORMAL_CLEARING); | |||
2131 | } | |||
2132 | break; | |||
2133 | case SOFTKEY_RESUME: | |||
2134 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
2135 | if(session) { | |||
2136 | status = skinny_session_unhold_line(session, listener, line_instance); | |||
2137 | } | |||
2138 | break; | |||
2139 | case SOFTKEY_ANSWER: | |||
2140 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
2141 | if(session) { | |||
2142 | status = skinny_session_answer(session, listener, line_instance); | |||
2143 | } | |||
2144 | break; | |||
2145 | case SOFTKEY_IDIVERT: | |||
2146 | session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); | |||
2147 | if(session) { | |||
2148 | switch_channel_t *channel = NULL((void*)0); | |||
2149 | channel = switch_core_session_get_channel(session); | |||
2150 | ||||
2151 | if (channel) { | |||
2152 | switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER)switch_channel_perform_hangup(channel, "skinny_server.c", (const char *)__func__, 2152, SWITCH_CAUSE_NO_ANSWER); | |||
2153 | } | |||
2154 | } | |||
2155 | break; | |||
2156 | case SOFTKEY_MEETME: | |||
2157 | skinny_create_incoming_session(listener, &line_instance, &session); | |||
2158 | if ( ! session ) { | |||
2159 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle soft key event, could not create incoming session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2159, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle soft key event, could not create incoming session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
2160 | return SWITCH_STATUS_FALSE; | |||
2161 | } | |||
2162 | skinny_session_process_dest(session, listener, line_instance, | |||
2163 | empty_null2(listener->ext_meetme, listener->profile->ext_meetme)((listener->ext_meetme)?(listener->ext_meetme):((listener ->profile->ext_meetme)?(listener->profile->ext_meetme ):((void*)0))), '\0', 0); | |||
2164 | break; | |||
2165 | case SOFTKEY_CALLPICKUP: | |||
2166 | case SOFTKEY_GRPCALLPICKUP: | |||
2167 | skinny_create_incoming_session(listener, &line_instance, &session); | |||
2168 | if ( ! session ) { | |||
2169 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle soft key event, could not create incoming session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2169, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle soft key event, could not create incoming session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
2170 | return SWITCH_STATUS_FALSE; | |||
2171 | } | |||
2172 | skinny_session_process_dest(session, listener, line_instance, | |||
2173 | empty_null2(listener->ext_pickup, listener->profile->ext_pickup)((listener->ext_pickup)?(listener->ext_pickup):((listener ->profile->ext_pickup)?(listener->profile->ext_pickup ):((void*)0))), '\0', 0); | |||
2174 | break; | |||
2175 | case SOFTKEY_CFWDALL: | |||
2176 | skinny_create_incoming_session(listener, &line_instance, &session); | |||
2177 | if ( ! session ) { | |||
2178 | skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle soft key event, could not create incoming session.\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2178, ((void*)0), SWITCH_LOG_CRIT, "[%s:%d @ %s:%d] " "Unable to handle soft key event, could not create incoming session.\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port); | |||
2179 | return SWITCH_STATUS_FALSE; | |||
2180 | } | |||
2181 | skinny_session_process_dest(session, listener, line_instance, | |||
2182 | empty_null2(listener->ext_cfwdall, listener->profile->ext_cfwdall)((listener->ext_cfwdall)?(listener->ext_cfwdall):((listener ->profile->ext_cfwdall)?(listener->profile->ext_cfwdall ):((void*)0))), '\0', 0); | |||
2183 | break; | |||
2184 | default: | |||
2185 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 2185, ((void*)0), SWITCH_LOG_WARNING, | |||
2186 | "Unknown SoftKeyEvent type: %d.\n", request->data.soft_key_event.event); | |||
2187 | } | |||
2188 | ||||
2189 | if(session) { | |||
2190 | switch_core_session_rwunlock(session); | |||
2191 | } | |||
2192 | ||||
2193 | return status; | |||
2194 | } | |||
2195 | ||||
2196 | switch_status_t skinny_handle_unregister(listener_t *listener, skinny_message_t *request) | |||
2197 | { | |||
2198 | switch_event_t *event = NULL((void*)0); | |||
2199 | skinny_message_t *message; | |||
2200 | ||||
2201 | /* skinny::unregister event */ | |||
2202 | skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_UNREGISTER"skinny::unregister"); | |||
2203 | switch_event_fire(&event)switch_event_fire_detailed("skinny_server.c", (const char * ) (const char *)__func__, 2203, &event, ((void*)0)); | |||
2204 | ||||
2205 | skinny_create_message(message, UNREGISTER_ACK_MESSAGE, unregister_ack)message = calloc(1, 12 + sizeof(message->data.unregister_ack )); message->type = 0x0118; message->length = 4 + sizeof (message->data.unregister_ack); | |||
2206 | ||||
2207 | message->data.unregister_ack.unregister_status = 0; /* OK */ | |||
2208 | ||||
2209 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Handle Unregister with Status (%d)\n", message->data.unregister_ack.unregister_status)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2209, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Handle Unregister with Status (%d)\n", (_zstr(listener-> device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, message ->data.unregister_ack.unregister_status); | |||
2210 | ||||
2211 | skinny_send_reply_quiet(listener, message, SWITCH_TRUE)skinny_perform_send_reply_quiet(listener, "skinny_server.c", ( const char *)__func__, 2211, message, SWITCH_TRUE); | |||
2212 | ||||
2213 | /* Close socket */ | |||
2214 | switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags &= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex );; | |||
2215 | ||||
2216 | /* Clear this device from database and any active lines/etc. */ | |||
2217 | skinny_clean_listener_from_db(listener); | |||
2218 | ||||
2219 | return SWITCH_STATUS_SUCCESS; | |||
2220 | } | |||
2221 | ||||
2222 | switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, skinny_message_t *request) | |||
2223 | { | |||
2224 | size_t i; | |||
2225 | skinny_message_t *message; | |||
2226 | ||||
2227 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 2227, __PRETTY_FUNCTION__)); | |||
2228 | switch_assert(listener->device_name)((listener->device_name) ? (void) (0) : __assert_fail ("listener->device_name" , "skinny_server.c", 2228, __PRETTY_FUNCTION__)); | |||
2229 | ||||
2230 | skinny_create_message(message, SOFT_KEY_TEMPLATE_RES_MESSAGE, soft_key_template)message = calloc(1, 12 + sizeof(message->data.soft_key_template )); message->type = 0x0108; message->length = 4 + sizeof (message->data.soft_key_template); | |||
2231 | ||||
2232 | message->data.soft_key_template.soft_key_offset = 0; | |||
2233 | message->data.soft_key_template.soft_key_count = 21; | |||
2234 | message->data.soft_key_template.total_soft_key_count = 21; | |||
2235 | ||||
2236 | for (i=0; i < sizeof(soft_key_template_default_textids)/4; i++) { | |||
2237 | char *label = skinny_textid2raw(soft_key_template_default_textids[i])(soft_key_template_default_textids[i] > 0 ? switch_mprintf ("\200%c", soft_key_template_default_textids[i]) : switch_mprintf ("")); | |||
2238 | switch_copy_string(message->data.soft_key_template.soft_key[i].soft_key_label, label, sizeof(message->data.soft_key_template.soft_key[i].soft_key_label)); | |||
2239 | switch_safe_free(label)if (label) {free(label);label=((void*)0);}; | |||
2240 | ||||
2241 | message->data.soft_key_template.soft_key[i].soft_key_event = soft_key_template_default_events[i]; | |||
2242 | } | |||
2243 | ||||
2244 | if ( listener->profile->debug >= 9 ) { | |||
2245 | skinny_log_l_msg(listener, SWITCH_LOG_DEBUG, "Handle Soft Key Template Request with Default Template\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2245, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Handle Soft Key Template Request with Default Template\n", ( _zstr(listener->device_name) ? "_undef_" : listener->device_name ), listener->device_instance, (_zstr(listener->remote_ip ) ? "_undef_" : listener->remote_ip), listener->remote_port ); | |||
2246 | } | |||
2247 | ||||
2248 | skinny_send_reply_quiet(listener, message, SWITCH_TRUE)skinny_perform_send_reply_quiet(listener, "skinny_server.c", ( const char *)__func__, 2248, message, SWITCH_TRUE); | |||
2249 | ||||
2250 | return SWITCH_STATUS_SUCCESS; | |||
2251 | } | |||
2252 | ||||
2253 | switch_status_t skinny_headset_status_message(listener_t *listener, skinny_message_t *request) | |||
2254 | { | |||
2255 | char *sql; | |||
2256 | ||||
2257 | skinny_check_data_length(request, sizeof(request->data.headset_status))if (request->length < sizeof(request->data.headset_status )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2257, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.headset_status )+4); return SWITCH_STATUS_FALSE; }; | |||
2258 | ||||
2259 | if ((sql = switch_mprintf( | |||
2260 | "UPDATE skinny_devices SET headset=%d WHERE name='%q' and instance=%d", | |||
2261 | (request->data.headset_status.mode==1) ? SKINNY_ACCESSORY_STATE_OFFHOOK : SKINNY_ACCESSORY_STATE_ONHOOK, | |||
2262 | listener->device_name, | |||
2263 | listener->device_instance | |||
2264 | ))) { | |||
2265 | skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); | |||
2266 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
2267 | } | |||
2268 | ||||
2269 | if ( listener->profile->debug >= 9 ) { | |||
2270 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Update headset accessory status (%s)\n",switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2271, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Update headset accessory status (%s)\n", (_zstr(listener-> device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, skinny_accessory_state2str (request->data.headset_status.mode)) | |||
2271 | skinny_accessory_state2str(request->data.headset_status.mode))switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2271, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Update headset accessory status (%s)\n", (_zstr(listener-> device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, skinny_accessory_state2str (request->data.headset_status.mode)); | |||
2272 | } | |||
2273 | ||||
2274 | return SWITCH_STATUS_SUCCESS; | |||
2275 | } | |||
2276 | ||||
2277 | switch_status_t skinny_handle_media_resource_message(listener_t *listener, skinny_message_t *request) | |||
2278 | { | |||
2279 | skinny_check_data_length(request, sizeof(request->data.media_resource))if (request->length < sizeof(request->data.media_resource )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2279, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.media_resource )+4); return SWITCH_STATUS_FALSE; }; | |||
2280 | ||||
2281 | skinny_log_l_msg(listener, SWITCH_LOG_DEBUG, "Handle Media Resource Notification\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2281, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Handle Media Resource Notification\n", (_zstr(listener-> device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port); | |||
2282 | ||||
2283 | /* Do nothing */ | |||
2284 | return SWITCH_STATUS_SUCCESS; | |||
2285 | } | |||
2286 | ||||
2287 | switch_status_t skinny_handle_register_available_lines_message(listener_t *listener, skinny_message_t *request) | |||
2288 | { | |||
2289 | skinny_check_data_length(request, sizeof(request->data.reg_lines))if (request->length < sizeof(request->data.reg_lines )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2289, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.reg_lines )+4); return SWITCH_STATUS_FALSE; }; | |||
2290 | ||||
2291 | if ( listener->profile->debug >= 9 ) { | |||
2292 | skinny_log_l_msg(listener, SWITCH_LOG_DEBUG, "Handle Register Available Lines\n")switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2292, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Handle Register Available Lines\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port); | |||
2293 | } | |||
2294 | ||||
2295 | /* Do nothing */ | |||
2296 | return SWITCH_STATUS_SUCCESS; | |||
2297 | } | |||
2298 | ||||
2299 | switch_status_t skinny_handle_data_message(listener_t *listener, skinny_message_t *request) | |||
2300 | { | |||
2301 | switch_event_t *event = NULL((void*)0); | |||
2302 | char *tmp = NULL((void*)0); | |||
2303 | skinny_check_data_length(request, sizeof(request->data.data))if (request->length < sizeof(request->data.data)+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2303, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.data)+ 4); return SWITCH_STATUS_FALSE; }; | |||
2304 | skinny_check_data_length(request, sizeof(request->data.data) + request->data.data.data_length - 1)if (request->length < sizeof(request->data.data) + request ->data.data.data_length - 1 +4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG , "skinny_server.c", (const char *)__func__, 2304, ((void*)0) , SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.data) + request->data.data.data_length - 1 +4); return SWITCH_STATUS_FALSE ; }; | |||
2305 | ||||
2306 | /* skinny::device_to_user event */ | |||
2307 | skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER"skinny::device_to_user"); | |||
2308 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type); | |||
2309 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type)); | |||
2310 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.data.application_id); | |||
2311 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.data.line_instance); | |||
2312 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.data.call_id); | |||
2313 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.data.transaction_id); | |||
2314 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.data.data_length); | |||
2315 | ||||
2316 | tmp = malloc(request->data.data.data_length + 1); | |||
2317 | memcpy(tmp, request->data.data.data, request->data.data.data_length); | |||
2318 | ||||
2319 | /* Ensure that the body is null-terminated */ | |||
2320 | tmp[request->data.data.data_length] = '\0'; | |||
2321 | switch_event_add_body(event, "%s", tmp); | |||
2322 | ||||
2323 | switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);}; | |||
2324 | ||||
2325 | switch_event_fire(&event)switch_event_fire_detailed("skinny_server.c", (const char * ) (const char *)__func__, 2325, &event, ((void*)0)); | |||
2326 | ||||
2327 | return SWITCH_STATUS_SUCCESS; | |||
2328 | } | |||
2329 | ||||
2330 | switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request) | |||
2331 | { | |||
2332 | skinny_message_t *message; | |||
2333 | struct service_url_stat_res_message *button = NULL((void*)0); | |||
2334 | ||||
2335 | skinny_check_data_length(request, sizeof(request->data.service_url_req))if (request->length < sizeof(request->data.service_url_req )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2335, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.service_url_req )+4); return SWITCH_STATUS_FALSE; }; | |||
2336 | ||||
2337 | skinny_create_message(message, SERVICE_URL_STAT_RES_MESSAGE, service_url_res)message = calloc(1, 12 + sizeof(message->data.service_url_res )); message->type = 0x012F; message->length = 4 + sizeof (message->data.service_url_res); | |||
2338 | ||||
2339 | skinny_service_url_get(listener, request->data.service_url_req.service_url_index, &button); | |||
2340 | ||||
2341 | memcpy(&message->data.service_url_res, button, sizeof(struct service_url_stat_res_message)); | |||
2342 | ||||
2343 | skinny_send_reply(listener, message, SWITCH_TRUE)skinny_perform_send_reply(listener, "skinny_server.c", (const char *)__func__, 2343, message, SWITCH_TRUE); | |||
2344 | ||||
2345 | return SWITCH_STATUS_SUCCESS; | |||
2346 | } | |||
2347 | ||||
2348 | switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_message_t *request) | |||
2349 | { | |||
2350 | skinny_message_t *message; | |||
2351 | struct feature_stat_res_message *button = NULL((void*)0); | |||
2352 | ||||
2353 | skinny_check_data_length(request, sizeof(request->data.feature_req))if (request->length < sizeof(request->data.feature_req )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2353, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.feature_req )+4); return SWITCH_STATUS_FALSE; }; | |||
2354 | ||||
2355 | skinny_create_message(message, FEATURE_STAT_RES_MESSAGE, feature_res)message = calloc(1, 12 + sizeof(message->data.feature_res) ); message->type = 0x011F; message->length = 4 + sizeof (message->data.feature_res); | |||
2356 | ||||
2357 | skinny_feature_get(listener, request->data.feature_req.feature_index, &button); | |||
2358 | ||||
2359 | memcpy(&message->data.feature_res, button, sizeof(struct feature_stat_res_message)); | |||
2360 | ||||
2361 | skinny_send_reply(listener, message, SWITCH_TRUE)skinny_perform_send_reply(listener, "skinny_server.c", (const char *)__func__, 2361, message, SWITCH_TRUE); | |||
2362 | ||||
2363 | return SWITCH_STATUS_SUCCESS; | |||
2364 | } | |||
2365 | ||||
2366 | switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny_message_t *request) | |||
2367 | { | |||
2368 | switch_event_t *event = NULL((void*)0); | |||
2369 | char *tmp = NULL((void*)0); | |||
2370 | skinny_check_data_length(request, sizeof(request->data.extended_data))if (request->length < sizeof(request->data.extended_data )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2370, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.extended_data )+4); return SWITCH_STATUS_FALSE; }; | |||
2371 | skinny_check_data_length(request, sizeof(request->data.extended_data)+request->data.extended_data.data_length-1)if (request->length < sizeof(request->data.extended_data )+request->data.extended_data.data_length-1 +4) { switch_log_printf (SWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 2371, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.extended_data )+request->data.extended_data.data_length-1 +4); return SWITCH_STATUS_FALSE ; }; | |||
2372 | ||||
2373 | /* skinny::device_to_user event */ | |||
2374 | skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER"skinny::device_to_user"); | |||
2375 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type); | |||
2376 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type)); | |||
2377 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.extended_data.application_id); | |||
2378 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.extended_data.line_instance); | |||
2379 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.extended_data.call_id); | |||
2380 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.extended_data.transaction_id); | |||
2381 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.extended_data.data_length); | |||
2382 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Sequence-Flag", "%d", request->data.extended_data.sequence_flag); | |||
2383 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Display-Priority", "%d", request->data.extended_data.display_priority); | |||
2384 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Conference-Id", "%d", request->data.extended_data.conference_id); | |||
2385 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-App-Instance-Id", "%d", request->data.extended_data.app_instance_id); | |||
2386 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Routing-Id", "%d", request->data.extended_data.routing_id); | |||
2387 | ||||
2388 | tmp = malloc(request->data.data.data_length + 1); | |||
2389 | memcpy(tmp, request->data.data.data, request->data.data.data_length); | |||
2390 | ||||
2391 | /* Ensure that the body is null-terminated */ | |||
2392 | tmp[request->data.data.data_length] = '\0'; | |||
2393 | switch_event_add_body(event, "%s", tmp); | |||
2394 | ||||
2395 | switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);}; | |||
2396 | switch_event_fire(&event)switch_event_fire_detailed("skinny_server.c", (const char * ) (const char *)__func__, 2396, &event, ((void*)0)); | |||
2397 | ||||
2398 | return SWITCH_STATUS_SUCCESS; | |||
2399 | } | |||
2400 | ||||
2401 | switch_status_t skinny_handle_dialed_phone_book_message(listener_t *listener, skinny_message_t *request) | |||
2402 | { | |||
2403 | skinny_message_t *message; | |||
2404 | ||||
2405 | skinny_check_data_length(request, sizeof(request->data.dialed_phone_book))if (request->length < sizeof(request->data.dialed_phone_book )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2405, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.dialed_phone_book )+4); return SWITCH_STATUS_FALSE; }; | |||
2406 | ||||
2407 | skinny_create_message(message, DIALED_PHONE_BOOK_ACK_MESSAGE, dialed_phone_book_ack)message = calloc(1, 12 + sizeof(message->data.dialed_phone_book_ack )); message->type = 0x0152; message->length = 4 + sizeof (message->data.dialed_phone_book_ack); | |||
2408 | ||||
2409 | message->data.dialed_phone_book_ack.number_index = request->data.dialed_phone_book.number_index; | |||
2410 | message->data.dialed_phone_book_ack.line_instance = request->data.dialed_phone_book.line_instance; | |||
2411 | message->data.dialed_phone_book_ack.unknown = request->data.dialed_phone_book.unknown; | |||
2412 | message->data.dialed_phone_book_ack.unknown2 = 0; | |||
2413 | ||||
2414 | #if 0 | |||
2415 | /* Not sure why this isn't being sent at this point, need to investigate */ | |||
2416 | skinny_log_l_ffl(listener, file, func, line, SWITCH_LOG_DEBUG,switch_log_printf( SWITCH_CHANNEL_ID_LOG, file, func, line, ( (void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Sending Handle Dialed Phone Book Ack Message with Number Index (%d), Line Instance (%d)\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, request->data.dialed_phone_book.number_index, request->data.dialed_phone_book.line_instance) | |||
2417 | "Sending Handle Dialed Phone Book Ack Message with Number Index (%d), Line Instance (%d)\n",switch_log_printf( SWITCH_CHANNEL_ID_LOG, file, func, line, ( (void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Sending Handle Dialed Phone Book Ack Message with Number Index (%d), Line Instance (%d)\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, request->data.dialed_phone_book.number_index, request->data.dialed_phone_book.line_instance) | |||
2418 | request->data.dialed_phone_book.number_index, request->data.dialed_phone_book.line_instance)switch_log_printf( SWITCH_CHANNEL_ID_LOG, file, func, line, ( (void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Sending Handle Dialed Phone Book Ack Message with Number Index (%d), Line Instance (%d)\n" , (_zstr(listener->device_name) ? "_undef_" : listener-> device_name), listener->device_instance, (_zstr(listener-> remote_ip) ? "_undef_" : listener->remote_ip), listener-> remote_port, request->data.dialed_phone_book.number_index, request->data.dialed_phone_book.line_instance); | |||
2419 | ||||
2420 | return skinny_send_reply_quiet(listener, message, SWITCH_TRUE)skinny_perform_send_reply_quiet(listener, "skinny_server.c", ( const char *)__func__, 2420, message, SWITCH_TRUE); | |||
2421 | #else | |||
2422 | switch_safe_free(message)if (message) {free(message);message=((void*)0);}; | |||
2423 | return SWITCH_STATUS_SUCCESS; | |||
2424 | #endif | |||
2425 | } | |||
2426 | ||||
2427 | switch_status_t skinny_handle_accessory_status_message(listener_t *listener, skinny_message_t *request) | |||
2428 | { | |||
2429 | char *sql; | |||
2430 | ||||
2431 | skinny_check_data_length(request, sizeof(request->data.accessory_status))if (request->length < sizeof(request->data.accessory_status )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2431, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.accessory_status )+4); return SWITCH_STATUS_FALSE; }; | |||
2432 | ||||
2433 | switch(request->data.accessory_status.accessory_id) { | |||
2434 | case SKINNY_ACCESSORY_HEADSET: | |||
2435 | if ((sql = switch_mprintf( | |||
2436 | "UPDATE skinny_devices SET headset=%d WHERE name='%q' and instance=%d", | |||
2437 | request->data.accessory_status.accessory_status, | |||
2438 | listener->device_name, | |||
2439 | listener->device_instance | |||
2440 | ))) { | |||
2441 | skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); | |||
2442 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
2443 | } | |||
2444 | break; | |||
2445 | case SKINNY_ACCESSORY_HANDSET: | |||
2446 | if ((sql = switch_mprintf( | |||
2447 | "UPDATE skinny_devices SET handset=%d WHERE name='%q' and instance=%d", | |||
2448 | request->data.accessory_status.accessory_status, | |||
2449 | listener->device_name, | |||
2450 | listener->device_instance | |||
2451 | ))) { | |||
2452 | skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); | |||
2453 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
2454 | } | |||
2455 | break; | |||
2456 | case SKINNY_ACCESSORY_SPEAKER: | |||
2457 | if ((sql = switch_mprintf( | |||
2458 | "UPDATE skinny_devices SET speaker=%d WHERE name='%q' and instance=%d", | |||
2459 | request->data.accessory_status.accessory_status, | |||
2460 | listener->device_name, | |||
2461 | listener->device_instance | |||
2462 | ))) { | |||
2463 | skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); | |||
2464 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
2465 | } | |||
2466 | break; | |||
2467 | } | |||
2468 | ||||
2469 | return SWITCH_STATUS_SUCCESS; | |||
2470 | } | |||
2471 | ||||
2472 | switch_status_t skinny_handle_updatecapabilities(listener_t *listener, skinny_message_t *request) | |||
2473 | { | |||
2474 | char *sql; | |||
2475 | skinny_profile_t *profile; | |||
2476 | ||||
2477 | uint32_t i = 0; | |||
2478 | uint32_t n = 0; | |||
2479 | char *codec_order[SKINNY_MAX_CAPABILITIES18]; | |||
2480 | char *codec_string; | |||
2481 | ||||
2482 | size_t string_len, string_pos, pos; | |||
2483 | ||||
2484 | switch_assert(listener->profile)((listener->profile) ? (void) (0) : __assert_fail ("listener->profile" , "skinny_server.c", 2484, __PRETTY_FUNCTION__)); | |||
2485 | switch_assert(listener->device_name)((listener->device_name) ? (void) (0) : __assert_fail ("listener->device_name" , "skinny_server.c", 2485, __PRETTY_FUNCTION__)); | |||
2486 | ||||
2487 | profile = listener->profile; | |||
2488 | ||||
2489 | skinny_check_data_length(request, sizeof(request->data.upd_cap.audio_cap_count))if (request->length < sizeof(request->data.upd_cap.audio_cap_count )+4) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c" , (const char *)__func__, 2489, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.upd_cap .audio_cap_count)+4); return SWITCH_STATUS_FALSE; }; | |||
2490 | ||||
2491 | n = request->data.upd_cap.audio_cap_count; | |||
2492 | if (n > SKINNY_MAX_CAPABILITIES18) { | |||
2493 | n = SKINNY_MAX_CAPABILITIES18; | |||
2494 | } | |||
2495 | string_len = -1; | |||
2496 | ||||
2497 | skinny_check_data_length(request, sizeof(request->data.upd_cap.audio_cap_count) + n * sizeof(request->data.upd_cap.audioCaps[0]))if (request->length < sizeof(request->data.upd_cap.audio_cap_count ) + n * sizeof(request->data.upd_cap.audioCaps[0])+4) { switch_log_printf (SWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 2497, ((void*)0), SWITCH_LOG_ERROR, "Received Too Short Skinny Message %s (type=%x,length=%d), expected %" "ld" ".\n", skinny_message_type2str(request->type), request ->type, request->length, sizeof(request->data.upd_cap .audio_cap_count) + n * sizeof(request->data.upd_cap.audioCaps [0])+4); return SWITCH_STATUS_FALSE; }; | |||
2498 | ||||
2499 | for (i = 0; i < n; i++) { | |||
2500 | char *codec = skinny_codec2string(request->data.upd_cap.audioCaps[i].payload_capability); | |||
2501 | codec_order[i] = codec; | |||
2502 | string_len += strlen(codec)+1; | |||
2503 | } | |||
2504 | i = 0; | |||
2505 | pos = 0; | |||
2506 | codec_string = switch_core_alloc(listener->pool, string_len+1)switch_core_perform_alloc(listener->pool, string_len+1, "skinny_server.c" , (const char *)__func__, 2506); | |||
2507 | for (string_pos = 0; string_pos < string_len; string_pos++) { | |||
2508 | char *codec = codec_order[i]; | |||
| ||||
2509 | switch_assert(i < n)((i < n) ? (void) (0) : __assert_fail ("i < n", "skinny_server.c" , 2509, __PRETTY_FUNCTION__)); | |||
2510 | if(pos == strlen(codec)) { | |||
2511 | codec_string[string_pos] = ','; | |||
2512 | i++; | |||
2513 | pos = 0; | |||
2514 | } else { | |||
2515 | codec_string[string_pos] = codec[pos++]; | |||
2516 | } | |||
2517 | } | |||
2518 | codec_string[string_len] = '\0'; | |||
2519 | if ((sql = switch_mprintf( | |||
2520 | "UPDATE skinny_devices SET codec_string='%q' WHERE name='%q'", | |||
2521 | codec_string, | |||
2522 | listener->device_name | |||
2523 | ))) { | |||
2524 | skinny_execute_sql(profile, sql, profile->sql_mutex); | |||
2525 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||
2526 | } | |||
2527 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 2527, ((void*)0), SWITCH_LOG_DEBUG, | |||
2528 | "Codecs %s supported.\n", codec_string); | |||
2529 | return SWITCH_STATUS_SUCCESS; | |||
2530 | } | |||
2531 | ||||
2532 | ||||
2533 | switch_status_t skinny_handle_server_req_message(listener_t *listener, skinny_message_t *request) | |||
2534 | { | |||
2535 | skinny_profile_t *profile; | |||
2536 | ||||
2537 | profile = listener->profile; | |||
2538 | ||||
2539 | skinny_log_l(listener, SWITCH_LOG_INFO, "Received Server Request Message (length=%d).\n", request->length)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2539, ((void*)0), SWITCH_LOG_INFO, "[%s:%d @ %s:%d] " "Received Server Request Message (length=%d).\n", (_zstr(listener ->device_name) ? "_undef_" : listener->device_name), listener ->device_instance, (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip), listener->remote_port, request ->length); | |||
2540 | ||||
2541 | send_srvreq_response(listener, profile->ip, profile->port)perform_send_srvreq_response(listener, "skinny_server.c", (const char *)__func__, 2541, profile->ip, profile->port); | |||
2542 | return SWITCH_STATUS_SUCCESS; | |||
2543 | } | |||
2544 | ||||
2545 | switch_status_t skinny_handle_xml_alarm(listener_t *listener, skinny_message_t *request) | |||
2546 | { | |||
2547 | switch_event_t *event = NULL((void*)0); | |||
2548 | char *tmp = NULL((void*)0); | |||
2549 | ||||
2550 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Received XML alarm (length=%d).\n", request->length)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2550, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Received XML alarm (length=%d).\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port, request->length); | |||
2551 | /* skinny::xml_alarm event */ | |||
2552 | skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_XML_ALARM"skinny::xml_alarm"); | |||
2553 | /* Ensure that the body is null-terminated */ | |||
2554 | tmp = malloc(request->length - 4 + 1); | |||
2555 | memcpy(tmp, request->data.as_char, request->length - 4); | |||
2556 | tmp[request->length - 4] = '\0'; | |||
2557 | switch_event_add_body(event, "%s", tmp); | |||
2558 | switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);}; | |||
2559 | switch_event_fire(&event)switch_event_fire_detailed("skinny_server.c", (const char * ) (const char *)__func__, 2559, &event, ((void*)0)); | |||
2560 | ||||
2561 | return SWITCH_STATUS_SUCCESS; | |||
2562 | } | |||
2563 | ||||
2564 | switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request) | |||
2565 | { | |||
2566 | if (listener->profile->debug >= 10 || | |||
2567 | (listener->profile->debug >= 9 && request->type != KEEP_ALIVE_MESSAGE0x0000)) { | |||
2568 | skinny_log_l(listener, SWITCH_LOG_DEBUG, "Received %s (type=%x,length=%d).\n",switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2569, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Received %s (type=%x,length=%d).\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port, skinny_message_type2str(request-> type), request->type, request->length) | |||
2569 | skinny_message_type2str(request->type), request->type, request->length)switch_log_printf(SWITCH_CHANNEL_ID_LOG, "skinny_server.c", ( const char *)__func__, 2569, ((void*)0), SWITCH_LOG_DEBUG, "[%s:%d @ %s:%d] " "Received %s (type=%x,length=%d).\n", (_zstr(listener->device_name ) ? "_undef_" : listener->device_name), listener->device_instance , (_zstr(listener->remote_ip) ? "_undef_" : listener->remote_ip ), listener->remote_port, skinny_message_type2str(request-> type), request->type, request->length); | |||
2570 | } | |||
2571 | if(zstr(listener->device_name)_zstr(listener->device_name) && request->type != REGISTER_MESSAGE0x0001 && request->type != ALARM_MESSAGE0x0020 && request->type != XML_ALARM_MESSAGE0x015A && request->type != KEEP_ALIVE_MESSAGE0x0000) { | |||
2572 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 2572, ((void*)0), SWITCH_LOG_WARNING, | |||
2573 | "Device should send a register message first. Received %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); | |||
2574 | return SWITCH_STATUS_FALSE; | |||
2575 | } | |||
2576 | switch(request->type) { | |||
| ||||
2577 | case KEEP_ALIVE_MESSAGE0x0000: | |||
2578 | return skinny_handle_keep_alive_message(listener, request); | |||
2579 | case REGISTER_MESSAGE0x0001: | |||
2580 | return skinny_handle_register(listener, request); | |||
2581 | case PORT_MESSAGE0x0002: | |||
2582 | return skinny_handle_port_message(listener, request); | |||
2583 | case KEYPAD_BUTTON_MESSAGE0x0003: | |||
2584 | return skinny_handle_keypad_button_message(listener, request); | |||
2585 | case ENBLOC_CALL_MESSAGE0x0004: | |||
2586 | return skinny_handle_enbloc_call_message(listener, request); | |||
2587 | case STIMULUS_MESSAGE0x0005: | |||
2588 | return skinny_handle_stimulus_message(listener, request); | |||
2589 | case OFF_HOOK_MESSAGE0x0006: | |||
2590 | return skinny_handle_off_hook_message(listener, request); | |||
2591 | case ON_HOOK_MESSAGE0x0007: | |||
2592 | return skinny_handle_on_hook_message(listener, request); | |||
2593 | case FORWARD_STAT_REQ_MESSAGE0x0009: | |||
2594 | return skinny_handle_forward_stat_req_message(listener, request); | |||
2595 | case SPEED_DIAL_STAT_REQ_MESSAGE0x000A: | |||
2596 | return skinny_handle_speed_dial_stat_request(listener, request); | |||
2597 | case LINE_STAT_REQ_MESSAGE0x000B: | |||
2598 | return skinny_handle_line_stat_request(listener, request); | |||
2599 | case CONFIG_STAT_REQ_MESSAGE0x000C: | |||
2600 | return skinny_handle_config_stat_request(listener, request); | |||
2601 | case TIME_DATE_REQ_MESSAGE0x000D: | |||
2602 | return skinny_handle_time_date_request(listener, request); | |||
2603 | case BUTTON_TEMPLATE_REQ_MESSAGE0x000E: | |||
2604 | return skinny_handle_button_template_request(listener, request); | |||
2605 | case VERSION_REQ_MESSAGE0x000F: | |||
2606 | return skinny_handle_version_request(listener, request); | |||
2607 | case CAPABILITIES_RES_MESSAGE0x0010: | |||
2608 | return skinny_handle_capabilities_response(listener, request); | |||
2609 | case ALARM_MESSAGE0x0020: | |||
2610 | return skinny_handle_alarm(listener, request); | |||
2611 | case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE0x0022: | |||
2612 | return skinny_handle_open_receive_channel_ack_message(listener, request); | |||
2613 | case SOFT_KEY_SET_REQ_MESSAGE0x0025: | |||
2614 | return skinny_handle_soft_key_set_request(listener, request); | |||
2615 | case SOFT_KEY_EVENT_MESSAGE0x0026: | |||
2616 | return skinny_handle_soft_key_event_message(listener, request); | |||
2617 | case UNREGISTER_MESSAGE0x0027: | |||
2618 | return skinny_handle_unregister(listener, request); | |||
2619 | case SOFT_KEY_TEMPLATE_REQ_MESSAGE0x0028: | |||
2620 | return skinny_handle_soft_key_template_request(listener, request); | |||
2621 | case MEDIA_RESOURCE_MESSAGE0x002C: | |||
2622 | return skinny_handle_media_resource_message(listener, request); | |||
2623 | case HEADSET_STATUS_MESSAGE0x002B: | |||
2624 | return skinny_headset_status_message(listener, request); | |||
2625 | case REGISTER_AVAILABLE_LINES_MESSAGE0x002D: | |||
2626 | return skinny_handle_register_available_lines_message(listener, request); | |||
2627 | case DEVICE_TO_USER_DATA_MESSAGE0x002E: | |||
2628 | return skinny_handle_data_message(listener, request); | |||
2629 | case DEVICE_TO_USER_DATA_RESPONSE_MESSAGE0x002F: | |||
2630 | return skinny_handle_data_message(listener, request); | |||
2631 | case SERVICE_URL_STAT_REQ_MESSAGE0x0033: | |||
2632 | return skinny_handle_service_url_stat_request(listener, request); | |||
2633 | case FEATURE_STAT_REQ_MESSAGE0x0034: | |||
2634 | return skinny_handle_feature_stat_request(listener, request); | |||
2635 | case DEVICE_TO_USER_DATA_VERSION1_MESSAGE0x0041: | |||
2636 | return skinny_handle_extended_data_message(listener, request); | |||
2637 | case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE0x0042: | |||
2638 | return skinny_handle_extended_data_message(listener, request); | |||
2639 | case DIALED_PHONE_BOOK_MESSAGE0x0048: | |||
2640 | return skinny_handle_dialed_phone_book_message(listener, request); | |||
2641 | case ACCESSORY_STATUS_MESSAGE0x0049: | |||
2642 | return skinny_handle_accessory_status_message(listener, request); | |||
2643 | case XML_ALARM_MESSAGE0x015A: | |||
2644 | return skinny_handle_xml_alarm(listener, request); | |||
2645 | case UPDATE_CAPABILITIES_MESSAGE0x0030: | |||
2646 | return skinny_handle_updatecapabilities(listener, request); | |||
2647 | case SERVER_REQ_MESSAGE0x0012: | |||
2648 | return skinny_handle_server_req_message(listener, request); | |||
2649 | default: | |||
2650 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "skinny_server.c", (const char *)__func__ , 2650, ((void*)0), SWITCH_LOG_WARNING, | |||
2651 | "Unhandled %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); | |||
2652 | return SWITCH_STATUS_SUCCESS; | |||
2653 | } | |||
2654 | } | |||
2655 | ||||
2656 | /* For Emacs: | |||
2657 | * Local Variables: | |||
2658 | * mode:c | |||
2659 | * indent-tabs-mode:t | |||
2660 | * tab-width:4 | |||
2661 | * c-basic-offset:4 | |||
2662 | * End: | |||
2663 | * For VIM: | |||
2664 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: | |||
2665 | */ | |||
2666 |