Bug Summary

File:src/mod/endpoints/mod_skinny/skinny_server.c
Location:line 2508, column 3
Description:Assigned value is garbage or undefined

Annotated Source Code

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
38uint32_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
61uint32_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/*****************************************************************************/
87switch_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;
193error:
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
202done:
203 *session = nsession;
204 listener->profile->ib_calls++;
205 return SWITCH_STATUS_SUCCESS;
206}
207
208skinny_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 }
254found:
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
277switch_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
329switch_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
402struct skinny_session_send_call_info_all_helper {
403 private_t *tech_pvt;
404};
405
406int 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
437switch_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
447struct 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
454int 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
547switch_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
570struct skinny_ring_lines_helper {
571 private_t *tech_pvt;
572 switch_core_session_t *remote_session;
573 uint32_t lines_count;
574};
575
576int 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
662switch_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
688switch_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
710struct skinny_session_answer_helper {
711 private_t *tech_pvt;
712 listener_t *listener;
713 uint32_t line_instance;
714};
715
716int 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
762switch_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
797switch_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
834switch_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
861switch_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
897switch_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
992switch_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
1018struct skinny_hold_active_calls_helper {
1019 listener_t *listener;
1020};
1021
1022int 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
1055switch_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/*****************************************************************************/
1081switch_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
1090switch_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, &params, 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
1301end:
1302 if(params) {
1303 switch_event_destroy(&params);
1304 }
1305
1306 return status;
1307}
1308
1309switch_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
1333switch_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
1396switch_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
1419switch_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
1538switch_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
1578switch_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}
1614switch_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
1633switch_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
1650switch_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
1668int 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
1690switch_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
1723switch_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
1728struct button_template_helper {
1729 skinny_message_t *message;
1730 int count[SKINNY_BUTTON_UNDEFINED+1];
1731 int max_position;
1732};
1733
1734int 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
1756switch_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
1815switch_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
1848switch_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
1920switch_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
1941switch_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 }
2032end:
2033 if(session) {
2034 switch_core_session_rwunlock(session);
2035 }
2036 return status;
2037}
2038
2039switch_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
2068switch_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
2196switch_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
2222switch_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
2253switch_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
2277switch_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
2287switch_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
2299switch_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
2330switch_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
2348switch_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
2366switch_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
2401switch_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
2427switch_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
2472switch_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) {
3
Assuming 'n' is <= 18
4
Taking false branch
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++) {
5
Assuming 'i' is >= 'n'
6
Loop condition is false. Execution continues on line 2504
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++) {
7
Loop condition is true. Entering loop body
2508 char *codec = codec_order[i];
8
Assigned value is garbage or undefined
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
2533switch_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
2545switch_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
2564switch_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) {
1
Control jumps to 'case 48:' at line 2645
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);
2
Calling 'skinny_handle_updatecapabilities'
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