Bug Summary

File:src/switch_core_session.c
Location:line 953, column 3
Description:Potential leak of memory pointed to by 'msg'

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
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 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 * Michael Jerris <mike@jerris.com>
28 * Paul D. Tinsley <pdt at jackhammer.org>
29 * Joseph Sullivan <jossulli@amazon.com>
30 *
31 *
32 * switch_core_session.c -- Main Core Library (session routines)
33 *
34 */
35
36#include "switch.h"
37#include "switch_core.h"
38#include "private/switch_core_pvt.h"
39
40#define DEBUG_THREAD_POOL
41
42struct switch_session_manager session_manager;
43
44SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target)
45{
46 int i = (int) target;
47
48 if (i == 0 || i == 1) {
49 if (dmachine) {
50 switch_ivr_dmachine_set_target(dmachine, target);
51 }
52 session->dmachine[i] = dmachine;
53 }
54}
55
56SWITCH_DECLARE(switch_ivr_dmachine_t *)__attribute__((visibility("default"))) switch_ivr_dmachine_t * switch_core_session_get_dmachine(switch_core_session_t *session, switch_digit_action_target_t target)
57{
58 int i = (int) target;
59
60 if (i == 0 || i == 1) {
61 return session->dmachine[i];
62 }
63
64 return NULL((void*)0);
65}
66
67
68SWITCH_DECLARE(stfu_instance_t *)__attribute__((visibility("default"))) stfu_instance_t * switch_core_session_get_jb(switch_core_session_t *session, switch_media_type_t type)
69{
70 if (session->endpoint_interface->io_routines->get_jb) {
71 return session->endpoint_interface->io_routines->get_jb(session, type);
72 }
73
74 return NULL((void*)0);
75}
76
77SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec)
78{
79 session->soft_lock = sec;
80}
81
82SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_soft_unlock(switch_core_session_t *session)
83{
84 session->soft_lock = 0;
85}
86
87SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_set_codec_slin(switch_core_session_t *session, switch_slin_data_t *data)
88
89{
90 switch_codec_implementation_t read_impl = { 0 };
91 int interval;
92
93 switch_core_session_get_read_impl(session, &read_impl);
94 interval = read_impl.microseconds_per_packet / 1000;
95 data->session = session;
96
97 if (switch_core_codec_init(&data->codec,switch_core_codec_init_with_bitrate(&data->codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, interval, 1
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), ((void*)0))
98 "L16",switch_core_codec_init_with_bitrate(&data->codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, interval, 1
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), ((void*)0))
99 NULL,switch_core_codec_init_with_bitrate(&data->codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, interval, 1
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), ((void*)0))
100 read_impl.actual_samples_per_second,switch_core_codec_init_with_bitrate(&data->codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, interval, 1
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), ((void*)0))
101 interval,switch_core_codec_init_with_bitrate(&data->codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, interval, 1
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), ((void*)0))
102 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL)switch_core_codec_init_with_bitrate(&data->codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, interval, 1
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), ((void*)0))
== SWITCH_STATUS_SUCCESS) {
103 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 103, (const char*)(session)
,
104 SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %dms\n", read_impl.actual_samples_per_second, interval);
105
106 memset(&data->write_frame, 0, sizeof(data->write_frame));
107
108 data->write_frame.codec = &data->codec;
109 data->write_frame.data = data->frame_data;
110 data->write_frame.buflen = sizeof(data->frame_data);
111 data->write_frame.datalen = 0;
112 switch_core_session_set_read_codec(session, &data->codec);
113 return SWITCH_STATUS_SUCCESS;
114 }
115
116 return SWITCH_STATUS_FALSE;
117}
118
119
120SWITCH_DECLARE(switch_core_session_t *)__attribute__((visibility("default"))) switch_core_session_t * switch_core_session_perform_locate(const char *uuid_str, const char *file, const char *func, int line)
121{
122 switch_core_session_t *session = NULL((void*)0);
123
124 if (uuid_str) {
125 switch_mutex_lock(runtime.session_hash_mutex);
126 if ((session = switch_core_hash_find(session_manager.session_table, uuid_str))) {
127 /* Acquire a read lock on the session */
128#ifdef SWITCH_DEBUG_RWLOCKS
129 if (switch_core_session_perform_read_lock(session, file, func, line) != SWITCH_STATUS_SUCCESS) {
130#if EMACS_CC_MODE_IS_BUGGY
131 }
132#endif
133#else
134 if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
135#endif
136 /* not available, forget it */
137 session = NULL((void*)0);
138 }
139 }
140 switch_mutex_unlock(runtime.session_hash_mutex);
141 }
142
143 /* if its not NULL, now it's up to you to rwunlock this */
144 return session;
145}
146
147
148
149
150
151SWITCH_DECLARE(switch_core_session_t *)__attribute__((visibility("default"))) switch_core_session_t * switch_core_session_perform_force_locate(const char *uuid_str, const char *file, const char *func, int line)
152{
153 switch_core_session_t *session = NULL((void*)0);
154 switch_status_t status;
155
156 if (uuid_str) {
157 switch_mutex_lock(runtime.session_hash_mutex);
158 if ((session = switch_core_hash_find(session_manager.session_table, uuid_str))) {
159 /* Acquire a read lock on the session */
160
161 if (switch_test_flag(session, SSF_DESTROYED)((session)->flags & SSF_DESTROYED)) {
162 status = SWITCH_STATUS_FALSE;
163#ifdef SWITCH_DEBUG_RWLOCKS
164 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, uuid_str, SWITCH_LOG_ERROR, "%s %s Read lock FAIL\n",
165 switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
166#endif
167 } else {
168 status = (switch_status_t) switch_thread_rwlock_tryrdlock(session->rwlock);
169#ifdef SWITCH_DEBUG_RWLOCKS
170 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, uuid_str, SWITCH_LOG_ERROR, "%s %s Read lock ACQUIRED\n",
171 switch_core_session_get_uuid(session), switch_channel_get_name(session->channel));
172#endif
173 }
174
175 if (status != SWITCH_STATUS_SUCCESS) {
176 /* not available, forget it */
177 session = NULL((void*)0);
178 }
179 }
180 switch_mutex_unlock(runtime.session_hash_mutex);
181 }
182
183 /* if its not NULL, now it's up to you to rwunlock this */
184 return session;
185}
186
187
188SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_perform_get_partner(switch_core_session_t *session, switch_core_session_t **partner,
189 const char *file, const char *func, int line)
190{
191 const char *uuid;
192
193 if ((uuid = switch_channel_get_partner_uuid(session->channel))) {
194 if ((*partner = switch_core_session_perform_locate(uuid, file, func, line))) {
195 return SWITCH_STATUS_SUCCESS;
196 }
197 }
198
199 *partner = NULL((void*)0);
200 return SWITCH_STATUS_FALSE;
201}
202
203
204struct str_node {
205 char *str;
206 struct str_node *next;
207};
208
209SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_session_hupall_matching_var_ans(const char *var_name, const char *var_val, switch_call_cause_t cause,
210 switch_hup_type_t type)
211{
212 switch_hash_index_t *hi;
213 void *val;
214 switch_core_session_t *session;
215 switch_memory_pool_t *pool;
216 struct str_node *head = NULL((void*)0), *np;
217 uint32_t r = 0;
218
219 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 219)
;
220
221 if (!var_val)
222 return r;
223
224 switch_mutex_lock(runtime.session_hash_mutex);
225 for (hi = switch_core_hash_first(session_manager.session_table)switch_core_hash_first_iter(session_manager.session_table, ((
void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
226 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
227 if (val) {
228 session = (switch_core_session_t *) val;
229 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
230 int ans = switch_channel_test_flag(switch_core_session_get_channel(session), CF_ANSWERED);
231 if ((ans && (type & SHT_ANSWERED)) || (!ans && (type & SHT_UNANSWERED))) {
232 np = switch_core_alloc(pool, sizeof(*np))switch_core_perform_alloc(pool, sizeof(*np), "src/switch_core_session.c"
, (const char *)__func__, 232)
;
233 np->str = switch_core_strdup(pool, session->uuid_str)switch_core_perform_strdup(pool, session->uuid_str, "src/switch_core_session.c"
, (const char *)__func__, 233)
;
234 np->next = head;
235 head = np;
236 }
237 switch_core_session_rwunlock(session);
238 }
239 }
240 }
241 switch_mutex_unlock(runtime.session_hash_mutex);
242
243 for(np = head; np; np = np->next) {
244 if ((session = switch_core_session_locate(np->str)switch_core_session_perform_locate(np->str, "src/switch_core_session.c"
, (const char *)__func__, 244)
)) {
245 const char *this_val;
246 if (switch_channel_up_nosig(session->channel)(switch_channel_get_state(session->channel) < CS_HANGUP
)
&&
247 (this_val = switch_channel_get_variable(session->channel, var_name)switch_channel_get_variable_dup(session->channel, var_name
, SWITCH_TRUE, -1)
) && (!strcmp(this_val, var_val)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(this_val) && __builtin_constant_p (var_val) &&
(__s1_len = __builtin_strlen (this_val), __s2_len = __builtin_strlen
(var_val), (!((size_t)(const void *)((this_val) + 1) - (size_t
)(const void *)(this_val) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((var_val) + 1) - (size_t)(const void
*)(var_val) == 1) || __s2_len >= 4)) ? __builtin_strcmp (
this_val, var_val) : (__builtin_constant_p (this_val) &&
((size_t)(const void *)((this_val) + 1) - (size_t)(const void
*)(this_val) == 1) && (__s1_len = __builtin_strlen (
this_val), __s1_len < 4) ? (__builtin_constant_p (var_val)
&& ((size_t)(const void *)((var_val) + 1) - (size_t)
(const void *)(var_val) == 1) ? __builtin_strcmp (this_val, var_val
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var_val); int __result = (((const unsigned
char *) (const char *) (this_val))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (this_val))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (this_val))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (this_val))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p (var_val) && ((size_t)
(const void *)((var_val) + 1) - (size_t)(const void *)(var_val
) == 1) && (__s2_len = __builtin_strlen (var_val), __s2_len
< 4) ? (__builtin_constant_p (this_val) && ((size_t
)(const void *)((this_val) + 1) - (size_t)(const void *)(this_val
) == 1) ? __builtin_strcmp (this_val, var_val) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (this_val); int __result = (((const unsigned char *)
(const char *) (var_val))[0] - __s2[0]); if (__s2_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (var_val))[1] - __s2[1]); if (__s2_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (var_val))[2] - __s2[2]); if (__s2_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (var_val))[3] - __s2[3]); } } __result; })
))) : __builtin_strcmp (this_val, var_val)))); })
)) {
248 switch_channel_hangup(session->channel, cause)switch_channel_perform_hangup(session->channel, "src/switch_core_session.c"
, (const char *)__func__, 248, cause)
;
249 r++;
250 }
251 switch_core_session_rwunlock(session);
252 }
253 }
254
255 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 255)
;
256
257 return r;
258}
259
260
261SWITCH_DECLARE(switch_console_callback_match_t *)__attribute__((visibility("default"))) switch_console_callback_match_t
*
switch_core_session_findall_matching_var(const char *var_name, const char *var_val)
262{
263 switch_hash_index_t *hi;
264 void *val;
265 switch_core_session_t *session;
266 switch_memory_pool_t *pool;
267 struct str_node *head = NULL((void*)0), *np;
268 switch_console_callback_match_t *my_matches = NULL((void*)0);
269 const char *like = NULL((void*)0);
270
271 if (var_val && *var_val == '~') {
272 like = var_val + 1;
273 }
274
275 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 275)
;
276
277 switch_mutex_lock(runtime.session_hash_mutex);
278 for (hi = switch_core_hash_first(session_manager.session_table)switch_core_hash_first_iter(session_manager.session_table, ((
void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
279 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
280 if (val) {
281 session = (switch_core_session_t *) val;
282 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
283 np = switch_core_alloc(pool, sizeof(*np))switch_core_perform_alloc(pool, sizeof(*np), "src/switch_core_session.c"
, (const char *)__func__, 283)
;
284 np->str = switch_core_strdup(pool, session->uuid_str)switch_core_perform_strdup(pool, session->uuid_str, "src/switch_core_session.c"
, (const char *)__func__, 284)
;
285 np->next = head;
286 head = np;
287 switch_core_session_rwunlock(session);
288 }
289 }
290 }
291 switch_mutex_unlock(runtime.session_hash_mutex);
292
293 for(np = head; np; np = np->next) {
294 if ((session = switch_core_session_locate(np->str)switch_core_session_perform_locate(np->str, "src/switch_core_session.c"
, (const char *)__func__, 294)
)) {
295 const char *this_val;
296 if (switch_channel_up_nosig(session->channel)(switch_channel_get_state(session->channel) < CS_HANGUP
)
&&
297 (this_val = switch_channel_get_variable_dup(session->channel, var_name, SWITCH_FALSE, -1)) &&
298 (!var_val || (like && switch_stristr(like, var_val)) || !strcmp(this_val, var_val)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(this_val) && __builtin_constant_p (var_val) &&
(__s1_len = __builtin_strlen (this_val), __s2_len = __builtin_strlen
(var_val), (!((size_t)(const void *)((this_val) + 1) - (size_t
)(const void *)(this_val) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((var_val) + 1) - (size_t)(const void
*)(var_val) == 1) || __s2_len >= 4)) ? __builtin_strcmp (
this_val, var_val) : (__builtin_constant_p (this_val) &&
((size_t)(const void *)((this_val) + 1) - (size_t)(const void
*)(this_val) == 1) && (__s1_len = __builtin_strlen (
this_val), __s1_len < 4) ? (__builtin_constant_p (var_val)
&& ((size_t)(const void *)((var_val) + 1) - (size_t)
(const void *)(var_val) == 1) ? __builtin_strcmp (this_val, var_val
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var_val); int __result = (((const unsigned
char *) (const char *) (this_val))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (this_val))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (this_val))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (this_val))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p (var_val) && ((size_t)
(const void *)((var_val) + 1) - (size_t)(const void *)(var_val
) == 1) && (__s2_len = __builtin_strlen (var_val), __s2_len
< 4) ? (__builtin_constant_p (this_val) && ((size_t
)(const void *)((this_val) + 1) - (size_t)(const void *)(this_val
) == 1) ? __builtin_strcmp (this_val, var_val) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (this_val); int __result = (((const unsigned char *)
(const char *) (var_val))[0] - __s2[0]); if (__s2_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (var_val))[1] - __s2[1]); if (__s2_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (var_val))[2] - __s2[2]); if (__s2_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (var_val))[3] - __s2[3]); } } __result; })
))) : __builtin_strcmp (this_val, var_val)))); })
)) {
299 switch_console_push_match(&my_matches, (const char *) np->str);
300 }
301 switch_core_session_rwunlock(session);
302 }
303 }
304
305 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 305)
;
306
307
308 return my_matches;
309}
310
311SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_hupall_endpoint(const switch_endpoint_interface_t *endpoint_interface, switch_call_cause_t cause)
312{
313 switch_hash_index_t *hi;
314 void *val;
315 switch_core_session_t *session;
316 switch_memory_pool_t *pool;
317 struct str_node *head = NULL((void*)0), *np;
318
319 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 319)
;
320
321 switch_mutex_lock(runtime.session_hash_mutex);
322 for (hi = switch_core_hash_first(session_manager.session_table)switch_core_hash_first_iter(session_manager.session_table, ((
void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
323 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
324 if (val) {
325 session = (switch_core_session_t *) val;
326 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
327 if (session->endpoint_interface == endpoint_interface) {
328 np = switch_core_alloc(pool, sizeof(*np))switch_core_perform_alloc(pool, sizeof(*np), "src/switch_core_session.c"
, (const char *)__func__, 328)
;
329 np->str = switch_core_strdup(pool, session->uuid_str)switch_core_perform_strdup(pool, session->uuid_str, "src/switch_core_session.c"
, (const char *)__func__, 329)
;
330 np->next = head;
331 head = np;
332 }
333 switch_core_session_rwunlock(session);
334 }
335 }
336 }
337 switch_mutex_unlock(runtime.session_hash_mutex);
338
339 for(np = head; np; np = np->next) {
340 if ((session = switch_core_session_locate(np->str)switch_core_session_perform_locate(np->str, "src/switch_core_session.c"
, (const char *)__func__, 340)
)) {
341 switch_channel_hangup(session->channel, cause)switch_channel_perform_hangup(session->channel, "src/switch_core_session.c"
, (const char *)__func__, 341, cause)
;
342 switch_core_session_rwunlock(session);
343 }
344 }
345
346 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 346)
;
347
348}
349
350SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_hupall(switch_call_cause_t cause)
351{
352 switch_hash_index_t *hi;
353 void *val;
354 switch_core_session_t *session;
355 switch_memory_pool_t *pool;
356 struct str_node *head = NULL((void*)0), *np;
357
358 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 358)
;
359
360
361 switch_mutex_lock(runtime.session_hash_mutex);
362 for (hi = switch_core_hash_first(session_manager.session_table)switch_core_hash_first_iter(session_manager.session_table, ((
void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
363 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
364 if (val) {
365 session = (switch_core_session_t *) val;
366 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
367 np = switch_core_alloc(pool, sizeof(*np))switch_core_perform_alloc(pool, sizeof(*np), "src/switch_core_session.c"
, (const char *)__func__, 367)
;
368 np->str = switch_core_strdup(pool, session->uuid_str)switch_core_perform_strdup(pool, session->uuid_str, "src/switch_core_session.c"
, (const char *)__func__, 368)
;
369 np->next = head;
370 head = np;
371 switch_core_session_rwunlock(session);
372 }
373 }
374 }
375 switch_mutex_unlock(runtime.session_hash_mutex);
376
377 for(np = head; np; np = np->next) {
378 if ((session = switch_core_session_locate(np->str)switch_core_session_perform_locate(np->str, "src/switch_core_session.c"
, (const char *)__func__, 378)
)) {
379 switch_channel_hangup(session->channel, cause)switch_channel_perform_hangup(session->channel, "src/switch_core_session.c"
, (const char *)__func__, 379, cause)
;
380 switch_core_session_rwunlock(session);
381 }
382 }
383
384 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 384)
;
385
386}
387
388
389SWITCH_DECLARE(switch_console_callback_match_t *)__attribute__((visibility("default"))) switch_console_callback_match_t
*
switch_core_session_findall(void)
390{
391 switch_hash_index_t *hi;
392 void *val;
393 switch_core_session_t *session;
394 switch_console_callback_match_t *my_matches = NULL((void*)0);
395
396 switch_mutex_lock(runtime.session_hash_mutex);
397 for (hi = switch_core_hash_first(session_manager.session_table)switch_core_hash_first_iter(session_manager.session_table, ((
void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
398 switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val);
399 if (val) {
400 session = (switch_core_session_t *) val;
401 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
402 switch_console_push_match(&my_matches, session->uuid_str);
403 switch_core_session_rwunlock(session);
404 }
405 }
406 }
407 switch_mutex_unlock(runtime.session_hash_mutex);
408
409 return my_matches;
410}
411
412SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_message_send(const char *uuid_str, switch_core_session_message_t *message)
413{
414 switch_core_session_t *session = NULL((void*)0);
415 switch_status_t status = SWITCH_STATUS_FALSE;
416
417 switch_mutex_lock(runtime.session_hash_mutex);
418 if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
419 /* Acquire a read lock on the session or forget it the channel is dead */
420 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
421 if (switch_channel_up_nosig(session->channel)(switch_channel_get_state(session->channel) < CS_HANGUP
)
) {
422 status = switch_core_session_receive_message(session, message)switch_core_session_perform_receive_message(session, message,
"src/switch_core_session.c", (const char *)__func__, 422)
;
423 }
424 switch_core_session_rwunlock(session);
425 }
426 }
427 switch_mutex_unlock(runtime.session_hash_mutex);
428
429 return status;
430}
431
432SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_event_send(const char *uuid_str, switch_event_t **event)
433{
434 switch_core_session_t *session = NULL((void*)0);
435 switch_status_t status = SWITCH_STATUS_FALSE;
436
437 switch_mutex_lock(runtime.session_hash_mutex);
438 if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
439 /* Acquire a read lock on the session or forget it the channel is dead */
440 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
441 if (switch_channel_up_nosig(session->channel)(switch_channel_get_state(session->channel) < CS_HANGUP
)
) {
442 status = switch_core_session_queue_event(session, event);
443 }
444 switch_core_session_rwunlock(session);
445 }
446 }
447 switch_mutex_unlock(runtime.session_hash_mutex);
448
449 return status;
450}
451
452
453SWITCH_DECLARE(void *)__attribute__((visibility("default"))) void * switch_core_session_get_private_class(switch_core_session_t *session, switch_pvt_class_t index)
454{
455 if ((int)index >= SWITCH_CORE_SESSION_MAX_PRIVATES2) {
456 return NULL((void*)0);
457 }
458
459 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 459, __PRETTY_FUNCTION__))
;
460 return session->private_info[index];
461}
462
463
464SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_set_private_class(switch_core_session_t *session, void *private_info, switch_pvt_class_t index)
465{
466 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 466, __PRETTY_FUNCTION__))
;
467
468 if ((int)index >= SWITCH_CORE_SESSION_MAX_PRIVATES2) {
469 return SWITCH_STATUS_FALSE;
470 }
471
472 session->private_info[index] = private_info;
473 return SWITCH_STATUS_SUCCESS;
474}
475
476SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_session_add_stream(switch_core_session_t *session, void *private_info)
477{
478 session->streams[session->stream_count++] = private_info;
479 return session->stream_count - 1;
480}
481
482SWITCH_DECLARE(void *)__attribute__((visibility("default"))) void * switch_core_session_get_stream(switch_core_session_t *session, int index)
483{
484 return session->streams[index];
485}
486
487
488SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_session_get_stream_count(switch_core_session_t *session)
489{
490 return session->stream_count;
491}
492
493SWITCH_DECLARE(switch_call_cause_t)__attribute__((visibility("default"))) switch_call_cause_t switch_core_session_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
494 const char *endpoint_name,
495 switch_caller_profile_t *caller_profile,
496 switch_core_session_t **new_session,
497 switch_memory_pool_t **pool,
498 switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
499{
500 switch_io_event_hook_outgoing_channel_t *ptr;
501 switch_status_t status = SWITCH_STATUS_FALSE;
502 switch_endpoint_interface_t *endpoint_interface;
503 switch_channel_t *channel = NULL((void*)0);
504 switch_caller_profile_t *outgoing_profile = caller_profile;
505 switch_call_cause_t cause = SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL;
506 const char *forwardvar;
507 int forwardval = 70;
508
509 if ((endpoint_interface = switch_loadable_module_get_endpoint_interface(endpoint_name)) == 0) {
510 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 510, (const char*)(session)
, SWITCH_LOG_ERROR, "Could not locate channel type %s\n", endpoint_name);
511 return SWITCH_CAUSE_CHAN_NOT_IMPLEMENTED;
512 }
513
514 if (!endpoint_interface->io_routines->outgoing_channel) {
515 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 515, (const char*)(session)
, SWITCH_LOG_ERROR, "Could not locate outgoing channel interface for %s\n", endpoint_name);
516 return SWITCH_CAUSE_CHAN_NOT_IMPLEMENTED;
517 }
518
519 if (session) {
520 channel = switch_core_session_get_channel(session);
521
522 switch_assert(channel != NULL)((channel != ((void*)0)) ? (void) (0) : __assert_fail ("channel != ((void*)0)"
, "src/switch_core_session.c", 522, __PRETTY_FUNCTION__))
;
523
524 forwardvar = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE)switch_channel_get_variable_dup(channel, "max_forwards", SWITCH_TRUE
, -1)
;
525 if (!zstr(forwardvar)_zstr(forwardvar)) {
526 forwardval = atoi(forwardvar) - 1;
527 }
528 if (forwardval <= 0) {
529 return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR;
530 }
531
532 if (caller_profile) {
533 const char *eani = NULL((void*)0), *eaniii = NULL((void*)0);
534 const char *ecaller_id_name = NULL((void*)0), *ecaller_id_number = NULL((void*)0);
535
536 if (!(flags & SOF_NO_EFFECTIVE_ANI)) {
537 eani = switch_channel_get_variable(channel, "effective_ani")switch_channel_get_variable_dup(channel, "effective_ani", SWITCH_TRUE
, -1)
;
538 }
539
540 if (!(flags & SOF_NO_EFFECTIVE_ANIII)) {
541 eaniii = switch_channel_get_variable(channel, "effective_aniii")switch_channel_get_variable_dup(channel, "effective_aniii", SWITCH_TRUE
, -1)
;
542 }
543
544 if (!(flags & SOF_NO_EFFECTIVE_CID_NAME)) {
545 ecaller_id_name = switch_channel_get_variable(channel, "effective_caller_id_name")switch_channel_get_variable_dup(channel, "effective_caller_id_name"
, SWITCH_TRUE, -1)
;
546 }
547
548 if (!(flags & SOF_NO_EFFECTIVE_CID_NUM)) {
549 ecaller_id_number = switch_channel_get_variable(channel, "effective_caller_id_number")switch_channel_get_variable_dup(channel, "effective_caller_id_number"
, SWITCH_TRUE, -1)
;
550 }
551
552 if (eani || eaniii || ecaller_id_name || ecaller_id_number) {
553 outgoing_profile = switch_caller_profile_clone(session, caller_profile);
554
555 if (eani) {
556 outgoing_profile->ani = eani;
557 }
558 if (eaniii) {
559 outgoing_profile->aniii = eaniii;
560 }
561 if (ecaller_id_name) {
562 outgoing_profile->caller_id_name = ecaller_id_name;
563 }
564 if (ecaller_id_number) {
565 outgoing_profile->caller_id_number = ecaller_id_number;
566 }
567 }
568 }
569 if (!outgoing_profile) {
570 outgoing_profile = switch_channel_get_caller_profile(channel);
571 }
572 }
573
574 if ((cause =
575 endpoint_interface->io_routines->outgoing_channel(session, var_event, outgoing_profile, new_session, pool, flags,
576 cancel_cause)) != SWITCH_CAUSE_SUCCESS) {
577 UNPROTECT_INTERFACE(endpoint_interface)if (endpoint_interface) {switch_mutex_lock(endpoint_interface
->reflock); switch_thread_rwlock_unlock(endpoint_interface
->rwlock); switch_thread_rwlock_unlock(endpoint_interface->
parent->rwlock); endpoint_interface->refs--; endpoint_interface
->parent->refs--; switch_mutex_unlock(endpoint_interface
->reflock);}
;
578 return cause;
579 }
580
581 if (session) {
582 for (ptr = session->event_hooks.outgoing_channel; ptr; ptr = ptr->next) {
583 if ((status = ptr->outgoing_channel(session, var_event, caller_profile, *new_session, flags)) != SWITCH_STATUS_SUCCESS) {
584 break;
585 }
586 }
587 }
588
589 if (!*new_session) {
590 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 590, (const char*)(session)
, SWITCH_LOG_CRIT,
591 "Outgoing method for endpoint: [%s] returned: [%s] but there is no new session!\n", endpoint_name,
592 switch_channel_cause2str(cause));
593 UNPROTECT_INTERFACE(endpoint_interface)if (endpoint_interface) {switch_mutex_lock(endpoint_interface
->reflock); switch_thread_rwlock_unlock(endpoint_interface
->rwlock); switch_thread_rwlock_unlock(endpoint_interface->
parent->rwlock); endpoint_interface->refs--; endpoint_interface
->parent->refs--; switch_mutex_unlock(endpoint_interface
->reflock);}
;
594 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
595 } else {
596 switch_caller_profile_t *profile = NULL((void*)0), *cloned_profile = NULL((void*)0);
597 switch_event_t *event;
598 switch_channel_t *peer_channel = switch_core_session_get_channel(*new_session);
599 const char *use_uuid;
600
601 switch_assert(peer_channel)((peer_channel) ? (void) (0) : __assert_fail ("peer_channel",
"src/switch_core_session.c", 601, __PRETTY_FUNCTION__))
;
602
603 if (channel && switch_true(switch_channel_get_variable(channel, "session_copy_loglevel")switch_channel_get_variable_dup(channel, "session_copy_loglevel"
, SWITCH_TRUE, -1)
)) {
604 (*new_session)->loglevel = session->loglevel;
605 }
606
607
608 if ((use_uuid = switch_event_get_header(var_event, "origination_uuid")switch_event_get_header_idx(var_event, "origination_uuid", -1
)
)) {
609 use_uuid = switch_core_session_strdup(*new_session, use_uuid)switch_core_perform_session_strdup(*new_session, use_uuid, "src/switch_core_session.c"
, (const char *)__func__, 609)
;
610 if (switch_core_session_set_uuid(*new_session, use_uuid) == SWITCH_STATUS_SUCCESS) {
611 switch_event_del_header(var_event, "origination_uuid")switch_event_del_header_val(var_event, "origination_uuid", ((
void*)0))
;
612 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 612, (const char*)(*new_session)
, SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(peer_channel),
613 use_uuid);
614 } else {
615 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 615, (const char*)(*new_session)
, SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
616 switch_channel_get_name(peer_channel), use_uuid);
617 }
618 }
619
620 if (channel) {
621 const char *val;
622 switch_codec_t *vid_read_codec = NULL((void*)0), *read_codec = switch_core_session_get_read_codec(session);
623 const char *ep, *max_forwards = switch_core_session_sprintf(session, "%d", forwardval);
624
625 switch_channel_set_variable(peer_channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards)switch_channel_set_variable_var_check(peer_channel, "max_forwards"
, max_forwards, SWITCH_TRUE)
;
626
627 profile = switch_channel_get_caller_profile(channel);
628
629 vid_read_codec = switch_core_session_get_video_read_codec(session);
630
631 if (read_codec && read_codec->implementation && switch_core_codec_ready(read_codec)) {
632 char rc[80] = "", vrc[80] = "", tmp[160] = "";
633
634 switch_codec2str(read_codec, rc, sizeof(rc))snprintf(rc, sizeof(rc), "%s@%uh@%ui", read_codec->implementation
->iananame, read_codec->implementation->samples_per_second
, read_codec->implementation->microseconds_per_packet /
1000)
;
635 if (vid_read_codec && vid_read_codec->implementation && switch_core_codec_ready(vid_read_codec)) {
636 vrc[0] = ',';
637 switch_codec2str(vid_read_codec, vrc + 1, sizeof(vrc) - 1)snprintf(vrc + 1, sizeof(vrc) - 1, "%s@%uh@%ui", vid_read_codec
->implementation->iananame, vid_read_codec->implementation
->samples_per_second, vid_read_codec->implementation->
microseconds_per_packet / 1000)
;
638 switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE, vrc + 1)switch_channel_set_variable_var_check(peer_channel, "originator_video_codec"
, vrc + 1, SWITCH_TRUE)
;
639 }
640
641 switch_snprintf(tmp, sizeof(tmp), "%s%s", rc, vrc);
642 switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_CODEC_VARIABLE, tmp)switch_channel_set_variable_var_check(peer_channel, "originator_codec"
, tmp, SWITCH_TRUE)
;
643 } else if ((ep = switch_channel_get_variable(channel, "ep_codec_string")switch_channel_get_variable_dup(channel, "ep_codec_string", SWITCH_TRUE
, -1)
)) {
644 switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_CODEC_VARIABLE, ep)switch_channel_set_variable_var_check(peer_channel, "originator_codec"
, ep, SWITCH_TRUE)
;
645 }
646
647 switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_VARIABLE, switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(peer_channel, "originator"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
648 switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(peer_channel, "signal_bond"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
649 // Needed by 3PCC proxy so that aleg can find bleg to pass SDP to, when final ACK arrives.
650 switch_channel_set_variable(channel, SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(*new_session))switch_channel_set_variable_var_check(channel, "originate_signal_bond"
, switch_core_session_get_uuid(*new_session), SWITCH_TRUE)
;
651
652 if ((val = switch_channel_get_variable(channel, SWITCH_PROCESS_CDR_VARIABLE)switch_channel_get_variable_dup(channel, "process_cdr", SWITCH_TRUE
, -1)
)) {
653 switch_channel_set_variable(peer_channel, SWITCH_PROCESS_CDR_VARIABLE, val)switch_channel_set_variable_var_check(peer_channel, "process_cdr"
, val, SWITCH_TRUE)
;
654 }
655
656 if ((val = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE)switch_channel_get_variable_dup(channel, "switch_r_sdp", SWITCH_TRUE
, -1)
)) {
657 switch_channel_pass_sdp(channel, peer_channel, val);
658 }
659
660 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
661 if (switch_channel_test_cap(peer_channel, CC_BYPASS_MEDIA)) {
662 switch_channel_set_flag(peer_channel, CF_PROXY_MODE)switch_channel_set_flag_value(peer_channel, CF_PROXY_MODE, 1);
663 } else {
664 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 664, (const char*)(session)
, SWITCH_LOG_WARNING,
665 "%s does not support the proxy feature, disabling.\n", switch_channel_get_name(peer_channel));
666 switch_channel_clear_flag(channel, CF_PROXY_MODE);
667 }
668 }
669
670 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
671 if (switch_channel_test_cap(peer_channel, CC_PROXY_MEDIA)) {
672 switch_channel_set_flag(peer_channel, CF_PROXY_MEDIA)switch_channel_set_flag_value(peer_channel, CF_PROXY_MEDIA, 1
)
;
673 if (switch_channel_test_flag(channel, CF_VIDEO)) {
674 switch_channel_set_flag(peer_channel, CF_VIDEO)switch_channel_set_flag_value(peer_channel, CF_VIDEO, 1);
675 }
676 } else {
677 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 677, (const char*)(session)
, SWITCH_LOG_WARNING,
678 "%s does not support the proxy feature, disabling.\n", switch_channel_get_name(peer_channel));
679 switch_channel_clear_flag(channel, CF_PROXY_MEDIA);
680 }
681 }
682
683 if (switch_channel_test_flag(channel, CF_ZRTP_PASSTHRU_REQ)) {
684 switch_channel_set_flag(peer_channel, CF_ZRTP_PASSTHRU_REQ)switch_channel_set_flag_value(peer_channel, CF_ZRTP_PASSTHRU_REQ
, 1)
;
685 }
686
687 if (profile) {
688 if ((cloned_profile = switch_caller_profile_clone(*new_session, profile)) != 0) {
689 switch_channel_set_originator_caller_profile(peer_channel, cloned_profile);
690 }
691 }
692
693
694 if ((profile = switch_channel_get_caller_profile(peer_channel))) {
695 if ((cloned_profile = switch_caller_profile_clone(session, profile)) != 0) {
696 switch_channel_set_origination_caller_profile(channel, cloned_profile);
697 }
698 }
699
700 }
701
702 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_OUTGOING)switch_event_create_subclass_detailed("src/switch_core_session.c"
, (const char * )(const char *)__func__, 702, &event, SWITCH_EVENT_CHANNEL_OUTGOING
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
703 switch_channel_event_set_data(peer_channel, event);
704 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_session.c", (const
char * )(const char *)__func__, 704, &event, ((void*)0))
;
705 }
706 }
707
708 UNPROTECT_INTERFACE(endpoint_interface)if (endpoint_interface) {switch_mutex_lock(endpoint_interface
->reflock); switch_thread_rwlock_unlock(endpoint_interface
->rwlock); switch_thread_rwlock_unlock(endpoint_interface->
parent->rwlock); endpoint_interface->refs--; endpoint_interface
->parent->refs--; switch_mutex_unlock(endpoint_interface
->reflock);}
;
709 return cause;
710}
711
712static const char *message_names[] = {
713 "REDIRECT_AUDIO",
714 "TRANSMIT_TEXT",
715 "ANSWER",
716 "PROGRESS",
717 "BRIDGE",
718 "UNBRIDGE",
719 "TRANSFER",
720 "RINGING",
721 "MEDIA",
722 "NOMEDIA",
723 "HOLD",
724 "UNHOLD",
725 "REDIRECT",
726 "RESPOND",
727 "BROADCAST",
728 "MEDIA_REDIRECT",
729 "DEFLECT",
730 "VIDEO_REFRESH_REQ",
731 "DISPLAY",
732 "TRANSCODING_NECESSARY",
733 "AUDIO_SYNC",
734 "REQUEST_IMAGE_MEDIA",
735 "UUID_CHANGE",
736 "SIMPLIFY",
737 "DEBUG_MEDIA",
738 "PROXY_MEDIA",
739 "APPLICATION_EXEC",
740 "APPLICATION_EXEC_COMPLETE",
741 "PHONE_EVENT",
742 "T38_DESCRIPTION",
743 "UDPTL_MODE",
744 "CLEAR_PROGRESS",
745 "JITTER_BUFFER",
746 "RECOVERY_REFRESH",
747 "SIGNAL_DATA",
748 "MESSAGE",
749 "INFO",
750 "AUDIO_DATA",
751 "BLIND_TRANSFER_RESPONSE",
752 "STUN_ERROR",
753 "MEDIA_RENEG",
754 "KEEPALIVE",
755 "REFER_EVENT",
756 "ANSWER_EVENT",
757 "PROGRESS_EVENT",
758 "RING_EVENT",
759 "RESAMPLE_EVENT",
760 "HEARTBEAT_EVENT",
761 "INVALID"
762};
763
764SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_perform_receive_message(switch_core_session_t *session,
765 switch_core_session_message_t *message,
766 const char *file, const char *func, int line)
767{
768 switch_io_event_hook_receive_message_t *ptr;
769 switch_status_t status = SWITCH_STATUS_SUCCESS;
770
771 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 771, __PRETTY_FUNCTION__))
;
772
773 if (message->message_id == SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) {
774 if (session->endpoint_interface->io_routines->receive_message) {
775 status = session->endpoint_interface->io_routines->receive_message(session, message);
776 }
777
778 switch_core_session_free_message(&message);
779 return status;
780 }
781
782 if ((status = switch_core_session_read_lock_hangup(session)) != SWITCH_STATUS_SUCCESS) {
783 return status;
784 }
785
786 if (!message->_file) {
787 message->_file = file;
788 }
789
790 if (!message->_func) {
791 message->_func = func;
792 }
793
794 if (!message->_line) {
795 message->_line = line;
796 }
797
798 if (message->message_id > SWITCH_MESSAGE_INVALID-1) {
799 message->message_id = SWITCH_MESSAGE_INVALID-1;
800 }
801
802 switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
803 switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG1, "%s receive message [%s]\n",
804 switch_channel_get_name(session->channel), message_names[message->message_id]);
805
806
807 if (message->message_id == SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS) {
808 switch_channel_clear_flag(session->channel, CF_EARLY_MEDIA);
809 }
810
811 if (message->message_id == SWITCH_MESSAGE_INDICATE_DISPLAY) {
812 char *arg = NULL((void*)0);
813
814 if (zstr(message->string_array_arg[0])_zstr(message->string_array_arg[0]) && !zstr(message->string_arg)_zstr(message->string_arg)) {
815 arg = switch_core_session_strdup(session, message->string_arg)switch_core_perform_session_strdup(session, message->string_arg
, "src/switch_core_session.c", (const char *)__func__, 815)
;
816 switch_separate_string(arg, '|', (char **)message->string_array_arg, 2);
817 }
818
819 if (!zstr(message->string_array_arg[0])_zstr(message->string_array_arg[0])) {
820 switch_channel_set_variable(session->channel, "last_sent_callee_id_name", message->string_array_arg[0])switch_channel_set_variable_var_check(session->channel, "last_sent_callee_id_name"
, message->string_array_arg[0], SWITCH_TRUE)
;
821 }
822
823 if (!zstr(message->string_array_arg[1])_zstr(message->string_array_arg[1])) {
824 switch_channel_set_variable(session->channel, "last_sent_callee_id_number", message->string_array_arg[1])switch_channel_set_variable_var_check(session->channel, "last_sent_callee_id_number"
, message->string_array_arg[1], SWITCH_TRUE)
;
825 }
826
827
828 if (switch_true(switch_channel_get_variable(session->channel, SWITCH_IGNORE_DISPLAY_UPDATES_VARIABLE)switch_channel_get_variable_dup(session->channel, "ignore_display_updates"
, SWITCH_TRUE, -1)
)) {
829 switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
830 switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG1, "Ignoring display update.\n");
831 status = SWITCH_STATUS_SUCCESS;
832 goto end;
833 }
834
835 }
836
837 if (switch_channel_down_nosig(session->channel)(switch_channel_get_state(session->channel) >= CS_HANGUP
)
) {
838 switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
839 switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "%s skip receive message [%s] (channel is hungup already)\n",
840 switch_channel_get_name(session->channel), message_names[message->message_id]);
841
842 } else {
843 if (session->media_handle) {
844 status = switch_core_media_receive_message(session, message);
845 }
846 if (status == SWITCH_STATUS_SUCCESS) {
847 if (session->endpoint_interface->io_routines->receive_message) {
848 status = session->endpoint_interface->io_routines->receive_message(session, message);
849 }
850 }
851 }
852
853 if (status == SWITCH_STATUS_SUCCESS) {
854 for (ptr = session->event_hooks.receive_message; ptr; ptr = ptr->next) {
855 if ((status = ptr->receive_message(session, message)) != SWITCH_STATUS_SUCCESS) {
856 break;
857 }
858 }
859
860
861 if (message->message_id == SWITCH_MESSAGE_INDICATE_BRIDGE &&
862 switch_channel_test_flag(session->channel, CF_CONFIRM_BLIND_TRANSFER)) {
863 switch_core_session_t *other_session;
864 const char *uuid = switch_channel_get_variable(session->channel, "blind_transfer_uuid")switch_channel_get_variable_dup(session->channel, "blind_transfer_uuid"
, SWITCH_TRUE, -1)
;
865
866 switch_channel_clear_flag(session->channel, CF_CONFIRM_BLIND_TRANSFER);
867
868 if (!zstr(uuid)_zstr(uuid) && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_core_session.c"
, (const char *)__func__, 868)
)) {
869 switch_core_session_message_t msg = { 0 };
870 msg.message_id = SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE;
871 msg.from = __FILE__"src/switch_core_session.c";
872 msg.numeric_arg = 1;
873 switch_core_session_receive_message(other_session, &msg)switch_core_session_perform_receive_message(other_session, &
msg, "src/switch_core_session.c", (const char *)__func__, 873
)
;
874 switch_core_session_rwunlock(other_session);
875 }
876 }
877 }
878
879
880 message->_file = NULL((void*)0);
881 message->_func = NULL((void*)0);
882 message->_line = 0;
883
884 if (switch_channel_up_nosig(session->channel)(switch_channel_get_state(session->channel) < CS_HANGUP
)
) {
885 if (message->message_id == SWITCH_MESSAGE_INDICATE_BRIDGE || message->message_id == SWITCH_MESSAGE_INDICATE_UNBRIDGE) {
886 switch_core_media_bug_flush_all(session);
887 switch_core_recovery_track(session);
888 }
889
890 switch (message->message_id) {
891 case SWITCH_MESSAGE_REDIRECT_AUDIO:
892 case SWITCH_MESSAGE_INDICATE_ANSWER:
893 case SWITCH_MESSAGE_INDICATE_PROGRESS:
894 case SWITCH_MESSAGE_INDICATE_BRIDGE:
895 case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
896 case SWITCH_MESSAGE_INDICATE_TRANSFER:
897 case SWITCH_MESSAGE_INDICATE_RINGING:
898 case SWITCH_MESSAGE_INDICATE_MEDIA:
899 case SWITCH_MESSAGE_INDICATE_NOMEDIA:
900 case SWITCH_MESSAGE_INDICATE_HOLD:
901 case SWITCH_MESSAGE_INDICATE_UNHOLD:
902 case SWITCH_MESSAGE_INDICATE_REDIRECT:
903 case SWITCH_MESSAGE_INDICATE_RESPOND:
904 case SWITCH_MESSAGE_INDICATE_BROADCAST:
905 case SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT:
906 case SWITCH_MESSAGE_INDICATE_DEFLECT:
907 switch_channel_set_flag(session->channel, CF_VIDEO_BREAK)switch_channel_set_flag_value(session->channel, CF_VIDEO_BREAK
, 1)
;
908 switch_core_session_kill_channel(session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session, "src/switch_core_session.c"
, (const char *)__func__, 908, SWITCH_SIG_BREAK)
;
909 break;
910 default:
911 break;
912 }
913 }
914
915 end:
916
917 switch_core_session_free_message(&message);
918 switch_core_session_rwunlock(session);
919
920 return status;
921}
922
923SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_pass_indication(switch_core_session_t *session, switch_core_session_message_types_t indication)
924{
925 switch_core_session_message_t msg = { 0 };
926 switch_core_session_t *other_session;
927 const char *uuid;
928 switch_channel_t *channel = switch_core_session_get_channel(session);
929 switch_status_t status = SWITCH_STATUS_SUCCESS;
930
931 if (((uuid = switch_channel_get_partner_uuid(channel))) && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_core_session.c"
, (const char *)__func__, 931)
)) {
932 msg.message_id = indication;
933 msg.from = __FILE__"src/switch_core_session.c";
934 status = switch_core_session_receive_message(other_session, &msg)switch_core_session_perform_receive_message(other_session, &
msg, "src/switch_core_session.c", (const char *)__func__, 934
)
;
935 switch_core_session_rwunlock(other_session);
936 } else {
937 status = SWITCH_STATUS_FALSE;
938 }
939
940 return status;
941}
942
943SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_queue_indication(switch_core_session_t *session, switch_core_session_message_types_t indication)
944{
945 switch_core_session_message_t *msg;
946
947 if ((msg = malloc(sizeof(*msg)))) {
1
Memory is allocated
2
Assuming 'msg' is not null
3
Taking true branch
948 memset(msg, 0, sizeof(*msg));
949 msg->message_id = indication;
950 msg->from = __FILE__"src/switch_core_session.c";
951 switch_set_flag(msg, SCSMF_DYNAMIC)(msg)->flags |= (SCSMF_DYNAMIC);
952 switch_core_session_queue_message(session, msg);
953 return SWITCH_STATUS_SUCCESS;
4
Potential leak of memory pointed to by 'msg'
954 }
955
956 return SWITCH_STATUS_FALSE;
957}
958
959SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_queue_message(switch_core_session_t *session, switch_core_session_message_t *message)
960{
961 switch_status_t status = SWITCH_STATUS_FALSE;
962
963 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 963, __PRETTY_FUNCTION__))
;
964
965 if (session->message_queue) {
966 if (switch_queue_trypush(session->message_queue, message) == SWITCH_STATUS_SUCCESS) {
967 status = SWITCH_STATUS_SUCCESS;
968 }
969
970 switch_core_session_kill_channel(session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session, "src/switch_core_session.c"
, (const char *)__func__, 970, SWITCH_SIG_BREAK)
;
971
972 switch_core_session_wake_session_thread(session);
973
974 }
975
976 return status;
977}
978
979SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_free_message(switch_core_session_message_t **message)
980{
981 switch_core_session_message_t *to_free = *message;
982 int i;
983 char *s;
984
985 *message = NULL((void*)0);
986
987 if (switch_test_flag(to_free, SCSMF_DYNAMIC)((to_free)->flags & SCSMF_DYNAMIC)) {
988 s = (char *) to_free->string_arg;
989 switch_safe_free(s)if (s) {free(s);s=((void*)0);};
990 switch_safe_free(to_free->pointer_arg)if (to_free->pointer_arg) {free(to_free->pointer_arg);to_free
->pointer_arg=((void*)0);}
;
991
992 for (i = 0; i < MESSAGE_STRING_ARG_MAX10; i++) {
993 s = (char *) to_free->string_array_arg[i];
994 switch_safe_free(s)if (s) {free(s);s=((void*)0);};
995 }
996
997 switch_safe_free(to_free)if (to_free) {free(to_free);to_free=((void*)0);};
998 }
999}
1000
1001SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_dequeue_message(switch_core_session_t *session, switch_core_session_message_t **message)
1002{
1003 switch_status_t status = SWITCH_STATUS_FALSE;
1004 void *pop;
1005
1006 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1006, __PRETTY_FUNCTION__))
;
1007
1008 if (session->message_queue) {
1009 if ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1010 *message = (switch_core_session_message_t *) pop;
1011 if ((*message)->delivery_time && (*message)->delivery_time > switch_epoch_time_now(NULL((void*)0))) {
1012 switch_core_session_queue_message(session, *message);
1013 *message = NULL((void*)0);
1014 status = SWITCH_STATUS_FALSE;
1015 }
1016 }
1017 }
1018
1019 return status;
1020}
1021
1022SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_flush_message(switch_core_session_t *session)
1023{
1024 switch_status_t status = SWITCH_STATUS_FALSE;
1025 void *pop;
1026 switch_core_session_message_t *message;
1027
1028 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1028, __PRETTY_FUNCTION__))
;
1029
1030
1031 if (session->message_queue) {
1032 while ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1033 message = (switch_core_session_message_t *) pop;
1034 switch_ivr_process_indications(session, message);
1035 switch_core_session_free_message(&message);
1036 }
1037 }
1038
1039 return SWITCH_STATUS_SUCCESS;
1040}
1041
1042SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_queue_signal_data(switch_core_session_t *session, void *signal_data)
1043{
1044 switch_status_t status = SWITCH_STATUS_FALSE;
1045
1046 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1046, __PRETTY_FUNCTION__))
;
1047
1048 if (session->signal_data_queue) {
1049 if (switch_queue_push(session->signal_data_queue, signal_data) == SWITCH_STATUS_SUCCESS) {
1050 status = SWITCH_STATUS_SUCCESS;
1051 }
1052
1053 switch_core_session_kill_channel(session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session, "src/switch_core_session.c"
, (const char *)__func__, 1053, SWITCH_SIG_BREAK)
;
1054
1055 switch_core_session_wake_session_thread(session);
1056
1057 }
1058
1059 return status;
1060}
1061
1062SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_dequeue_signal_data(switch_core_session_t *session, void **signal_data)
1063{
1064 switch_status_t status = SWITCH_STATUS_FALSE;
1065 void *pop;
1066
1067 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1067, __PRETTY_FUNCTION__))
;
1068
1069 if (session->signal_data_queue) {
1070 if ((status = (switch_status_t) switch_queue_trypop(session->signal_data_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1071 *signal_data = pop;
1072 }
1073 }
1074
1075 return status;
1076}
1077
1078SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_receive_event(switch_core_session_t *session, switch_event_t **event)
1079{
1080 switch_io_event_hook_receive_event_t *ptr;
1081 switch_status_t status = SWITCH_STATUS_FALSE;
1082
1083 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1083, __PRETTY_FUNCTION__))
;
1084
1085 /* Acquire a read lock on the session or forget it the channel is dead */
1086 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
1087 if (switch_channel_up_nosig(session->channel)(switch_channel_get_state(session->channel) < CS_HANGUP
)
) {
1088 if (session->endpoint_interface->io_routines->receive_event) {
1089 status = session->endpoint_interface->io_routines->receive_event(session, *event);
1090 }
1091
1092 if (status == SWITCH_STATUS_SUCCESS) {
1093 for (ptr = session->event_hooks.receive_event; ptr; ptr = ptr->next) {
1094 if ((status = ptr->receive_event(session, *event)) != SWITCH_STATUS_SUCCESS) {
1095 break;
1096 }
1097 }
1098 }
1099
1100 if (status == SWITCH_STATUS_BREAK) {
1101 status = SWITCH_STATUS_SUCCESS;
1102 }
1103
1104 if (status == SWITCH_STATUS_SUCCESS) {
1105 switch_event_destroy(event);
1106 }
1107 }
1108 switch_core_session_rwunlock(session);
1109 }
1110
1111 switch_core_session_kill_channel(session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session, "src/switch_core_session.c"
, (const char *)__func__, 1111, SWITCH_SIG_BREAK)
;
1112
1113 return status;
1114}
1115
1116SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_queue_event(switch_core_session_t *session, switch_event_t **event)
1117{
1118 switch_status_t status = SWITCH_STATUS_FALSE;
1119
1120 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1120, __PRETTY_FUNCTION__))
;
1121
1122 if (session->event_queue) {
1123 if (switch_queue_trypush(session->event_queue, *event) == SWITCH_STATUS_SUCCESS) {
1124 *event = NULL((void*)0);
1125 status = SWITCH_STATUS_SUCCESS;
1126
1127 switch_core_session_wake_session_thread(session);
1128 }
1129 }
1130
1131 return status;
1132}
1133
1134SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_session_messages_waiting(switch_core_session_t *session)
1135{
1136 int x = 0;
1137
1138 if (session->private_event_queue) {
1139 x += switch_queue_size(session->private_event_queue);
1140 }
1141
1142 if (session->message_queue) {
1143 x += switch_queue_size(session->message_queue);
1144 }
1145
1146 return x;
1147}
1148
1149SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_session_event_count(switch_core_session_t *session)
1150{
1151 if (session->event_queue) {
1152 return switch_queue_size(session->event_queue);
1153 }
1154
1155 return 0;
1156}
1157
1158SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_dequeue_event(switch_core_session_t *session, switch_event_t **event, switch_bool_t force)
1159{
1160 switch_status_t status = SWITCH_STATUS_FALSE;
1161 void *pop;
1162
1163 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1163, __PRETTY_FUNCTION__))
;
1164
1165 if (session->event_queue && (force || !switch_channel_test_flag(session->channel, CF_DIVERT_EVENTS))) {
1166 if ((status = (switch_status_t) switch_queue_trypop(session->event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1167 *event = (switch_event_t *) pop;
1168 }
1169 }
1170
1171 return status;
1172}
1173
1174SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_queue_private_event(switch_core_session_t *session, switch_event_t **event, switch_bool_t priority)
1175{
1176 switch_status_t status = SWITCH_STATUS_FALSE;
1177 switch_queue_t *queue;
1178
1179 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1179, __PRETTY_FUNCTION__))
;
1180 switch_assert(event != NULL)((event != ((void*)0)) ? (void) (0) : __assert_fail ("event != ((void*)0)"
, "src/switch_core_session.c", 1180, __PRETTY_FUNCTION__))
;
1181
1182 if (session->private_event_queue) {
1183 queue = priority ? session->private_event_queue_pri : session->private_event_queue;
1184
1185 (*event)->event_id = SWITCH_EVENT_PRIVATE_COMMAND;
1186 if (switch_queue_trypush(queue, *event) == SWITCH_STATUS_SUCCESS) {
1187 *event = NULL((void*)0);
1188 switch_core_session_kill_channel(session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session, "src/switch_core_session.c"
, (const char *)__func__, 1188, SWITCH_SIG_BREAK)
;
1189 status = SWITCH_STATUS_SUCCESS;
1190 }
1191 }
1192
1193 return status;
1194}
1195
1196#define check_media(session){ if (switch_channel_test_flag(session->channel, CF_BROADCAST_DROP_MEDIA
)) { switch_channel_clear_flag(session->channel, CF_BROADCAST_DROP_MEDIA
); switch_ivr_nomedia(session->uuid_str, SMF_REBRIDGE); } }
\
1197 { \
1198 if (switch_channel_test_flag(session->channel, CF_BROADCAST_DROP_MEDIA)) { \
1199 switch_channel_clear_flag(session->channel, CF_BROADCAST_DROP_MEDIA); \
1200 switch_ivr_nomedia(session->uuid_str, SMF_REBRIDGE); \
1201 } \
1202 } \
1203
1204SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_session_private_event_count(switch_core_session_t *session)
1205{
1206 switch_channel_t *channel = switch_core_session_get_channel(session);
1207 uint32_t count = 0;
1208
1209 if (session->private_event_queue) {
1210
1211 if (!switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
1212 count = switch_queue_size(session->private_event_queue);
1213 }
1214
1215 if (!switch_channel_test_flag(channel, CF_EVENT_LOCK_PRI)) {
1216 count += switch_queue_size(session->private_event_queue_pri);
1217 }
1218
1219 if (count == 0) {
1220 check_media(session){ if (switch_channel_test_flag(session->channel, CF_BROADCAST_DROP_MEDIA
)) { switch_channel_clear_flag(session->channel, CF_BROADCAST_DROP_MEDIA
); switch_ivr_nomedia(session->uuid_str, SMF_REBRIDGE); } }
;
1221 }
1222 }
1223
1224 return count;
1225}
1226
1227SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_dequeue_private_event(switch_core_session_t *session, switch_event_t **event)
1228{
1229 switch_status_t status = SWITCH_STATUS_FALSE;
1230 void *pop;
1231 switch_channel_t *channel = switch_core_session_get_channel(session);
1232 switch_queue_t *queue;
1233
1234 if (session->private_event_queue) {
1235 if (switch_queue_size(session->private_event_queue_pri)) {
1236 queue = session->private_event_queue_pri;
1237
1238 if (switch_channel_test_flag(channel, CF_EVENT_LOCK_PRI)) {
1239 return SWITCH_STATUS_FALSE;
1240 }
1241 } else {
1242 queue = session->private_event_queue;
1243
1244 if (switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
1245 return SWITCH_STATUS_FALSE;
1246 }
1247 }
1248
1249 if ((status = (switch_status_t) switch_queue_trypop(queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1250 *event = (switch_event_t *) pop;
1251 } else {
1252 check_media(session){ if (switch_channel_test_flag(session->channel, CF_BROADCAST_DROP_MEDIA
)) { switch_channel_clear_flag(session->channel, CF_BROADCAST_DROP_MEDIA
); switch_ivr_nomedia(session->uuid_str, SMF_REBRIDGE); } }
;
1253 }
1254 }
1255
1256 return status;
1257}
1258
1259SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_session_flush_private_events(switch_core_session_t *session)
1260{
1261 switch_status_t status = SWITCH_STATUS_FALSE;
1262 int x = 0;
1263 void *pop;
1264
1265 if (session->private_event_queue) {
1266 while ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue_pri, &pop)) == SWITCH_STATUS_SUCCESS) {
1267 if (pop) {
1268 switch_event_t *event = (switch_event_t *) pop;
1269 switch_event_destroy(&event);
1270 }
1271 x++;
1272 }
1273 while ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1274 if (pop) {
1275 switch_event_t *event = (switch_event_t *) pop;
1276 switch_event_destroy(&event);
1277 }
1278 x++;
1279 }
1280 check_media(session){ if (switch_channel_test_flag(session->channel, CF_BROADCAST_DROP_MEDIA
)) { switch_channel_clear_flag(session->channel, CF_BROADCAST_DROP_MEDIA
); switch_ivr_nomedia(session->uuid_str, SMF_REBRIDGE); } }
;
1281 }
1282
1283 return x;
1284}
1285
1286SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_reset(switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
1287{
1288 switch_channel_t *channel = switch_core_session_get_channel(session);
1289 switch_size_t has;
1290
1291 if (reset_read_codec) {
1292 switch_core_session_set_read_codec(session, NULL((void*)0));
1293 }
1294
1295 /* clear resamplers */
1296 switch_mutex_lock(session->resample_mutex);
1297 switch_resample_destroy(&session->read_resampler);
1298 switch_resample_destroy(&session->write_resampler);
1299 switch_mutex_unlock(session->resample_mutex);
1300 /* clear indications */
1301 switch_core_session_flush_message(session);
1302
1303 /* wipe these, they will be recreated if need be */
1304 switch_mutex_lock(session->codec_write_mutex);
1305 switch_buffer_destroy(&session->raw_write_buffer);
1306 switch_mutex_unlock(session->codec_write_mutex);
1307
1308 switch_mutex_lock(session->codec_read_mutex);
1309 switch_buffer_destroy(&session->raw_read_buffer);
1310 switch_mutex_unlock(session->codec_read_mutex);
1311
1312 if (flush_dtmf) {
1313 while ((has = switch_channel_has_dtmf(channel))) {
1314 switch_channel_flush_dtmf(channel);
1315 }
1316 }
1317
1318 switch_clear_flag(session, SSF_WARN_TRANSCODE)(session)->flags &= ~(SSF_WARN_TRANSCODE);
1319 switch_ivr_deactivate_unicast(session);
1320 switch_channel_clear_flag(channel, CF_BREAK);
1321}
1322
1323
1324SWITCH_DECLARE(switch_channel_t *)__attribute__((visibility("default"))) switch_channel_t * switch_core_session_get_channel(switch_core_session_t *session)
1325{
1326 switch_assert(session->channel)((session->channel) ? (void) (0) : __assert_fail ("session->channel"
, "src/switch_core_session.c", 1326, __PRETTY_FUNCTION__))
;
1327 return session->channel;
1328}
1329
1330SWITCH_DECLARE(switch_mutex_t *)__attribute__((visibility("default"))) switch_mutex_t * switch_core_session_get_mutex(switch_core_session_t *session)
1331{
1332 return session->mutex;
1333}
1334
1335SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_wake_session_thread(switch_core_session_t *session)
1336{
1337 switch_status_t status;
1338 int tries = 0;
1339
1340 /* If trylock fails the signal is already awake so we needn't bother ..... or do we????*/
1341
1342 top:
1343
1344 status = switch_mutex_trylock(session->mutex);
1345
1346 if (status == SWITCH_STATUS_SUCCESS) {
1347 switch_thread_cond_signal(session->cond);
1348 switch_mutex_unlock(session->mutex);
1349 } else {
1350 if (switch_channel_state_thread_trylock(session->channel) == SWITCH_STATUS_SUCCESS) {
1351 /* We've beat them for sure, as soon as we release this lock, they will be checking their queue on the next line. */
1352 switch_channel_state_thread_unlock(session->channel);
1353 } else {
1354 /* What luck! The channel has already started going to sleep *after* we checked if we need to wake it up.
1355 It will miss any messages in its queue because they were inserted after *it* checked its queue. (catch-22)
1356 So, it's not asleep yet, but it's too late for us to be sure they know we want them to stay awake and check its queue again.
1357 Now *we* need to sleep instead but just for 1ms so we can circle back and try again.
1358 This is so rare (yet possible) to happen that we can be fairly certian it will not happen 2x in a row but we'll try 10x just in case.
1359 */
1360 if (++tries < 10) {
1361 switch_cond_next();
1362 goto top;
1363 }
1364 }
1365 }
1366
1367 return status;
1368}
1369
1370SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_signal_state_change(switch_core_session_t *session)
1371{
1372 switch_status_t status = SWITCH_STATUS_SUCCESS;
1373 switch_io_event_hook_state_change_t *ptr;
1374
1375 switch_core_session_wake_session_thread(session);
1376
1377 if (session->endpoint_interface->io_routines->state_change) {
1378 status = session->endpoint_interface->io_routines->state_change(session);
1379 }
1380
1381 if (status == SWITCH_STATUS_SUCCESS) {
1382 for (ptr = session->event_hooks.state_change; ptr; ptr = ptr->next) {
1383 if ((status = ptr->state_change(session)) != SWITCH_STATUS_SUCCESS) {
1384 break;
1385 }
1386 }
1387 }
1388 switch_core_session_kill_channel(session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session, "src/switch_core_session.c"
, (const char *)__func__, 1388, SWITCH_SIG_BREAK)
;
1389}
1390
1391SWITCH_DECLARE(unsigned int)__attribute__((visibility("default"))) unsigned int switch_core_session_running(switch_core_session_t *session)
1392{
1393 return switch_test_flag(session, SSF_THREAD_RUNNING)((session)->flags & SSF_THREAD_RUNNING) ? 1 : 0;
1394}
1395
1396SWITCH_DECLARE(unsigned int)__attribute__((visibility("default"))) unsigned int switch_core_session_started(switch_core_session_t *session)
1397{
1398 return switch_test_flag(session, SSF_THREAD_STARTED)((session)->flags & SSF_THREAD_STARTED) ? 1 : 0;
1399}
1400
1401SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_session_sync_clock(void)
1402{
1403 int doit = 0;
1404
1405 switch_mutex_lock(runtime.session_hash_mutex);
1406 if (session_manager.session_count == 0) {
1407 doit = 1;
1408 } else {
1409 switch_set_flag((&runtime), SCF_SYNC_CLOCK_REQUESTED)((&runtime))->flags |= (SCF_SYNC_CLOCK_REQUESTED);
1410 }
1411 switch_mutex_unlock(runtime.session_hash_mutex);
1412
1413 if (doit) {
1414 switch_time_sync();
1415 }
1416
1417 return doit;
1418
1419}
1420
1421SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_perform_destroy(switch_core_session_t **session, const char *file, const char *func, int line)
1422{
1423 switch_memory_pool_t *pool;
1424 switch_event_t *event;
1425 switch_endpoint_interface_t *endpoint_interface = (*session)->endpoint_interface;
1426 int i;
1427
1428
1429 switch_core_session_flush_private_events(*session);
1430
1431 if (switch_core_session_running(*session) && !switch_test_flag((*session), SSF_DESTROYABLE)(((*session))->flags & SSF_DESTROYABLE)) {
1432 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(*session), SWITCH_LOG_ERROR,
1433 "Cowardly ignoring an attempt to call destroy on a running session.\n");
1434 }
1435
1436 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(*session), SWITCH_LOG_NOTICE, "Close Channel %s [%s]\n",
1437 switch_channel_get_name((*session)->channel), switch_channel_state_name(switch_channel_get_state((*session)->channel)));
1438
1439
1440 switch_core_session_reset(*session, SWITCH_TRUE, SWITCH_TRUE);
1441
1442 switch_core_media_bug_remove_all(*session)switch_core_media_bug_remove_all_function(*session, ((void*)0
))
;
1443 switch_ivr_deactivate_unicast(*session);
1444
1445 switch_scheduler_del_task_group((*session)->uuid_str);
1446
1447 switch_mutex_lock(runtime.session_hash_mutex);
1448 switch_core_hash_delete(session_manager.session_table, (*session)->uuid_str);
1449 if (session_manager.session_count) {
1450 session_manager.session_count--;
1451 if (session_manager.session_count == 0) {
1452 if (switch_test_flag((&runtime), SCF_SYNC_CLOCK_REQUESTED)(((&runtime))->flags & SCF_SYNC_CLOCK_REQUESTED)) {
1453 switch_time_sync();
1454 switch_clear_flag((&runtime), SCF_SYNC_CLOCK_REQUESTED)((&runtime))->flags &= ~(SCF_SYNC_CLOCK_REQUESTED);
1455 }
1456 }
1457 }
1458 switch_mutex_unlock(runtime.session_hash_mutex);
1459
1460 if ((*session)->plc) {
1461 plc_free((*session)->plc);
1462 (*session)->plc = NULL((void*)0);
1463 }
1464
1465 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DESTROY)switch_event_create_subclass_detailed("src/switch_core_session.c"
, (const char * )(const char *)__func__, 1465, &event, SWITCH_EVENT_CHANNEL_DESTROY
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1466 switch_channel_event_set_data((*session)->channel, event);
1467 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_session.c", (const
char * )(const char *)__func__, 1467, &event, ((void*)0)
)
;
1468 }
1469
1470 switch_core_session_destroy_state(*session);
1471
1472 switch_buffer_destroy(&(*session)->raw_read_buffer);
1473 switch_buffer_destroy(&(*session)->raw_write_buffer);
1474 switch_ivr_clear_speech_cache(*session);
1475 switch_channel_uninit((*session)->channel);
1476
1477 for (i = 0; i < 2; i++) {
1478 if ((*session)->dmachine[i]) {
1479 switch_ivr_dmachine_destroy(&(*session)->dmachine[i]);
1480 }
1481 }
1482
1483 pool = (*session)->pool;
1484 //#ifndef NDEBUG
1485 //memset(*session, 0, sizeof(switch_core_session_t));
1486 //#endif
1487 *session = NULL((void*)0);
1488 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 1488)
;
1489
1490 UNPROTECT_INTERFACE(endpoint_interface)if (endpoint_interface) {switch_mutex_lock(endpoint_interface
->reflock); switch_thread_rwlock_unlock(endpoint_interface
->rwlock); switch_thread_rwlock_unlock(endpoint_interface->
parent->rwlock); endpoint_interface->refs--; endpoint_interface
->parent->refs--; switch_mutex_unlock(endpoint_interface
->reflock);}
;
1491}
1492
1493
1494
1495SWITCH_STANDARD_SCHED_FUNC(sch_heartbeat_callback)static void sch_heartbeat_callback (switch_scheduler_task_t *
task)
1496{
1497 switch_event_t *event;
1498 switch_core_session_t *session;
1499 char *uuid = task->cmd_arg;
1500 switch_core_session_message_t msg = { 0 };
1501
1502 if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_core_session.c"
, (const char *)__func__, 1502)
)) {
1503 switch_event_create(&event, SWITCH_EVENT_SESSION_HEARTBEAT)switch_event_create_subclass_detailed("src/switch_core_session.c"
, (const char * )(const char *)__func__, 1503, &event, SWITCH_EVENT_SESSION_HEARTBEAT
, ((void*)0))
;
1504 switch_channel_event_set_data(session->channel, event);
1505 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_session.c", (const
char * )(const char *)__func__, 1505, &event, ((void*)0)
)
;
1506
1507 /* reschedule this task */
1508 task->runtime = switch_epoch_time_now(NULL((void*)0)) + session->track_duration;
1509
1510 msg.message_id = SWITCH_MESSAGE_HEARTBEAT_EVENT;
1511 msg.numeric_arg = session->track_duration;
1512 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_core_session.c", (const char *)__func__, 1512)
;
1513
1514 switch_core_session_rwunlock(session);
1515 }
1516}
1517
1518SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_unsched_heartbeat(switch_core_session_t *session)
1519{
1520 if (session->track_id) {
1521 switch_scheduler_del_task_id(session->track_id);
1522 session->track_id = 0;
1523 }
1524}
1525
1526SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_sched_heartbeat(switch_core_session_t *session, uint32_t seconds)
1527{
1528 time_t when;
1529
1530 switch_core_session_unsched_heartbeat(session);
1531 if (switch_true(switch_channel_get_variable(session->channel, "heartbeat_fire_on_set")switch_channel_get_variable_dup(session->channel, "heartbeat_fire_on_set"
, SWITCH_TRUE, -1)
)) {
1532 when = switch_epoch_time_now(NULL((void*)0));
1533 } else {
1534 when = switch_epoch_time_now(NULL((void*)0)) + session->track_duration;
1535 }
1536
1537 session->track_id = switch_scheduler_add_task(when, sch_heartbeat_callback, (char *) __SWITCH_FUNC__(const char *)__func__,
1538 switch_core_session_get_uuid(session), 0, strdup(switch_core_session_get_uuid(session))(__extension__ (__builtin_constant_p (switch_core_session_get_uuid
(session)) && ((size_t)(const void *)((switch_core_session_get_uuid
(session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(session)) == 1) ? (((const char *) (switch_core_session_get_uuid
(session)))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen (switch_core_session_get_uuid
(session)) + 1; char *__retval = (char *) malloc (__len); if (
__retval != ((void*)0)) __retval = (char *) memcpy (__retval,
switch_core_session_get_uuid(session), __len); __retval; }))
: __strdup (switch_core_session_get_uuid(session))))
, SSHF_FREE_ARG);
1539}
1540
1541SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_enable_heartbeat(switch_core_session_t *session, uint32_t seconds)
1542{
1543 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1543, __PRETTY_FUNCTION__))
;
1544
1545 if (!seconds) {
1546 seconds = 60;
1547 }
1548
1549 session->track_duration = seconds;
1550
1551 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || !switch_channel_media_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_TRUE
)
||
1552 switch_true(switch_channel_get_variable_dup(session->channel, "heartbeat_use_scheduler", SWITCH_FALSE, -1)) ||
1553 switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media", SWITCH_FALSE, -1)) ||
1554 switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_after_bridge", SWITCH_FALSE, -1))) {
1555 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1555, (const char*)(session)
, SWITCH_LOG_WARNING, "%s using scheduler due to bypass media or media is not established.\n",
1556 switch_channel_get_name(session->channel));
1557 switch_core_session_sched_heartbeat(session, seconds);
1558 return;
1559 }
1560
1561 if (switch_true(switch_channel_get_variable(session->channel, "heartbeat_fire_on_set")switch_channel_get_variable_dup(session->channel, "heartbeat_fire_on_set"
, SWITCH_TRUE, -1)
)) {
1562 session->read_frame_count = 0;
1563 } else {
1564 session->read_frame_count = (session->read_impl.samples_per_second / session->read_impl.samples_per_packet) * seconds;
1565 }
1566
1567 switch_core_session_unsched_heartbeat(session);
1568
1569 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1569, (const char*)(session)
, SWITCH_LOG_INFO, "%s setting session heartbeat to %u second(s).\n",
1570 switch_channel_get_name(session->channel), seconds);
1571
1572}
1573
1574SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_disable_heartbeat(switch_core_session_t *session)
1575{
1576 switch_core_session_unsched_heartbeat(session);
1577 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 1577, __PRETTY_FUNCTION__))
;
1578 session->read_frame_count = 0;
1579 session->track_duration = 0;
1580
1581}
1582
1583SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_core_session_in_thread(switch_core_session_t *session)
1584{
1585 return switch_thread_equal(switch_thread_self(), session->thread_id) ? SWITCH_TRUE : SWITCH_FALSE;
1586}
1587
1588static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thread, void *obj)
1589{
1590 switch_core_session_t *session = obj;
1591 switch_event_t *event;
1592 char *event_str = NULL((void*)0);
1593 const char *val;
1594
1595 session->thread = thread;
1596 session->thread_id = switch_thread_self();
1597
1598 switch_core_session_run(session);
1599 switch_core_media_bug_remove_all(session)switch_core_media_bug_remove_all_function(session, ((void*)0)
)
;
1600
1601 if (session->soft_lock) {
1602 uint32_t loops = session->soft_lock * 10;
1603
1604 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1604, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session %" SWITCH_SIZE_T_FMT"ld" " (%s) Soft-Locked, "
1605 "Waiting %u for external entities\n",
1606 session->id, switch_channel_get_name(session->channel), session->soft_lock);
1607
1608 while(--loops > 0) {
1609 if (!session->soft_lock) break;
1610 switch_yield(100000)switch_sleep(100000);;
1611 }
1612
1613 }
1614
1615 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1615, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session %" SWITCH_SIZE_T_FMT"ld" " (%s) Locked, Waiting on external entities\n",
1616 session->id, switch_channel_get_name(session->channel));
1617 switch_core_session_write_lock(session);
1618 switch_set_flag(session, SSF_DESTROYED)(session)->flags |= (SSF_DESTROYED);
1619
1620 if ((val = switch_channel_get_variable(session->channel, "memory_debug")switch_channel_get_variable_dup(session->channel, "memory_debug"
, SWITCH_TRUE, -1)
) && switch_true(val)) {
1621 if (switch_event_create(&event, SWITCH_EVENT_GENERAL)switch_event_create_subclass_detailed("src/switch_core_session.c"
, (const char * )(const char *)__func__, 1621, &event, SWITCH_EVENT_GENERAL
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1622 switch_channel_event_set_data(session->channel, event);
1623 switch_event_serialize(event, &event_str, SWITCH_FALSE);
1624 switch_assert(event_str)((event_str) ? (void) (0) : __assert_fail ("event_str", "src/switch_core_session.c"
, 1624, __PRETTY_FUNCTION__))
;
1625 switch_core_memory_pool_tag(switch_core_session_get_pool(session), switch_core_session_strdup(session, event_str)switch_core_perform_session_strdup(session, event_str, "src/switch_core_session.c"
, (const char *)__func__, 1625)
);
1626 free(event_str);
1627 switch_event_destroy(&event);
1628 }
1629 }
1630
1631 switch_core_session_rwunlock(session);
1632
1633 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1633, (const char*)(session)
, SWITCH_LOG_NOTICE, "Session %" SWITCH_SIZE_T_FMT"ld" " (%s) Ended\n",
1634 session->id, switch_channel_get_name(session->channel));
1635
1636 switch_set_flag(session, SSF_DESTROYABLE)(session)->flags |= (SSF_DESTROYABLE);
1637 switch_core_session_destroy(&session)switch_core_session_perform_destroy(&session, "src/switch_core_session.c"
, (const char *)__func__, 1637)
;
1638 return NULL((void*)0);
1639}
1640
1641typedef struct switch_thread_pool_node_s {
1642 switch_memory_pool_t *pool;
1643} switch_thread_pool_node_t;
1644
1645static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_thread_t *thread, void *obj)
1646{
1647 switch_thread_pool_node_t *node = (switch_thread_pool_node_t *) obj;
1648 switch_memory_pool_t *pool = node->pool;
1649 void *pop;
1650 int check = 0;
1651
1652 switch_mutex_lock(session_manager.mutex);
1653 session_manager.starting--;
1654 session_manager.running++;
1655 switch_mutex_unlock(session_manager.mutex);
1656#ifdef DEBUG_THREAD_POOL
1657 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 1657, ((void*)0)
, SWITCH_LOG_DEBUG10, "Worker Thread %ld Started\n", (long) thread);
1658#endif
1659 while(session_manager.ready) {
1660 switch_status_t check_status;
1661
1662 pop = NULL((void*)0);
1663
1664 if (check) {
1665 check_status = switch_queue_trypop(session_manager.thread_queue, &pop);
1666 } else {
1667 switch_mutex_lock(session_manager.mutex);
1668 session_manager.popping++;
1669 switch_mutex_unlock(session_manager.mutex);
1670
1671 check_status = switch_queue_pop(session_manager.thread_queue, &pop);
1672
1673 switch_mutex_lock(session_manager.mutex);
1674 session_manager.popping--;
1675 switch_mutex_unlock(session_manager.mutex);
1676 }
1677
1678 if (check_status == SWITCH_STATUS_SUCCESS && pop) {
1679 switch_thread_data_t *td = (switch_thread_data_t *) pop;
1680
1681 if (!td) break;
1682
1683 switch_mutex_lock(session_manager.mutex);
1684 session_manager.busy++;
1685 switch_mutex_unlock(session_manager.mutex);
1686#ifdef DEBUG_THREAD_POOL
1687 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 1687, ((void*)0)
, SWITCH_LOG_DEBUG10, "Worker Thread %ld Processing\n", (long) thread);
1688#endif
1689
1690 td->func(thread, td->obj);
1691
1692 if (td->pool) {
1693 switch_memory_pool_t *pool = td->pool;
1694 td = NULL((void*)0);
1695 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 1695)
;
1696 } else if (td->alloc) {
1697 free(td);
1698 }
1699#ifdef DEBUG_THREAD_POOL
1700 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 1700, ((void*)0)
, SWITCH_LOG_DEBUG10, "Worker Thread %ld Done Processing\n", (long) thread);
1701#endif
1702 switch_mutex_lock(session_manager.mutex);
1703 session_manager.busy--;
1704 switch_mutex_unlock(session_manager.mutex);
1705
1706 } else {
1707 if (check) {
1708 break;
1709 }
1710 check++;
1711 }
1712 }
1713#ifdef DEBUG_THREAD_POOL
1714 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 1714, ((void*)0)
, SWITCH_LOG_DEBUG10, "Worker Thread %ld Ended\n", (long) thread);
1715#endif
1716 switch_mutex_lock(session_manager.mutex);
1717 session_manager.running--;
1718 switch_mutex_unlock(session_manager.mutex);
1719
1720 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 1720)
;
1721
1722 return NULL((void*)0);
1723}
1724
1725static void thread_launch_failure(void)
1726{
1727 uint32_t sess_count;
1728
1729 switch_mutex_lock(session_manager.mutex);
1730
1731 sess_count = switch_core_session_count();
1732
1733 if (sess_count > 110) {
1734
1735 switch_core_session_limit(sess_count - 10);
1736 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 1736, ((void*)0)
, SWITCH_LOG_CRIT, "LUKE: I'm hit, but not bad.\n");
1737 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 1737, ((void*)0)
, SWITCH_LOG_CRIT,
1738 "LUKE'S VOICE: Artoo, see what you can do with it. Hang on back there....\n"
1739 "Green laserfire moves past the beeping little robot as his head turns. "
1740 "After a few beeps and a twist of his mechanical arm,\n"
1741 "Artoo reduces the max sessions to %d thus, saving the switch from certain doom.\n", sess_count - 10);
1742
1743 }
1744
1745 switch_mutex_unlock(session_manager.mutex);
1746}
1747
1748static int wake_queue(void)
1749{
1750 switch_status_t status;
1751 int tries = 0;
1752
1753 top:
1754
1755 status = switch_mutex_trylock(session_manager.cond_mutex);
1756
1757 if (status == SWITCH_STATUS_SUCCESS) {
1758 switch_thread_cond_signal(session_manager.cond);
1759 switch_mutex_unlock(session_manager.cond_mutex);
1760 return 1;
1761 } else {
1762 if (switch_mutex_trylock(session_manager.cond2_mutex) == SWITCH_STATUS_SUCCESS) {
1763 switch_mutex_unlock(session_manager.cond2_mutex);
1764 } else {
1765 if (++tries < 10) {
1766 switch_cond_next();
1767 goto top;
1768 }
1769 }
1770 }
1771
1772 return 0;
1773}
1774
1775static switch_status_t check_queue(void)
1776{
1777 switch_status_t status = SWITCH_STATUS_FALSE;
1778 int ttl = 0;
1779 int x = 0;
1780
1781 switch_mutex_lock(session_manager.mutex);
1782 ttl = switch_queue_size(session_manager.thread_queue);
1783 x = ((session_manager.running + session_manager.starting) - session_manager.busy);
1784 switch_mutex_unlock(session_manager.mutex);
1785
1786
1787 while (x < ttl) {
1788 switch_thread_t *thread;
1789 switch_threadattr_t *thd_attr;
1790 switch_memory_pool_t *pool;
1791 switch_thread_pool_node_t *node;
1792
1793 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 1793)
;
1794 node = switch_core_alloc(pool, sizeof(*node))switch_core_perform_alloc(pool, sizeof(*node), "src/switch_core_session.c"
, (const char *)__func__, 1794)
;
1795 node->pool = pool;
1796
1797 switch_threadattr_create(&thd_attr, node->pool);
1798 switch_threadattr_detach_set(thd_attr, 1);
1799 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
1800 switch_threadattr_priority_set(thd_attr, SWITCH_PRI_LOW);
1801
1802 if (switch_thread_create(&thread, thd_attr, switch_core_session_thread_pool_worker, node, node->pool) != SWITCH_STATUS_SUCCESS) {
1803 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 1803, ((void*)0)
, SWITCH_LOG_CRIT, "Thread Failure!\n");
1804 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_session.c"
, (const char *)__func__, 1804)
;
1805 status = SWITCH_STATUS_GENERR;
1806 thread_launch_failure();
1807 } else {
1808 status = SWITCH_STATUS_SUCCESS;
1809 }
1810
1811 switch_mutex_lock(session_manager.mutex);
1812 session_manager.starting++;
1813 switch_mutex_unlock(session_manager.mutex);
1814 x++;
1815 }
1816
1817 return status;
1818}
1819
1820
1821static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_manager(switch_thread_t *thread, void *obj)
1822{
1823
1824 uint32_t sleep = 10000000;
1825 switch_time_t next = switch_micro_time_now() + sleep;
1826
1827 switch_mutex_lock(session_manager.cond_mutex);
1828
1829 while(session_manager.ready) {
1830 int check = 1;
1831 int ttl = 0;
1832 uint32_t xsleep = sleep;
1833
1834 switch_mutex_lock(session_manager.mutex);
1835 ttl = switch_queue_size(session_manager.thread_queue);
1836 switch_mutex_unlock(session_manager.mutex);
1837
1838
1839 if (!ttl) {
1840 xsleep = 10000;
1841 }
1842
1843 switch_mutex_lock(session_manager.cond2_mutex);
1844 switch_thread_cond_timedwait(session_manager.cond, session_manager.cond_mutex, xsleep);
1845 switch_mutex_unlock(session_manager.cond2_mutex);
1846
1847
1848 if (switch_micro_time_now() >= next) {
1849 if (session_manager.popping) {
1850#ifdef DEBUG_THREAD_POOL
1851 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 1851, ((void*)0)
, SWITCH_LOG_DEBUG10,
1852 "Thread pool: running:%d busy:%d popping:%d\n", session_manager.running, session_manager.busy, session_manager.popping);
1853#endif
1854 switch_queue_interrupt_all(session_manager.thread_queue);
1855
1856 sleep = 100000;
1857 check = 0;
1858 } else {
1859 sleep = 10000000;
1860 }
1861 }
1862
1863 if (check) check_queue();
1864
1865 next = switch_micro_time_now() + sleep;
1866 }
1867
1868 switch_mutex_unlock(session_manager.cond_mutex);
1869
1870 while(session_manager.running) {
1871 switch_queue_interrupt_all(session_manager.thread_queue);
1872 switch_yield(20000)switch_sleep(20000);;
1873 }
1874
1875
1876 return NULL((void*)0);
1877}
1878
1879SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_thread_pool_launch_thread(switch_thread_data_t **tdp)
1880{
1881 switch_status_t status = SWITCH_STATUS_SUCCESS;
1882 switch_thread_data_t *td;
1883
1884 switch_assert(tdp)((tdp) ? (void) (0) : __assert_fail ("tdp", "src/switch_core_session.c"
, 1884, __PRETTY_FUNCTION__))
;
1885
1886 td = *tdp;
1887 *tdp = NULL((void*)0);
1888
1889 switch_queue_push(session_manager.thread_queue, td);
1890 wake_queue();
1891
1892 return status;
1893}
1894
1895SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_thread_pool_launch(switch_core_session_t *session)
1896{
1897 switch_status_t status = SWITCH_STATUS_INUSE;
1898 switch_thread_data_t *td;
1899
1900 switch_mutex_lock(session->mutex);
1901 if (switch_test_flag(session, SSF_THREAD_RUNNING)((session)->flags & SSF_THREAD_RUNNING)) {
1902 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1902, (const char*)(session)
, SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
1903 } else if (switch_test_flag(session, SSF_THREAD_STARTED)((session)->flags & SSF_THREAD_STARTED)) {
1904 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1904, (const char*)(session)
, SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n");
1905 } else {
1906 status = SWITCH_STATUS_SUCCESS;
1907 switch_set_flag(session, SSF_THREAD_RUNNING)(session)->flags |= (SSF_THREAD_RUNNING);
1908 switch_set_flag(session, SSF_THREAD_STARTED)(session)->flags |= (SSF_THREAD_STARTED);
1909 td = switch_core_session_alloc(session, sizeof(*td))switch_core_perform_session_alloc(session, sizeof(*td), "src/switch_core_session.c"
, (const char *)__func__, 1909)
;
1910 td->obj = session;
1911 td->func = switch_core_session_thread;
1912 switch_queue_push(session_manager.thread_queue, td);
1913 wake_queue();
1914 }
1915 switch_mutex_unlock(session->mutex);
1916
1917 return status;
1918}
1919
1920
1921SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_thread_launch(switch_core_session_t *session)
1922{
1923 switch_status_t status = SWITCH_STATUS_FALSE;
1924 switch_thread_t *thread;
1925 switch_threadattr_t *thd_attr;
1926
1927 if (switch_test_flag(session, SSF_THREAD_RUNNING)((session)->flags & SSF_THREAD_RUNNING) || switch_test_flag(session, SSF_THREAD_STARTED)((session)->flags & SSF_THREAD_STARTED)) {
1928 status = SWITCH_STATUS_INUSE;
1929 goto end;
1930 }
1931
1932
1933 if (switch_test_flag((&runtime), SCF_SESSION_THREAD_POOL)(((&runtime))->flags & SCF_SESSION_THREAD_POOL)) {
1934 return switch_core_session_thread_pool_launch(session);
1935 }
1936
1937 switch_mutex_lock(session->mutex);
1938
1939 if (switch_test_flag(session, SSF_THREAD_RUNNING)((session)->flags & SSF_THREAD_RUNNING)) {
1940 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1940, (const char*)(session)
, SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
1941 } else if (switch_test_flag(session, SSF_THREAD_STARTED)((session)->flags & SSF_THREAD_STARTED)) {
1942 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1942, (const char*)(session)
, SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n");
1943 } else {
1944 switch_set_flag(session, SSF_THREAD_RUNNING)(session)->flags |= (SSF_THREAD_RUNNING);
1945 switch_set_flag(session, SSF_THREAD_STARTED)(session)->flags |= (SSF_THREAD_STARTED);
1946
1947 switch_threadattr_create(&thd_attr, session->pool);
1948 switch_threadattr_detach_set(thd_attr, 1);
1949 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
1950
1951 if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) == SWITCH_STATUS_SUCCESS) {
1952 switch_set_flag(session, SSF_THREAD_STARTED)(session)->flags |= (SSF_THREAD_STARTED);
1953 status = SWITCH_STATUS_SUCCESS;
1954 } else {
1955 switch_clear_flag(session, SSF_THREAD_RUNNING)(session)->flags &= ~(SSF_THREAD_RUNNING);
1956 switch_clear_flag(session, SSF_THREAD_STARTED)(session)->flags &= ~(SSF_THREAD_STARTED);
1957 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1957, (const char*)(session)
, SWITCH_LOG_CRIT, "Cannot create thread!\n");
1958 thread_launch_failure();
1959 }
1960 }
1961
1962 switch_mutex_unlock(session->mutex);
1963
1964 end:
1965
1966 return status;
1967}
1968
1969SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_launch_thread(switch_core_session_t *session, switch_thread_start_t func, void *obj)
1970{
1971 switch_thread_t *thread;
1972 switch_threadattr_t *thd_attr = NULL((void*)0);
1973 switch_threadattr_create(&thd_attr, session->pool);
1974 switch_threadattr_detach_set(thd_attr, 1);
1975
1976 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
1977 if (switch_thread_create(&thread, thd_attr, func, obj, session->pool) != SWITCH_STATUS_SUCCESS) {
1978 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1978, (const char*)(session)
, SWITCH_LOG_CRIT, "Cannot create thread!\n");
1979 thread_launch_failure();
1980 }
1981
1982}
1983
1984SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_set_uuid(switch_core_session_t *session, const char *use_uuid)
1985{
1986 switch_event_t *event;
1987 switch_core_session_message_t msg = { 0 };
1988 switch_caller_profile_t *profile;
1989
1990 switch_assert(use_uuid)((use_uuid) ? (void) (0) : __assert_fail ("use_uuid", "src/switch_core_session.c"
, 1990, __PRETTY_FUNCTION__))
;
1991
1992 if (!strcmp(use_uuid, session->uuid_str)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(use_uuid) && __builtin_constant_p (session->uuid_str
) && (__s1_len = __builtin_strlen (use_uuid), __s2_len
= __builtin_strlen (session->uuid_str), (!((size_t)(const
void *)((use_uuid) + 1) - (size_t)(const void *)(use_uuid) ==
1) || __s1_len >= 4) && (!((size_t)(const void *)
((session->uuid_str) + 1) - (size_t)(const void *)(session
->uuid_str) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(use_uuid, session->uuid_str) : (__builtin_constant_p (use_uuid
) && ((size_t)(const void *)((use_uuid) + 1) - (size_t
)(const void *)(use_uuid) == 1) && (__s1_len = __builtin_strlen
(use_uuid), __s1_len < 4) ? (__builtin_constant_p (session
->uuid_str) && ((size_t)(const void *)((session->
uuid_str) + 1) - (size_t)(const void *)(session->uuid_str)
== 1) ? __builtin_strcmp (use_uuid, session->uuid_str) : (
__extension__ ({ const unsigned char *__s2 = (const unsigned char
*) (const char *) (session->uuid_str); int __result = (((
const unsigned char *) (const char *) (use_uuid))[0] - __s2[0
]); if (__s1_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (use_uuid))[1] - __s2
[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (use_uuid))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (use_uuid))[3] - __s2
[3]); } } __result; }))) : (__builtin_constant_p (session->
uuid_str) && ((size_t)(const void *)((session->uuid_str
) + 1) - (size_t)(const void *)(session->uuid_str) == 1) &&
(__s2_len = __builtin_strlen (session->uuid_str), __s2_len
< 4) ? (__builtin_constant_p (use_uuid) && ((size_t
)(const void *)((use_uuid) + 1) - (size_t)(const void *)(use_uuid
) == 1) ? __builtin_strcmp (use_uuid, session->uuid_str) :
(- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (use_uuid); int __result = (((const unsigned
char *) (const char *) (session->uuid_str))[0] - __s2[0])
; if (__s2_len > 0 && __result == 0) { __result = (
((const unsigned char *) (const char *) (session->uuid_str
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (session
->uuid_str))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (session->uuid_str))[3] - __s2[3]); } } __result; })))
) : __builtin_strcmp (use_uuid, session->uuid_str)))); })
) {
1993 return SWITCH_STATUS_SUCCESS;
1994 }
1995
1996
1997 switch_mutex_lock(runtime.session_hash_mutex);
1998 if (switch_core_hash_find(session_manager.session_table, use_uuid)) {
1999 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 1999, (const char*)(session)
, SWITCH_LOG_CRIT, "Duplicate UUID!\n");
2000 switch_mutex_unlock(runtime.session_hash_mutex);
2001 return SWITCH_STATUS_FALSE;
2002 }
2003
2004 msg.message_id = SWITCH_MESSAGE_INDICATE_UUID_CHANGE;
2005 msg.from = switch_channel_get_name(session->channel);
2006 msg.string_array_arg[0] = session->uuid_str;
2007 msg.string_array_arg[1] = use_uuid;
2008 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_core_session.c", (const char *)__func__, 2008)
;
2009
2010 if ((profile = switch_channel_get_caller_profile(session->channel))) {
2011 profile->uuid = switch_core_strdup(profile->pool, use_uuid)switch_core_perform_strdup(profile->pool, use_uuid, "src/switch_core_session.c"
, (const char *)__func__, 2011)
;
2012 }
2013
2014 switch_channel_set_variable(session->channel, "uuid", use_uuid)switch_channel_set_variable_var_check(session->channel, "uuid"
, use_uuid, SWITCH_TRUE)
;
2015 switch_channel_set_variable(session->channel, "call_uuid", use_uuid)switch_channel_set_variable_var_check(session->channel, "call_uuid"
, use_uuid, SWITCH_TRUE)
;
2016
2017 switch_event_create(&event, SWITCH_EVENT_CHANNEL_UUID)switch_event_create_subclass_detailed("src/switch_core_session.c"
, (const char * )(const char *)__func__, 2017, &event, SWITCH_EVENT_CHANNEL_UUID
, ((void*)0))
;
2018 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-Unique-ID", session->uuid_str);
2019 switch_core_hash_delete(session_manager.session_table, session->uuid_str);
2020 switch_set_string(session->uuid_str, use_uuid)switch_copy_string(session->uuid_str, use_uuid, sizeof(session
->uuid_str))
;
2021 switch_core_hash_insert(session_manager.session_table, session->uuid_str, session)switch_core_hash_insert_destructor(session_manager.session_table
, session->uuid_str, session, ((void*)0))
;
2022 switch_mutex_unlock(runtime.session_hash_mutex);
2023 switch_channel_event_set_data(session->channel, event);
2024 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_session.c", (const
char * )(const char *)__func__, 2024, &event, ((void*)0)
)
;
2025
2026
2027 return SWITCH_STATUS_SUCCESS;
2028}
2029
2030static char *xml_find_var(switch_xml_t vars, const char *name)
2031{
2032 switch_xml_t var;
2033 if ((var = switch_xml_child(vars, name)) && var->txt) {
2034 return var->txt;
2035 }
2036
2037 return NULL((void*)0);
2038}
2039
2040static void parse_array(const char *str, uint32_t *array, int32_t array_len)
2041{
2042 char *p, *v, *dup, *next = NULL((void*)0);
2043
2044 if (zstr(str)_zstr(str)) {
2045 return;
2046 }
2047
2048 dup = strdup(str)(__extension__ (__builtin_constant_p (str) && ((size_t
)(const void *)((str) + 1) - (size_t)(const void *)(str) == 1
) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, str, __len); __retval
; })) : __strdup (str)))
;
2049
2050 p = dup;
2051 while (p) {
2052 if ((next = strchr(p, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(p) && (';') == '\0' ? (char *) __rawmemchr (p, ';')
: __builtin_strchr (p, ';')))
)) {
2053 *next++ = '\0';
2054 }
2055
2056 if ((v = strchr(p, '=')(__extension__ (__builtin_constant_p ('=') && !__builtin_constant_p
(p) && ('=') == '\0' ? (char *) __rawmemchr (p, '=')
: __builtin_strchr (p, '=')))
)) {
2057 *v++ = '\0';
2058 }
2059
2060 if (p && v) {
2061 int x = 0, y = 0;
2062
2063 x = atoi(p);
2064 y = atoi(v);
2065
2066 if (x < array_len) {
2067 array[x] = y;
2068 }
2069 }
2070
2071 p = next;
2072
2073 }
2074
2075 free(dup);
2076}
2077
2078SWITCH_DECLARE(switch_core_session_t *)__attribute__((visibility("default"))) switch_core_session_t * switch_core_session_request_xml(switch_endpoint_interface_t *endpoint_interface,
2079 switch_memory_pool_t **pool, switch_xml_t xml)
2080{
2081 switch_core_session_t *session;
2082 switch_channel_t *channel;
2083 switch_xml_t tag, tag2, tag3, vars, callflow;
2084 switch_call_direction_t direction = SWITCH_CALL_DIRECTION_OUTBOUND;
2085 char *flag_str = NULL((void*)0), *cap_str = NULL((void*)0), *direction_s = NULL((void*)0), *uuid = NULL((void*)0);
2086 uint32_t flags[CF_FLAG_MAX] = { 0 };
2087 uint32_t caps[CC_FLAG_MAX] = { 0 };
2088 int i;
2089
2090 vars = switch_xml_child(xml, "variables");
2091 uuid = xml_find_var(vars, "uuid");
2092
2093 if ((tag = switch_xml_child(xml, "channel_data"))) {
2094 direction_s = xml_find_var(tag, "direction");
2095 direction = !strcmp(direction_s, "outbound")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(direction_s) && __builtin_constant_p ("outbound") &&
(__s1_len = __builtin_strlen (direction_s), __s2_len = __builtin_strlen
("outbound"), (!((size_t)(const void *)((direction_s) + 1) -
(size_t)(const void *)(direction_s) == 1) || __s1_len >= 4
) && (!((size_t)(const void *)(("outbound") + 1) - (size_t
)(const void *)("outbound") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(direction_s, "outbound") : (__builtin_constant_p (direction_s
) && ((size_t)(const void *)((direction_s) + 1) - (size_t
)(const void *)(direction_s) == 1) && (__s1_len = __builtin_strlen
(direction_s), __s1_len < 4) ? (__builtin_constant_p ("outbound"
) && ((size_t)(const void *)(("outbound") + 1) - (size_t
)(const void *)("outbound") == 1) ? __builtin_strcmp (direction_s
, "outbound") : (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) ("outbound"); int __result
= (((const unsigned char *) (const char *) (direction_s))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (direction_s))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (direction_s))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (direction_s))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p ("outbound"
) && ((size_t)(const void *)(("outbound") + 1) - (size_t
)(const void *)("outbound") == 1) && (__s2_len = __builtin_strlen
("outbound"), __s2_len < 4) ? (__builtin_constant_p (direction_s
) && ((size_t)(const void *)((direction_s) + 1) - (size_t
)(const void *)(direction_s) == 1) ? __builtin_strcmp (direction_s
, "outbound") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (direction_s); int __result
= (((const unsigned char *) (const char *) ("outbound"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("outbound"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("outbound"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("outbound"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (direction_s
, "outbound")))); })
? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND;
2096 flag_str = xml_find_var(tag, "flags");
2097 cap_str = xml_find_var(tag, "caps");
2098 }
2099
2100 parse_array(flag_str, flags, CF_FLAG_MAX);
2101 parse_array(cap_str, caps, CC_FLAG_MAX);
2102
2103 flags[CF_RECOVERING] = 0;
2104 flags[CF_RECOVERING_BRIDGE] = 0;
2105 flags[CF_TRACKED] = 0;
2106 flags[CF_TRANSFER] = 0;
2107 flags[CF_ACCEPT_CNG] = 0;
2108 flags[CF_REDIRECT] = 0;
2109 flags[CF_BRIDGED] = 0;
2110 flags[CF_HOLD] = 0;
2111 flags[CF_SERVICE] = 0;
2112 flags[CF_TAGGED] = 0;
2113 flags[CF_WINNER] = 0;
2114 flags[CF_EARLY_OK] = 0;
2115 flags[CF_CONTROLLED] = 0;
2116 flags[CF_SUSPEND] = 0;
2117 flags[CF_EVENT_PARSE] = 0;
2118 flags[CF_GEN_RINGBACK] = 0;
2119 flags[CF_BREAK] = 0;
2120 flags[CF_BROADCAST] = 0;
2121 flags[CF_UNICAST] = 0;
2122 flags[CF_EVENT_LOCK] = 0;
2123 flags[CF_EVENT_LOCK_PRI] = 0;
2124 flags[CF_RESET] = 0;
2125 flags[CF_ORIGINATING] = 0;
2126 flags[CF_STOP_BROADCAST] = 0;
2127 flags[CF_INNER_BRIDGE] = 0;
2128 flags[CF_REQ_MEDIA] = 0;
2129 flags[CF_PAUSE_BUGS] = 0;
2130 flags[CF_DIVERT_EVENTS] = 0;
2131 flags[CF_BLOCK_STATE] = 0;
2132 flags[CF_FS_RTP] = 0;
2133 flags[CF_REPORTING] = 0;
2134 flags[CF_PARK] = 0;
2135 flags[CF_TIMESTAMP_SET] = 0;
2136 flags[CF_ORIGINATOR] = 0;
2137 flags[CF_XFER_ZOMBIE] = 0;
2138 flags[CF_MEDIA_ACK] = 0;
2139 flags[CF_THREAD_SLEEPING] = 0;
2140 flags[CF_DISABLE_RINGBACK] = 0;
2141 flags[CF_NOT_READY] = 0;
2142 flags[CF_SIGNAL_BRIDGE_TTL] = 0;
2143 flags[CF_MEDIA_BRIDGE_TTL] = 0;
2144 flags[CF_BYPASS_MEDIA_AFTER_BRIDGE] = 0;
2145 flags[CF_LEG_HOLDING] = 0;
2146 flags[CF_BROADCAST_DROP_MEDIA] = 0;
2147 flags[CF_EARLY_HANGUP] = 0;
2148 flags[CF_MEDIA_SET] = 0;
2149 flags[CF_CONSUME_ON_ORIGINATE] = 0;
2150 flags[CF_PASSTHRU_PTIME_MISMATCH] = 0;
2151 flags[CF_BRIDGE_NOWRITE] = 0;
2152 flags[CF_RECOVERED] = 0;
2153 flags[CF_JITTERBUFFER] = 0;
2154 flags[CF_JITTERBUFFER_PLC] = 0;
2155 flags[CF_DIALPLAN] = 0;
2156 flags[CF_BLOCK_BROADCAST_UNTIL_MEDIA] = 0;
2157 flags[CF_CNG_PLC] = 0;
2158 flags[CF_ATTENDED_TRANSFER] = 0;
2159 flags[CF_LAZY_ATTENDED_TRANSFER] = 0;
2160 flags[CF_SIGNAL_DATA] = 0;
2161 flags[CF_SIMPLIFY] = 0;
2162
2163
2164 if (!(session = switch_core_session_request_uuid(endpoint_interface, direction, SOF_NO_LIMITS, pool, uuid))) {
2165 return NULL((void*)0);
2166 }
2167
2168 channel = switch_core_session_get_channel(session);
2169
2170 for (i = 0; i < CF_FLAG_MAX; i++) {
2171 if (flags[i]) {
2172 switch_channel_set_flag_value(channel, i, flags[i]);
2173 }
2174 }
2175
2176 for (i = 0; i < CC_FLAG_MAX; i++) {
2177 if (caps[i]) {
2178 switch_channel_set_cap_value(channel, i, caps[i]);
2179 }
2180 }
2181
2182 if ((tag2 = switch_xml_child(xml, "variables"))) {
2183 for (tag = tag2->child; tag; tag = tag->sibling) {
2184 if (tag->name && tag->txt) {
2185 char *p = strdup(tag->txt)(__extension__ (__builtin_constant_p (tag->txt) &&
((size_t)(const void *)((tag->txt) + 1) - (size_t)(const void
*)(tag->txt) == 1) ? (((const char *) (tag->txt))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (tag->txt) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, tag->txt, __len); __retval; })) : __strdup (tag
->txt)))
;
2186 char *val = p;
2187 switch_url_decode(val);
2188 switch_channel_set_variable(channel, tag->name, val)switch_channel_set_variable_var_check(channel, tag->name, val
, SWITCH_TRUE)
;
2189 if (!strcasecmp(tag->name, "channel_name")) {
2190 switch_channel_set_name(channel, val);
2191 }
2192 free(p);
2193 }
2194 }
2195 }
2196
2197 if ((callflow = switch_xml_child(xml, "callflow"))) {
2198 if ((tag2 = switch_xml_child(callflow, "caller_profile"))) {
2199 switch_caller_profile_t *caller_profile;
2200 char *tmp;
2201
2202 caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2203 xml_find_var(tag2, "username"),
2204 xml_find_var(tag2, "dialplan"),
2205 xml_find_var(tag2, "caller_id_name"),
2206 xml_find_var(tag2, "caller_id_number"),
2207 xml_find_var(tag2, "network_addr"),
2208 xml_find_var(tag2, "ani"),
2209 xml_find_var(tag2, "aniii"),
2210 xml_find_var(tag2, "rdnis"),
2211 xml_find_var(tag2, "source"),
2212 xml_find_var(tag2, "context"), xml_find_var(tag2, "destination_number"));
2213
2214 if ((tmp = xml_find_var(tag2, "callee_id_name"))) {
2215 caller_profile->callee_id_name = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_session.c"
, (const char *)__func__, 2215)
;
2216 }
2217
2218 if ((tmp = xml_find_var(tag2, "callee_id_number"))) {
2219 caller_profile->callee_id_number = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_session.c"
, (const char *)__func__, 2219)
;
2220 }
2221
2222 if ((tag3 = switch_xml_child(callflow, "times"))) {
2223 caller_profile->times = (switch_channel_timetable_t *) switch_core_session_alloc(session, sizeof(*caller_profile->times))switch_core_perform_session_alloc(session, sizeof(*caller_profile
->times), "src/switch_core_session.c", (const char *)__func__
, 2223)
;
2224
2225 caller_profile->times->resurrected = switch_time_now();
2226
2227 for (tag3 = tag3->child; tag3; tag3 = tag3->sibling) {
2228 int64_t v;
2229
2230 if (tag3->name && tag3->txt) {
2231 v = atoll(tag3->txt);
2232 if (!strcmp(tag3->name, "created_time")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tag3->name) && __builtin_constant_p ("created_time"
) && (__s1_len = __builtin_strlen (tag3->name), __s2_len
= __builtin_strlen ("created_time"), (!((size_t)(const void *
)((tag3->name) + 1) - (size_t)(const void *)(tag3->name
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("created_time") + 1) - (size_t)(const void *)("created_time"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (tag3->name
, "created_time") : (__builtin_constant_p (tag3->name) &&
((size_t)(const void *)((tag3->name) + 1) - (size_t)(const
void *)(tag3->name) == 1) && (__s1_len = __builtin_strlen
(tag3->name), __s1_len < 4) ? (__builtin_constant_p ("created_time"
) && ((size_t)(const void *)(("created_time") + 1) - (
size_t)(const void *)("created_time") == 1) ? __builtin_strcmp
(tag3->name, "created_time") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("created_time"
); int __result = (((const unsigned char *) (const char *) (tag3
->name))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
tag3->name))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tag3->name))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tag3->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("created_time") && ((size_t)(const void *)(("created_time"
) + 1) - (size_t)(const void *)("created_time") == 1) &&
(__s2_len = __builtin_strlen ("created_time"), __s2_len <
4) ? (__builtin_constant_p (tag3->name) && ((size_t
)(const void *)((tag3->name) + 1) - (size_t)(const void *)
(tag3->name) == 1) ? __builtin_strcmp (tag3->name, "created_time"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (tag3->name); int __result = (((const
unsigned char *) (const char *) ("created_time"))[0] - __s2[
0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("created_time"))
[1] - __s2[1]); if (__s2_len > 1 && __result == 0)
{ __result = (((const unsigned char *) (const char *) ("created_time"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("created_time"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (tag3
->name, "created_time")))); })
) {
2233 caller_profile->times->created = v;
2234 } else if (!strcmp(tag3->name, "profile_created_time")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tag3->name) && __builtin_constant_p ("profile_created_time"
) && (__s1_len = __builtin_strlen (tag3->name), __s2_len
= __builtin_strlen ("profile_created_time"), (!((size_t)(const
void *)((tag3->name) + 1) - (size_t)(const void *)(tag3->
name) == 1) || __s1_len >= 4) && (!((size_t)(const
void *)(("profile_created_time") + 1) - (size_t)(const void *
)("profile_created_time") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(tag3->name, "profile_created_time") : (__builtin_constant_p
(tag3->name) && ((size_t)(const void *)((tag3->
name) + 1) - (size_t)(const void *)(tag3->name) == 1) &&
(__s1_len = __builtin_strlen (tag3->name), __s1_len < 4
) ? (__builtin_constant_p ("profile_created_time") &&
((size_t)(const void *)(("profile_created_time") + 1) - (size_t
)(const void *)("profile_created_time") == 1) ? __builtin_strcmp
(tag3->name, "profile_created_time") : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
("profile_created_time"); int __result = (((const unsigned char
*) (const char *) (tag3->name))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (tag3->name))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (tag3->name))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (tag3->name))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("profile_created_time") &&
((size_t)(const void *)(("profile_created_time") + 1) - (size_t
)(const void *)("profile_created_time") == 1) && (__s2_len
= __builtin_strlen ("profile_created_time"), __s2_len < 4
) ? (__builtin_constant_p (tag3->name) && ((size_t
)(const void *)((tag3->name) + 1) - (size_t)(const void *)
(tag3->name) == 1) ? __builtin_strcmp (tag3->name, "profile_created_time"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (tag3->name); int __result = (((const
unsigned char *) (const char *) ("profile_created_time"))[0]
- __s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("profile_created_time"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("profile_created_time"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("profile_created_time"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (tag3
->name, "profile_created_time")))); })
) {
2235 caller_profile->times->profile_created = v;
2236 } else if (!strcmp(tag3->name, "progress_time")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tag3->name) && __builtin_constant_p ("progress_time"
) && (__s1_len = __builtin_strlen (tag3->name), __s2_len
= __builtin_strlen ("progress_time"), (!((size_t)(const void
*)((tag3->name) + 1) - (size_t)(const void *)(tag3->name
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("progress_time") + 1) - (size_t)(const void *)("progress_time"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (tag3->name
, "progress_time") : (__builtin_constant_p (tag3->name) &&
((size_t)(const void *)((tag3->name) + 1) - (size_t)(const
void *)(tag3->name) == 1) && (__s1_len = __builtin_strlen
(tag3->name), __s1_len < 4) ? (__builtin_constant_p ("progress_time"
) && ((size_t)(const void *)(("progress_time") + 1) -
(size_t)(const void *)("progress_time") == 1) ? __builtin_strcmp
(tag3->name, "progress_time") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("progress_time"
); int __result = (((const unsigned char *) (const char *) (tag3
->name))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
tag3->name))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tag3->name))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tag3->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("progress_time") && ((size_t)(const void *)(("progress_time"
) + 1) - (size_t)(const void *)("progress_time") == 1) &&
(__s2_len = __builtin_strlen ("progress_time"), __s2_len <
4) ? (__builtin_constant_p (tag3->name) && ((size_t
)(const void *)((tag3->name) + 1) - (size_t)(const void *)
(tag3->name) == 1) ? __builtin_strcmp (tag3->name, "progress_time"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (tag3->name); int __result = (((const
unsigned char *) (const char *) ("progress_time"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("progress_time")
)[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("progress_time"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("progress_time"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (tag3
->name, "progress_time")))); })
) {
2237 caller_profile->times->progress = v;
2238 } else if (!strcmp(tag3->name, "progress_media_time")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tag3->name) && __builtin_constant_p ("progress_media_time"
) && (__s1_len = __builtin_strlen (tag3->name), __s2_len
= __builtin_strlen ("progress_media_time"), (!((size_t)(const
void *)((tag3->name) + 1) - (size_t)(const void *)(tag3->
name) == 1) || __s1_len >= 4) && (!((size_t)(const
void *)(("progress_media_time") + 1) - (size_t)(const void *
)("progress_media_time") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(tag3->name, "progress_media_time") : (__builtin_constant_p
(tag3->name) && ((size_t)(const void *)((tag3->
name) + 1) - (size_t)(const void *)(tag3->name) == 1) &&
(__s1_len = __builtin_strlen (tag3->name), __s1_len < 4
) ? (__builtin_constant_p ("progress_media_time") && (
(size_t)(const void *)(("progress_media_time") + 1) - (size_t
)(const void *)("progress_media_time") == 1) ? __builtin_strcmp
(tag3->name, "progress_media_time") : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
("progress_media_time"); int __result = (((const unsigned char
*) (const char *) (tag3->name))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (tag3->name))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (tag3->name))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (tag3->name))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("progress_media_time") &&
((size_t)(const void *)(("progress_media_time") + 1) - (size_t
)(const void *)("progress_media_time") == 1) && (__s2_len
= __builtin_strlen ("progress_media_time"), __s2_len < 4)
? (__builtin_constant_p (tag3->name) && ((size_t)
(const void *)((tag3->name) + 1) - (size_t)(const void *)(
tag3->name) == 1) ? __builtin_strcmp (tag3->name, "progress_media_time"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (tag3->name); int __result = (((const
unsigned char *) (const char *) ("progress_media_time"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("progress_media_time"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("progress_media_time"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("progress_media_time"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (tag3
->name, "progress_media_time")))); })
) {
2239 caller_profile->times->progress_media = v;
2240 } else if (!strcmp(tag3->name, "answered_time")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tag3->name) && __builtin_constant_p ("answered_time"
) && (__s1_len = __builtin_strlen (tag3->name), __s2_len
= __builtin_strlen ("answered_time"), (!((size_t)(const void
*)((tag3->name) + 1) - (size_t)(const void *)(tag3->name
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("answered_time") + 1) - (size_t)(const void *)("answered_time"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (tag3->name
, "answered_time") : (__builtin_constant_p (tag3->name) &&
((size_t)(const void *)((tag3->name) + 1) - (size_t)(const
void *)(tag3->name) == 1) && (__s1_len = __builtin_strlen
(tag3->name), __s1_len < 4) ? (__builtin_constant_p ("answered_time"
) && ((size_t)(const void *)(("answered_time") + 1) -
(size_t)(const void *)("answered_time") == 1) ? __builtin_strcmp
(tag3->name, "answered_time") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("answered_time"
); int __result = (((const unsigned char *) (const char *) (tag3
->name))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
tag3->name))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tag3->name))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tag3->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("answered_time") && ((size_t)(const void *)(("answered_time"
) + 1) - (size_t)(const void *)("answered_time") == 1) &&
(__s2_len = __builtin_strlen ("answered_time"), __s2_len <
4) ? (__builtin_constant_p (tag3->name) && ((size_t
)(const void *)((tag3->name) + 1) - (size_t)(const void *)
(tag3->name) == 1) ? __builtin_strcmp (tag3->name, "answered_time"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (tag3->name); int __result = (((const
unsigned char *) (const char *) ("answered_time"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("answered_time")
)[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("answered_time"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("answered_time"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (tag3
->name, "answered_time")))); })
) {
2241 caller_profile->times->answered = v;
2242 } else if (!strcmp(tag3->name, "hangup_time")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tag3->name) && __builtin_constant_p ("hangup_time"
) && (__s1_len = __builtin_strlen (tag3->name), __s2_len
= __builtin_strlen ("hangup_time"), (!((size_t)(const void *
)((tag3->name) + 1) - (size_t)(const void *)(tag3->name
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("hangup_time") + 1) - (size_t)(const void *)("hangup_time"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (tag3->name
, "hangup_time") : (__builtin_constant_p (tag3->name) &&
((size_t)(const void *)((tag3->name) + 1) - (size_t)(const
void *)(tag3->name) == 1) && (__s1_len = __builtin_strlen
(tag3->name), __s1_len < 4) ? (__builtin_constant_p ("hangup_time"
) && ((size_t)(const void *)(("hangup_time") + 1) - (
size_t)(const void *)("hangup_time") == 1) ? __builtin_strcmp
(tag3->name, "hangup_time") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("hangup_time"
); int __result = (((const unsigned char *) (const char *) (tag3
->name))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
tag3->name))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tag3->name))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tag3->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("hangup_time") && ((size_t)(const void *)(("hangup_time"
) + 1) - (size_t)(const void *)("hangup_time") == 1) &&
(__s2_len = __builtin_strlen ("hangup_time"), __s2_len < 4
) ? (__builtin_constant_p (tag3->name) && ((size_t
)(const void *)((tag3->name) + 1) - (size_t)(const void *)
(tag3->name) == 1) ? __builtin_strcmp (tag3->name, "hangup_time"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (tag3->name); int __result = (((const
unsigned char *) (const char *) ("hangup_time"))[0] - __s2[0
]); if (__s2_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) ("hangup_time"))[1]
- __s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("hangup_time"))[
2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("hangup_time"))[
3] - __s2[3]); } } __result; })))) : __builtin_strcmp (tag3->
name, "hangup_time")))); })
) {
2243 caller_profile->times->hungup = v;
2244 } else if (!strcmp(tag3->name, "transfer_time")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tag3->name) && __builtin_constant_p ("transfer_time"
) && (__s1_len = __builtin_strlen (tag3->name), __s2_len
= __builtin_strlen ("transfer_time"), (!((size_t)(const void
*)((tag3->name) + 1) - (size_t)(const void *)(tag3->name
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("transfer_time") + 1) - (size_t)(const void *)("transfer_time"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (tag3->name
, "transfer_time") : (__builtin_constant_p (tag3->name) &&
((size_t)(const void *)((tag3->name) + 1) - (size_t)(const
void *)(tag3->name) == 1) && (__s1_len = __builtin_strlen
(tag3->name), __s1_len < 4) ? (__builtin_constant_p ("transfer_time"
) && ((size_t)(const void *)(("transfer_time") + 1) -
(size_t)(const void *)("transfer_time") == 1) ? __builtin_strcmp
(tag3->name, "transfer_time") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("transfer_time"
); int __result = (((const unsigned char *) (const char *) (tag3
->name))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
tag3->name))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tag3->name))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tag3->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("transfer_time") && ((size_t)(const void *)(("transfer_time"
) + 1) - (size_t)(const void *)("transfer_time") == 1) &&
(__s2_len = __builtin_strlen ("transfer_time"), __s2_len <
4) ? (__builtin_constant_p (tag3->name) && ((size_t
)(const void *)((tag3->name) + 1) - (size_t)(const void *)
(tag3->name) == 1) ? __builtin_strcmp (tag3->name, "transfer_time"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (tag3->name); int __result = (((const
unsigned char *) (const char *) ("transfer_time"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("transfer_time")
)[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("transfer_time"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("transfer_time"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (tag3
->name, "transfer_time")))); })
) {
2245 caller_profile->times->transferred = v;
2246 }
2247 }
2248
2249 }
2250 }
2251
2252 switch_channel_set_caller_profile(channel, caller_profile);
2253 if ((tag = switch_xml_child(tag2, "originator")) && (tag = tag->child)) {
2254 caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2255 xml_find_var(tag, "username"),
2256 xml_find_var(tag, "dialplan"),
2257 xml_find_var(tag, "caller_id_name"),
2258 xml_find_var(tag, "caller_id_number"),
2259 xml_find_var(tag, "network_addr"),
2260 xml_find_var(tag, "ani"),
2261 xml_find_var(tag, "aniii"),
2262 xml_find_var(tag, "rdnis"),
2263 xml_find_var(tag, "source"),
2264 xml_find_var(tag, "context"), xml_find_var(tag, "destination_number"));
2265
2266 switch_channel_set_originator_caller_profile(channel, caller_profile);
2267 }
2268
2269 if ((tag = switch_xml_child(tag2, "originatee")) && (tag = tag->child)) {
2270 caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2271 xml_find_var(tag, "username"),
2272 xml_find_var(tag, "dialplan"),
2273 xml_find_var(tag, "caller_id_name"),
2274 xml_find_var(tag, "caller_id_number"),
2275 xml_find_var(tag, "network_addr"),
2276 xml_find_var(tag, "ani"),
2277 xml_find_var(tag, "aniii"),
2278 xml_find_var(tag, "rdnis"),
2279 xml_find_var(tag, "source"),
2280 xml_find_var(tag, "context"), xml_find_var(tag, "destination_number"));
2281
2282 switch_channel_set_originatee_caller_profile(channel, caller_profile);
2283 }
2284
2285 }
2286
2287
2288 switch_channel_set_flag(channel, CF_RECOVERED)switch_channel_set_flag_value(channel, CF_RECOVERED, 1);
2289 }
2290
2291
2292 if (!channel || !switch_channel_get_caller_profile(channel)) {
2293 if (session) {
2294 switch_core_session_destroy(&session)switch_core_session_perform_destroy(&session, "src/switch_core_session.c"
, (const char *)__func__, 2294)
;
2295 }
2296 }
2297
2298
2299 return session;
2300}
2301
2302
2303
2304SWITCH_DECLARE(switch_core_session_t *)__attribute__((visibility("default"))) switch_core_session_t * switch_core_session_request_uuid(switch_endpoint_interface_t
2305 *endpoint_interface,
2306 switch_call_direction_t direction,
2307 switch_originate_flag_t originate_flags,
2308 switch_memory_pool_t **pool, const char *use_uuid)
2309{
2310 switch_memory_pool_t *usepool;
2311 switch_core_session_t *session;
2312 switch_uuid_t uuid;
2313 uint32_t count = 0;
2314 int32_t sps = 0;
2315
2316
2317 if (use_uuid && switch_core_hash_find(session_manager.session_table, use_uuid)) {
2318 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 2318, ((void*)0)
, SWITCH_LOG_CRIT, "Duplicate UUID!\n");
2319 return NULL((void*)0);
2320 }
2321
2322 if (direction == SWITCH_CALL_DIRECTION_INBOUND && !switch_core_ready_inbound()) {
2323 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 2323, ((void*)0)
, SWITCH_LOG_CRIT, "The system cannot create any inbound sessions at this time.\n");
2324 return NULL((void*)0);
2325 }
2326
2327 if (direction == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_core_ready_outbound()) {
2328 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 2328, ((void*)0)
, SWITCH_LOG_CRIT, "The system cannot create any outbound sessions at this time.\n");
2329 return NULL((void*)0);
2330 }
2331
2332 if (!switch_core_ready() || endpoint_interface == NULL((void*)0)) {
2333 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 2333, ((void*)0)
, SWITCH_LOG_CRIT, "The system cannot create any sessions at this time.\n");
2334 return NULL((void*)0);
2335 }
2336
2337 if (runtime.min_idle_time > 0 && runtime.profile_time < runtime.min_idle_time) {
2338 return NULL((void*)0);
2339 }
2340
2341 PROTECT_INTERFACE(endpoint_interface)if (endpoint_interface) {switch_mutex_lock(endpoint_interface
->reflock); switch_thread_rwlock_rdlock(endpoint_interface
->parent->rwlock); switch_thread_rwlock_rdlock(endpoint_interface
->rwlock); endpoint_interface->refs++; endpoint_interface
->parent->refs++; switch_mutex_unlock(endpoint_interface
->reflock);}
;
2342
2343 if (!(originate_flags & SOF_NO_LIMITS)) {
2344 switch_mutex_lock(runtime.throttle_mutex);
2345 count = session_manager.session_count;
2346 sps = --runtime.sps;
2347 switch_mutex_unlock(runtime.throttle_mutex);
2348
2349 if (sps <= 0) {
2350 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 2350, ((void*)0)
, SWITCH_LOG_CRIT, "Throttle Error! %d\n", session_manager.session_count);
2351 UNPROTECT_INTERFACE(endpoint_interface)if (endpoint_interface) {switch_mutex_lock(endpoint_interface
->reflock); switch_thread_rwlock_unlock(endpoint_interface
->rwlock); switch_thread_rwlock_unlock(endpoint_interface->
parent->rwlock); endpoint_interface->refs--; endpoint_interface
->parent->refs--; switch_mutex_unlock(endpoint_interface
->reflock);}
;
2352 return NULL((void*)0);
2353 }
2354
2355 if ((count + 1) > session_manager.session_limit) {
2356 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 2356, ((void*)0)
, SWITCH_LOG_CRIT, "Over Session Limit! %d\n", session_manager.session_limit);
2357 UNPROTECT_INTERFACE(endpoint_interface)if (endpoint_interface) {switch_mutex_lock(endpoint_interface
->reflock); switch_thread_rwlock_unlock(endpoint_interface
->rwlock); switch_thread_rwlock_unlock(endpoint_interface->
parent->rwlock); endpoint_interface->refs--; endpoint_interface
->parent->refs--; switch_mutex_unlock(endpoint_interface
->reflock);}
;
2358 return NULL((void*)0);
2359 }
2360 }
2361
2362
2363 if (pool && *pool) {
2364 usepool = *pool;
2365 *pool = NULL((void*)0);
2366 } else {
2367 switch_core_new_memory_pool(&usepool)switch_core_perform_new_memory_pool(&usepool, "src/switch_core_session.c"
, (const char *)__func__, 2367)
;
2368 }
2369
2370 session = switch_core_alloc(usepool, sizeof(*session))switch_core_perform_alloc(usepool, sizeof(*session), "src/switch_core_session.c"
, (const char *)__func__, 2370)
;
2371 session->pool = usepool;
2372
2373 switch_core_memory_pool_set_data(session->pool, "__session", session);
2374
2375 if (switch_channel_alloc(&session->channel, direction, session->pool) != SWITCH_STATUS_SUCCESS) {
2376 abort();
2377 }
2378
2379 switch_channel_init(session->channel, session, CS_NEW, 0);
2380
2381 if (direction == SWITCH_CALL_DIRECTION_OUTBOUND) {
2382 switch_channel_set_flag(session->channel, CF_OUTBOUND)switch_channel_set_flag_value(session->channel, CF_OUTBOUND
, 1)
;
2383 }
2384
2385 /* The session *IS* the pool you may not alter it because you have no idea how
2386 its all private it will be passed to the thread run function */
2387
2388 if (use_uuid) {
2389 switch_set_string(session->uuid_str, use_uuid)switch_copy_string(session->uuid_str, use_uuid, sizeof(session
->uuid_str))
;
2390 } else {
2391 switch_uuid_get(&uuid);
2392 switch_uuid_format(session->uuid_str, &uuid);
2393 }
2394
2395 switch_channel_set_variable(session->channel, "uuid", session->uuid_str)switch_channel_set_variable_var_check(session->channel, "uuid"
, session->uuid_str, SWITCH_TRUE)
;
2396 switch_channel_set_variable(session->channel, "call_uuid", session->uuid_str)switch_channel_set_variable_var_check(session->channel, "call_uuid"
, session->uuid_str, SWITCH_TRUE)
;
2397
2398 session->endpoint_interface = endpoint_interface;
2399 session->raw_write_frame.data = session->raw_write_buf;
2400 session->raw_write_frame.buflen = sizeof(session->raw_write_buf);
2401 session->raw_read_frame.data = session->raw_read_buf;
2402 session->raw_read_frame.buflen = sizeof(session->raw_read_buf);
2403
2404
2405 session->enc_write_frame.data = session->enc_write_buf;
2406 session->enc_write_frame.buflen = sizeof(session->enc_write_buf);
2407 session->enc_read_frame.data = session->enc_read_buf;
2408 session->enc_read_frame.buflen = sizeof(session->enc_read_buf);
2409
2410 switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED0x1, session->pool);
2411 switch_mutex_init(&session->resample_mutex, SWITCH_MUTEX_NESTED0x1, session->pool);
2412 switch_mutex_init(&session->codec_read_mutex, SWITCH_MUTEX_NESTED0x1, session->pool);
2413 switch_mutex_init(&session->codec_write_mutex, SWITCH_MUTEX_NESTED0x1, session->pool);
2414 switch_mutex_init(&session->frame_read_mutex, SWITCH_MUTEX_NESTED0x1, session->pool);
2415 switch_thread_rwlock_create(&session->bug_rwlock, session->pool);
2416 switch_thread_cond_create(&session->cond, session->pool);
2417 switch_thread_rwlock_create(&session->rwlock, session->pool);
2418 switch_thread_rwlock_create(&session->io_rwlock, session->pool);
2419 switch_queue_create(&session->message_queue, SWITCH_MESSAGE_QUEUE_LEN256, session->pool);
2420 switch_queue_create(&session->signal_data_queue, SWITCH_MESSAGE_QUEUE_LEN256, session->pool);
2421 switch_queue_create(&session->event_queue, SWITCH_EVENT_QUEUE_LEN256, session->pool);
2422 switch_queue_create(&session->private_event_queue, SWITCH_EVENT_QUEUE_LEN256, session->pool);
2423 switch_queue_create(&session->private_event_queue_pri, SWITCH_EVENT_QUEUE_LEN256, session->pool);
2424
2425 switch_mutex_lock(runtime.session_hash_mutex);
2426 switch_core_hash_insert(session_manager.session_table, session->uuid_str, session)switch_core_hash_insert_destructor(session_manager.session_table
, session->uuid_str, session, ((void*)0))
;
2427 session->id = session_manager.session_id++;
2428 session_manager.session_count++;
2429
2430 if (session_manager.session_count > (uint32_t)runtime.sessions_peak) {
2431 runtime.sessions_peak = session_manager.session_count;
2432 }
2433 if (session_manager.session_count > (uint32_t)runtime.sessions_peak_fivemin) {
2434 runtime.sessions_peak_fivemin = session_manager.session_count;
2435 }
2436
2437 switch_mutex_unlock(runtime.session_hash_mutex);
2438
2439 switch_channel_set_variable_printf(session->channel, "session_id", "%u", session->id);
2440
2441 return session;
2442}
2443
2444SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_session_count(void)
2445{
2446 return session_manager.session_count;
2447}
2448
2449SWITCH_DECLARE(switch_size_t)__attribute__((visibility("default"))) switch_size_t switch_core_session_get_id(switch_core_session_t *session)
2450{
2451 return session->id;
2452}
2453
2454SWITCH_DECLARE(switch_size_t)__attribute__((visibility("default"))) switch_size_t switch_core_session_id_dec(void)
2455{
2456 switch_mutex_lock(runtime.session_hash_mutex);
2457 session_manager.session_id--;
2458 switch_mutex_unlock(runtime.session_hash_mutex);
2459 return session_manager.session_id;
2460}
2461
2462SWITCH_DECLARE(switch_size_t)__attribute__((visibility("default"))) switch_size_t switch_core_session_id(void)
2463{
2464 return session_manager.session_id;
2465}
2466
2467
2468SWITCH_DECLARE(switch_core_session_t *)__attribute__((visibility("default"))) switch_core_session_t * switch_core_session_request_by_name(const char *endpoint_name,
2469 switch_call_direction_t direction, switch_memory_pool_t **pool)
2470{
2471 switch_endpoint_interface_t *endpoint_interface;
2472 switch_core_session_t *session;
2473
2474 if ((endpoint_interface = switch_loadable_module_get_endpoint_interface(endpoint_name)) == 0) {
2475 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 2475, ((void*)0)
, SWITCH_LOG_ERROR, "Could not locate channel type %s\n", endpoint_name);
2476 return NULL((void*)0);
2477 }
2478
2479 session = switch_core_session_request(endpoint_interface, direction, SOF_NONE, pool)switch_core_session_request_uuid(endpoint_interface, direction
, SOF_NONE, pool, ((void*)0))
;
2480
2481 UNPROTECT_INTERFACE(endpoint_interface)if (endpoint_interface) {switch_mutex_lock(endpoint_interface
->reflock); switch_thread_rwlock_unlock(endpoint_interface
->rwlock); switch_thread_rwlock_unlock(endpoint_interface->
parent->rwlock); endpoint_interface->refs--; endpoint_interface
->parent->refs--; switch_mutex_unlock(endpoint_interface
->reflock);}
;
2482
2483 return session;
2484}
2485
2486#ifndef SWITCH_PREFIX_DIR"/usr/local/freeswitch"
2487#define SWITCH_PREFIX_DIR"/usr/local/freeswitch" "."
2488#endif
2489
2490SWITCH_DECLARE(uint8_t)__attribute__((visibility("default"))) uint8_t switch_core_session_compare(switch_core_session_t *a, switch_core_session_t *b)
2491{
2492 switch_assert(a != NULL)((a != ((void*)0)) ? (void) (0) : __assert_fail ("a != ((void*)0)"
, "src/switch_core_session.c", 2492, __PRETTY_FUNCTION__))
;
2493 switch_assert(b != NULL)((b != ((void*)0)) ? (void) (0) : __assert_fail ("b != ((void*)0)"
, "src/switch_core_session.c", 2493, __PRETTY_FUNCTION__))
;
2494
2495 return (uint8_t) (a->endpoint_interface == b->endpoint_interface);
2496}
2497
2498SWITCH_DECLARE(uint8_t)__attribute__((visibility("default"))) uint8_t switch_core_session_check_interface(switch_core_session_t *session, const switch_endpoint_interface_t *endpoint_interface)
2499{
2500 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 2500, __PRETTY_FUNCTION__))
;
2501 switch_assert(endpoint_interface != NULL)((endpoint_interface != ((void*)0)) ? (void) (0) : __assert_fail
("endpoint_interface != ((void*)0)", "src/switch_core_session.c"
, 2501, __PRETTY_FUNCTION__))
;
2502
2503 return (uint8_t) (session->endpoint_interface == endpoint_interface);
2504}
2505
2506SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_core_session_get_uuid(switch_core_session_t *session)
2507{
2508 if (!session) return NULL((void*)0);
2509 return session->uuid_str;
2510}
2511
2512
2513SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_session_limit(uint32_t new_limit)
2514{
2515 if (new_limit) {
2516 session_manager.session_limit = new_limit;
2517 }
2518
2519 return session_manager.session_limit;
2520}
2521
2522SWITCH_DECLARE(double)__attribute__((visibility("default"))) double switch_core_min_idle_cpu(double new_limit)
2523{
2524 if (new_limit >= 0) {
2525 runtime.min_idle_time = new_limit;
2526 }
2527
2528 return runtime.min_idle_time;
2529}
2530
2531
2532SWITCH_DECLARE(double)__attribute__((visibility("default"))) double switch_core_idle_cpu(void)
2533{
2534 return runtime.profile_time;
2535}
2536
2537SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_sessions_per_second(uint32_t new_limit)
2538{
2539 if (new_limit) {
2540 runtime.sps_total = new_limit;
2541 }
2542
2543 return runtime.sps_total;
2544}
2545
2546void switch_core_session_init(switch_memory_pool_t *pool)
2547{
2548 memset(&session_manager, 0, sizeof(session_manager));
2549 session_manager.session_limit = 1000;
2550 session_manager.session_id = 1;
2551 session_manager.memory_pool = pool;
2552 switch_core_hash_init(&session_manager.session_table)switch_core_hash_init_case(&session_manager.session_table
, SWITCH_TRUE)
;
2553
2554 if (switch_test_flag((&runtime), SCF_SESSION_THREAD_POOL)(((&runtime))->flags & SCF_SESSION_THREAD_POOL)) {
2555 switch_threadattr_t *thd_attr;
2556
2557 switch_mutex_init(&session_manager.mutex, SWITCH_MUTEX_NESTED0x1, session_manager.memory_pool);
2558 switch_thread_cond_create(&session_manager.cond, session_manager.memory_pool);
2559 switch_mutex_init(&session_manager.cond_mutex, SWITCH_MUTEX_NESTED0x1, session_manager.memory_pool);
2560 switch_mutex_init(&session_manager.cond2_mutex, SWITCH_MUTEX_NESTED0x1, session_manager.memory_pool);
2561 switch_queue_create(&session_manager.thread_queue, 100000, session_manager.memory_pool);
2562 switch_threadattr_create(&thd_attr, session_manager.memory_pool);
2563 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
2564 session_manager.ready = 1;
2565 switch_thread_create(&session_manager.manager_thread, thd_attr, switch_core_session_thread_pool_manager, NULL((void*)0), session_manager.memory_pool);
2566 }
2567
2568}
2569
2570void switch_core_session_uninit(void)
2571{
2572 int sanity = 100;
2573 switch_status_t st = SWITCH_STATUS_FALSE;
2574
2575 session_manager.ready = 0;
2576 wake_queue();
2577
2578 while(session_manager.running && --sanity > 0) {
2579 switch_queue_interrupt_all(session_manager.thread_queue);
2580 switch_yield(100000)switch_sleep(100000);;
2581 }
2582
2583 switch_thread_join(&st, session_manager.manager_thread);
2584 switch_core_hash_destroy(&session_manager.session_table);
2585
2586}
2587
2588SWITCH_DECLARE(switch_app_log_t *)__attribute__((visibility("default"))) switch_app_log_t * switch_core_session_get_app_log(switch_core_session_t *session)
2589{
2590 return session->app_log;
2591}
2592
2593SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_get_app_flags(const char *app, int32_t *flags)
2594{
2595 switch_application_interface_t *application_interface;
2596 switch_status_t status = SWITCH_STATUS_FALSE;
2597
2598 switch_assert(flags)((flags) ? (void) (0) : __assert_fail ("flags", "src/switch_core_session.c"
, 2598, __PRETTY_FUNCTION__))
;
2599
2600 *flags = 0;
2601
2602 if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2603 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_session.c", (const char
*)__func__, 2603, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
2604 goto end;
2605 } else if (application_interface->flags) {
2606 *flags = application_interface->flags;
2607 status = SWITCH_STATUS_SUCCESS;
2608 }
2609
2610 UNPROTECT_INTERFACE(application_interface)if (application_interface) {switch_mutex_lock(application_interface
->reflock); switch_thread_rwlock_unlock(application_interface
->rwlock); switch_thread_rwlock_unlock(application_interface
->parent->rwlock); application_interface->refs--; application_interface
->parent->refs--; switch_mutex_unlock(application_interface
->reflock);}
;
2611
2612 end:
2613
2614 return status;
2615
2616}
2617
2618SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg)
2619{
2620 switch_event_t *execute_event;
2621 char *ap, *arp;
2622
2623 if (!arg && strstr(app, "::")) {
2624 ap = switch_core_session_strdup(session, app)switch_core_perform_session_strdup(session, app, "src/switch_core_session.c"
, (const char *)__func__, 2624)
;
2625 app = ap;
2626
2627 if ((arp = strstr(ap, "::"))) {
2628 *arp = '\0';
2629 arg = arp + 2;
2630 }
2631 }
2632
2633 if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND)switch_event_create_subclass_detailed("src/switch_core_session.c"
, (const char * )(const char *)__func__, 2633, &execute_event
, SWITCH_EVENT_COMMAND, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2634 switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute");
2635 switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", app);
2636
2637 if (arg) {
2638 switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", arg);
2639 }
2640
2641 if (!switch_channel_test_flag(session->channel, CF_PROXY_MODE)) {
2642 switch_channel_set_flag(session->channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA)switch_channel_set_flag_value(session->channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA
, 1)
;
2643 }
2644
2645 switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true");
2646 switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE);
2647
2648 return SWITCH_STATUS_SUCCESS;
2649 }
2650
2651 return SWITCH_STATUS_FALSE;
2652}
2653
2654SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_video_reset(switch_core_session_t *session)
2655{
2656 switch_channel_set_flag(session->channel, CF_VIDEO_ECHO)switch_channel_set_flag_value(session->channel, CF_VIDEO_ECHO
, 1)
;
2657 switch_channel_clear_flag(session->channel, CF_VIDEO_PASSIVE);
2658 switch_core_session_refresh_video(session);
2659}
2660
2661SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_execute_application_get_flags(switch_core_session_t *session, const char *app,
2662 const char *arg, int32_t *flags)
2663{
2664 switch_application_interface_t *application_interface;
2665 switch_status_t status = SWITCH_STATUS_SUCCESS;
2666
2667 if (switch_channel_down_nosig(session->channel)(switch_channel_get_state(session->channel) >= CS_HANGUP
)
) {
2668 char *p;
2669 if (!arg && (p = strstr(app, "::"))) {
2670 *p++ = '0';
2671 *p++ = '0';
2672 arg = p;
2673
2674 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2674, (const char*)(session)
, SWITCH_LOG_WARNING, "%s ASYNC CALL CONVERTED TO INLINE %s(%s)\n",
2675 switch_channel_get_name(session->channel), app, switch_str_nil(arg)(arg ? arg : ""));
2676 }
2677
2678 if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2679 return SWITCH_STATUS_FALSE;
2680 }
2681
2682 if (switch_test_flag(application_interface, SAF_ZOMBIE_EXEC)((application_interface)->flags & SAF_ZOMBIE_EXEC)) {
2683 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2683, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s ZOMBIE EXEC %s(%s)\n",
2684 switch_channel_get_name(session->channel), app, switch_str_nil(arg)(arg ? arg : ""));
2685 goto exec;
2686 }
2687
2688 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2688, (const char*)(session)
, SWITCH_LOG_DEBUG,
2689 "%s Channel is hungup and application '%s' does not have the zombie_exec flag.\n",
2690 switch_channel_get_name(session->channel), app);
2691
2692 switch_goto_status(SWITCH_STATUS_IGNORE, done)status = SWITCH_STATUS_IGNORE; goto done;
2693 }
2694
2695 if (!arg && strstr(app, "::")) {
2696 return switch_core_session_execute_application_async(session, app, arg);
2697 }
2698
2699 if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2700 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2700, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
2701 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(session->channel, "src/switch_core_session.c"
, (const char *)__func__, 2701, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
2702 switch_goto_status(SWITCH_STATUS_FALSE, done)status = SWITCH_STATUS_FALSE; goto done;
2703 }
2704
2705 if (!application_interface->application_function) {
2706 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2706, (const char*)(session)
, SWITCH_LOG_ERROR, "No Function for %s\n", app);
2707 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(session->channel, "src/switch_core_session.c"
, (const char *)__func__, 2707, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
2708 switch_goto_status(SWITCH_STATUS_FALSE, done)status = SWITCH_STATUS_FALSE; goto done;
2709 }
2710
2711 if (flags && application_interface->flags) {
2712 *flags = application_interface->flags;
2713 }
2714
2715 if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)((application_interface)->flags & SAF_SUPPORT_NOMEDIA) && (switch_channel_test_flag(session->channel, CF_VIDEO))) {
2716 switch_core_session_refresh_video(session);
2717 }
2718
2719 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)((application_interface)->flags & SAF_SUPPORT_NOMEDIA)) {
2720 switch_ivr_media(session->uuid_str, SMF_NONE);
2721 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2721, (const char*)(session)
, SWITCH_LOG_DEBUG, "Application %s Requires media on channel %s!\n",
2722 app, switch_channel_get_name(session->channel));
2723 } else if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)((application_interface)->flags & SAF_SUPPORT_NOMEDIA) && !switch_channel_media_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_TRUE
)
) {
2724 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
2725 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2725, (const char*)(session)
, SWITCH_LOG_DEBUG, "Application %s Requires media! pre_answering channel %s\n",
2726 app, switch_channel_get_name(session->channel));
2727 if (switch_channel_pre_answer(session->channel)switch_channel_perform_pre_answer(session->channel, "src/switch_core_session.c"
, (const char *)__func__, 2727)
!= SWITCH_STATUS_SUCCESS) {
2728 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2728, (const char*)(session)
, SWITCH_LOG_DEBUG, "Well, that didn't work very well did it? ...\n");
2729 switch_goto_status(SWITCH_STATUS_FALSE, done)status = SWITCH_STATUS_FALSE; goto done;
2730 }
2731 } else {
2732 uint32_t ready = 0, sanity = 2000;
2733
2734 do {
2735 sanity--;
2736 ready = switch_channel_media_up(session->channel)(switch_channel_test_flag(session->channel, CF_ANSWERED) ||
switch_channel_test_flag(session->channel, CF_EARLY_MEDIA
))
;
2737 switch_cond_next();
2738 } while(!ready && sanity);
2739
2740 if (!ready) {
2741 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2741, (const char*)(session)
, SWITCH_LOG_WARNING,
2742 "Cannot execute app '%s' media required on an outbound channel that does not have media established\n", app);
2743 switch_goto_status(SWITCH_STATUS_FALSE, done)status = SWITCH_STATUS_FALSE; goto done;
2744 }
2745 }
2746 }
2747
2748 exec:
2749
2750 switch_core_session_exec(session, application_interface, arg);
2751
2752 done:
2753
2754 UNPROTECT_INTERFACE(application_interface)if (application_interface) {switch_mutex_lock(application_interface
->reflock); switch_thread_rwlock_unlock(application_interface
->rwlock); switch_thread_rwlock_unlock(application_interface
->parent->rwlock); application_interface->refs--; application_interface
->parent->refs--; switch_mutex_unlock(application_interface
->reflock);}
;
2755
2756 return status;
2757}
2758
2759SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_exec(switch_core_session_t *session,
2760 const switch_application_interface_t *application_interface, const char *arg)
2761{
2762 switch_app_log_t *log, *lp;
2763 switch_event_t *event;
2764 const char *var;
2765 switch_channel_t *channel = switch_core_session_get_channel(session);
2766 char *expanded = NULL((void*)0);
2767 const char *app, *app_uuid_var;
2768 switch_core_session_message_t msg = { 0 };
2769 char delim = ',';
2770 int scope = 0;
2771 char uuid_str[SWITCH_UUID_FORMATTED_LENGTH256 + 1];
2772 char *app_uuid = uuid_str;
2773
2774 if ((app_uuid_var = switch_channel_get_variable(channel, "app_uuid")switch_channel_get_variable_dup(channel, "app_uuid", SWITCH_TRUE
, -1)
)) {
2775 app_uuid = (char *)app_uuid_var;
2776 switch_channel_set_variable(channel, "app_uuid", NULL)switch_channel_set_variable_var_check(channel, "app_uuid", ((
void*)0), SWITCH_TRUE)
;
2777 } else {
2778 switch_uuid_str(uuid_str, sizeof(uuid_str));
2779 }
2780
2781 switch_assert(application_interface)((application_interface) ? (void) (0) : __assert_fail ("application_interface"
, "src/switch_core_session.c", 2781, __PRETTY_FUNCTION__))
;
2782
2783 app = application_interface->interface_name;
2784
2785 if (arg) {
2786 expanded = switch_channel_expand_variables(session->channel, arg)switch_channel_expand_variables_check(session->channel, arg
, ((void*)0), ((void*)0), 0)
;
2787 }
2788
2789 if (expanded && *expanded == '%' && (*(expanded+1) == '[' || *(expanded+2) == '[')) {
2790 char *p, *dup;
2791 switch_event_t *ovars = NULL((void*)0);
2792
2793 p = expanded + 1;
2794
2795 if (*p != '[') {
2796 delim = *p;
2797 p++;
2798 }
2799
2800 dup = strdup(p)(__extension__ (__builtin_constant_p (p) && ((size_t)
(const void *)((p) + 1) - (size_t)(const void *)(p) == 1) ? (
((const char *) (p))[0] == '\0' ? (char *) calloc ((size_t) 1
, (size_t) 1) : ({ size_t __len = strlen (p) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, p, __len); __retval; })) : __strdup
(p)))
;
2801
2802 if (expanded != arg) {
2803 switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);};
2804 }
2805
2806 switch_event_create_brackets(dup, '[', ']', delim, &ovars, &expanded, SWITCH_TRUE);
2807 free(dup);
2808
2809 switch_channel_set_scope_variables(session->channel, &ovars);
2810 scope = 1;
2811 }
2812
2813
2814 if ( switch_core_test_flag(SCF_DIALPLAN_TIMESTAMPS) ) {
2815 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2815, (const char*)(session)
, SWITCH_LOG_DEBUG, "EXECUTE %s %s(%s)\n",
2816 switch_channel_get_name(session->channel), app, switch_str_nil(expanded)(expanded ? expanded : ""));
2817 } else {
2818 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session)SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_core_session.c", (const
char *)__func__, 2818, switch_core_session_get_uuid((session
))
, SWITCH_LOG_DEBUG, "EXECUTE %s %s(%s)\n",
2819 switch_channel_get_name(session->channel), app, switch_str_nil(expanded)(expanded ? expanded : ""));
2820 }
2821
2822 if ((var = switch_channel_get_variable(session->channel, "verbose_presence")switch_channel_get_variable_dup(session->channel, "verbose_presence"
, SWITCH_TRUE, -1)
) && switch_true(var)) {
2823 char *myarg = NULL((void*)0);
2824 if (expanded) {
2825 myarg = switch_mprintf("%s(%s)", app, expanded);
2826 } else if (!zstr(arg)_zstr(arg)) {
2827 myarg = switch_mprintf("%s(%s)", app, arg);
2828 } else {
2829 myarg = switch_mprintf("%s", app);
2830 }
2831 if (myarg) {
2832 switch_channel_presence(session->channel, "unknown", myarg, NULL)switch_channel_perform_presence(session->channel, "unknown"
, myarg, ((void*)0), "src/switch_core_session.c", (const char
*)__func__, 2832)
;
2833 switch_safe_free(myarg)if (myarg) {free(myarg);myarg=((void*)0);};
2834 }
2835 }
2836
2837 if (!(var = switch_channel_get_variable(session->channel, SWITCH_DISABLE_APP_LOG_VARIABLE)switch_channel_get_variable_dup(session->channel, "disable_app_log"
, SWITCH_TRUE, -1)
) || (!(switch_true(var)))) {
2838 log = switch_core_session_alloc(session, sizeof(*log))switch_core_perform_session_alloc(session, sizeof(*log), "src/switch_core_session.c"
, (const char *)__func__, 2838)
;
2839
2840 log->app = switch_core_session_strdup(session, application_interface->interface_name)switch_core_perform_session_strdup(session, application_interface
->interface_name, "src/switch_core_session.c", (const char
*)__func__, 2840)
;
2841 if (expanded) {
2842 log->arg = switch_core_session_strdup(session, expanded)switch_core_perform_session_strdup(session, expanded, "src/switch_core_session.c"
, (const char *)__func__, 2842)
;
2843 }
2844
2845 log->stamp = switch_time_now();
2846
2847 for (lp = session->app_log; lp && lp->next; lp = lp->next);
2848
2849 if (lp) {
2850 lp->next = log;
2851 } else {
2852 session->app_log = log;
2853 }
2854 }
2855
2856 switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_VARIABLE, application_interface->interface_name)switch_channel_set_variable_var_check(channel, "current_application"
, application_interface->interface_name, SWITCH_TRUE)
;
2857 switch_channel_set_variable_var_check(channel, SWITCH_CURRENT_APPLICATION_DATA_VARIABLE"current_application_data", expanded, SWITCH_FALSE);
2858 switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "current_application_response"
, ((void*)0), SWITCH_TRUE)
;
2859
2860 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE)switch_event_create_subclass_detailed("src/switch_core_session.c"
, (const char * )(const char *)__func__, 2860, &event, SWITCH_EVENT_CHANNEL_EXECUTE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2861 switch_channel_event_set_data(session->channel, event);
2862 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", application_interface->interface_name);
2863 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", expanded);
2864 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID", app_uuid);
2865 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_session.c", (const
char * )(const char *)__func__, 2865, &event, ((void*)0)
)
;
2866 }
2867
2868 switch_channel_clear_flag(session->channel, CF_BREAK);
2869
2870 switch_assert(application_interface->application_function)((application_interface->application_function) ? (void) (0
) : __assert_fail ("application_interface->application_function"
, "src/switch_core_session.c", 2870, __PRETTY_FUNCTION__))
;
2871
2872 switch_channel_set_variable(session->channel, SWITCH_CURRENT_APPLICATION_VARIABLE, application_interface->interface_name)switch_channel_set_variable_var_check(session->channel, "current_application"
, application_interface->interface_name, SWITCH_TRUE)
;
2873
2874 msg.from = __FILE__"src/switch_core_session.c";
2875 msg.message_id = SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC;
2876 msg.string_array_arg[0] = application_interface->interface_name;
2877 msg.string_array_arg[1] = expanded;
2878 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_core_session.c", (const char *)__func__, 2878)
;
2879
2880 application_interface->application_function(session, expanded);
2881
2882 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE)switch_event_create_subclass_detailed("src/switch_core_session.c"
, (const char * )(const char *)__func__, 2882, &event, SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2883 const char *resp = switch_channel_get_variable(session->channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE)switch_channel_get_variable_dup(session->channel, "current_application_response"
, SWITCH_TRUE, -1)
;
2884 switch_channel_event_set_data(session->channel, event);
2885 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", application_interface->interface_name);
2886 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", expanded);
2887 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Response", resp ? resp : "_none_");
2888 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID", app_uuid);
2889 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_session.c", (const
char * )(const char *)__func__, 2889, &event, ((void*)0)
)
;
2890 }
2891
2892 msg.message_id = SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC_COMPLETE;
2893 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_core_session.c", (const char *)__func__, 2893)
;
2894
2895 if (expanded != arg) {
2896 switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);};
2897 }
2898
2899 if (scope) {
2900 switch_channel_set_scope_variables(session->channel, NULL((void*)0));
2901 }
2902
2903 return SWITCH_STATUS_SUCCESS;
2904}
2905
2906SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_execute_exten(switch_core_session_t *session, const char *exten, const char *dialplan,
2907 const char *context)
2908{
2909 char *dp[25];
2910 char *dpstr;
2911 int argc, x, count = 0;
2912 switch_caller_profile_t *profile, *new_profile, *pp = NULL((void*)0);
2913 switch_channel_t *channel = switch_core_session_get_channel(session);
2914 switch_dialplan_interface_t *dialplan_interface = NULL((void*)0);
2915 switch_caller_extension_t *extension = NULL((void*)0);
2916 switch_status_t status = SWITCH_STATUS_SUCCESS;
2917
2918 if (!(profile = switch_channel_get_caller_profile(channel))) {
2919 return SWITCH_STATUS_FALSE;
2920 }
2921
2922 if (session->stack_count > SWITCH_MAX_STACKS16) {
2923 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2923, (const char*)(session)
, SWITCH_LOG_ERROR, "Error %s too many stacked extensions\n",
2924 switch_channel_get_name(session->channel));
2925 return SWITCH_STATUS_FALSE;
2926 }
2927
2928 session->stack_count++;
2929
2930 new_profile = switch_caller_profile_clone(session, profile);
2931 new_profile->destination_number = switch_core_strdup(new_profile->pool, exten)switch_core_perform_strdup(new_profile->pool, exten, "src/switch_core_session.c"
, (const char *)__func__, 2931)
;
2932 new_profile->times = (switch_channel_timetable_t *) switch_core_session_alloc(session, sizeof(*new_profile->times))switch_core_perform_session_alloc(session, sizeof(*new_profile
->times), "src/switch_core_session.c", (const char *)__func__
, 2932)
;
2933 *new_profile->times = *profile->times;
2934
2935
2936 if (!zstr(dialplan)_zstr(dialplan)) {
2937 new_profile->dialplan = switch_core_strdup(new_profile->pool, dialplan)switch_core_perform_strdup(new_profile->pool, dialplan, "src/switch_core_session.c"
, (const char *)__func__, 2937)
;
2938 }
2939
2940 if (!zstr(context)_zstr(context)) {
2941 new_profile->context = switch_core_strdup(new_profile->pool, context)switch_core_perform_strdup(new_profile->pool, context, "src/switch_core_session.c"
, (const char *)__func__, 2941)
;
2942 }
2943
2944 dpstr = switch_core_session_strdup(session, new_profile->dialplan)switch_core_perform_session_strdup(session, new_profile->dialplan
, "src/switch_core_session.c", (const char *)__func__, 2944)
;
2945
2946 switch_channel_set_hunt_caller_profile(channel, new_profile);
2947 argc = switch_separate_string(dpstr, ',', dp, (sizeof(dp) / sizeof(dp[0])));
2948 for (x = 0; x < argc; x++) {
2949 char *dpname = dp[x];
2950 char *dparg = NULL((void*)0);
2951
2952 if (dpname) {
2953 if ((dparg = strchr(dpname, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(dpname) && (':') == '\0' ? (char *) __rawmemchr (dpname
, ':') : __builtin_strchr (dpname, ':')))
)) {
2954 *dparg++ = '\0';
2955 }
2956 } else {
2957 continue;
2958 }
2959
2960 if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) {
2961 continue;
2962 }
2963
2964 count++;
2965
2966 extension = dialplan_interface->hunt_function(session, dparg, new_profile);
2967 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);}
;
2968
2969 if (extension) {
2970 break;
2971 }
2972 }
2973
2974 if (!extension) {
2975 status = SWITCH_STATUS_FALSE;
2976 goto done;
2977 }
2978
2979 new_profile->caller_extension = extension;
2980
2981 if (profile->caller_extension) {
2982 for (pp = profile->caller_extension->children; pp && pp->next; pp = pp->next);
2983
2984 if (pp) {
2985 pp->next = new_profile;
2986 } else {
2987 profile->caller_extension->children = new_profile;
2988 }
2989 }
2990
2991 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && extension->current_application) {
2992 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_session.c", (const
char *)__func__, 2992, (const char*)(session)
, SWITCH_LOG_NOTICE, "Execute %s(%s)\n",
2993 extension->current_application->application_name, switch_str_nil(extension->current_application->application_data)(extension->current_application->application_data ? extension
->current_application->application_data : "")
);
2994
2995 if (switch_core_session_execute_application(session,switch_core_session_execute_application_get_flags(session, extension
->current_application->application_name, extension->
current_application->application_data, ((void*)0))
2996 extension->current_application->application_name,switch_core_session_execute_application_get_flags(session, extension
->current_application->application_name, extension->
current_application->application_data, ((void*)0))
2997 extension->current_application->application_data)switch_core_session_execute_application_get_flags(session, extension
->current_application->application_name, extension->
current_application->application_data, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
2998 goto done;
2999 }
3000
3001 extension->current_application = extension->current_application->next;
3002 }
3003
3004 done:
3005 switch_channel_set_hunt_caller_profile(channel, NULL((void*)0));
3006
3007 session->stack_count--;
3008 return status;
3009}
3010
3011SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_set_loglevel(switch_core_session_t *session, switch_log_level_t loglevel)
3012{
3013 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 3013, __PRETTY_FUNCTION__))
;
3014 session->loglevel = loglevel;
3015 return SWITCH_STATUS_SUCCESS;
3016}
3017
3018SWITCH_DECLARE(switch_log_level_t)__attribute__((visibility("default"))) switch_log_level_t switch_core_session_get_loglevel(switch_core_session_t *session)
3019{
3020 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_core_session.c", 3020, __PRETTY_FUNCTION__))
;
3021 return session->loglevel;
3022}
3023
3024SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_refresh_video(switch_core_session_t *session)
3025{
3026 switch_channel_t *channel = switch_core_session_get_channel(session);
3027
3028 if (switch_channel_test_flag(channel, CF_VIDEO)) {
3029 switch_core_session_message_t msg = { 0 };
3030 msg.from = __FILE__"src/switch_core_session.c";
3031 msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
3032 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_core_session.c", (const char *)__func__, 3032)
;
3033 return SWITCH_STATUS_SUCCESS;
3034 }
3035
3036 return SWITCH_STATUS_FALSE;
3037}
3038
3039SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_debug_pool(switch_stream_handle_t *stream)
3040{
3041 stream->write_function(stream, "Thread pool: running:%d busy:%d popping:%d\n",
3042 session_manager.running, session_manager.busy, session_manager.popping);
3043}
3044
3045/* For Emacs:
3046 * Local Variables:
3047 * mode:c
3048 * indent-tabs-mode:t
3049 * tab-width:4
3050 * c-basic-offset:4
3051 * End:
3052 * For VIM:
3053 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3054 */