File: | src/switch_core_media_bug.c |
Location: | line 391, column 3 |
Description: | Value stored to 'do_read' is never read |
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 | * |
30 | * |
31 | * switch_core_media_bug.c -- Main Core Library (Media Bugs) |
32 | * |
33 | */ |
34 | |
35 | #include "switch.h" |
36 | #include "private/switch_core_pvt.h" |
37 | |
38 | static void switch_core_media_bug_destroy(switch_media_bug_t *bug) |
39 | { |
40 | switch_event_t *event = NULL((void*)0); |
41 | |
42 | if (bug->raw_read_buffer) { |
43 | switch_buffer_destroy(&bug->raw_read_buffer); |
44 | } |
45 | |
46 | if (bug->raw_write_buffer) { |
47 | switch_buffer_destroy(&bug->raw_write_buffer); |
48 | } |
49 | |
50 | if (switch_event_create(&event, SWITCH_EVENT_MEDIA_BUG_STOP)switch_event_create_subclass_detailed("src/switch_core_media_bug.c" , (const char * )(const char *)__func__, 50, &event, SWITCH_EVENT_MEDIA_BUG_STOP , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
51 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bug->function); |
52 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bug->target); |
53 | if (bug->session) switch_channel_event_set_data(bug->session->channel, event); |
54 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_media_bug.c", (const char * )(const char *)__func__, 54, &event, ((void*)0)); |
55 | } |
56 | } |
57 | |
58 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_bug_pause(switch_core_session_t *session) |
59 | { |
60 | switch_channel_set_flag(session->channel, CF_PAUSE_BUGS)switch_channel_set_flag_value(session->channel, CF_PAUSE_BUGS , 1); |
61 | } |
62 | |
63 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_bug_resume(switch_core_session_t *session) |
64 | { |
65 | switch_channel_clear_flag(session->channel, CF_PAUSE_BUGS); |
66 | } |
67 | |
68 | SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_media_bug_test_flag(switch_media_bug_t *bug, uint32_t flag) |
69 | { |
70 | return switch_test_flag(bug, flag)((bug)->flags & flag); |
71 | } |
72 | |
73 | SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_media_bug_set_flag(switch_media_bug_t *bug, uint32_t flag) |
74 | { |
75 | if ((flag & SMBF_PRUNE)) { |
76 | switch_clear_flag(bug, SMBF_LOCK)(bug)->flags &= ~(SMBF_LOCK); |
77 | } |
78 | return switch_set_flag(bug, flag)(bug)->flags |= (flag); |
79 | } |
80 | |
81 | SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_media_bug_clear_flag(switch_media_bug_t *bug, uint32_t flag) |
82 | { |
83 | return switch_clear_flag(bug, flag)(bug)->flags &= ~(flag); |
84 | } |
85 | |
86 | SWITCH_DECLARE(switch_core_session_t *)__attribute__((visibility("default"))) switch_core_session_t * switch_core_media_bug_get_session(switch_media_bug_t *bug) |
87 | { |
88 | return bug->session; |
89 | } |
90 | |
91 | SWITCH_DECLARE(switch_frame_t *)__attribute__((visibility("default"))) switch_frame_t * switch_core_media_bug_get_write_replace_frame(switch_media_bug_t *bug) |
92 | { |
93 | return bug->write_replace_frame_in; |
94 | } |
95 | |
96 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_bug_set_write_replace_frame(switch_media_bug_t *bug, switch_frame_t *frame) |
97 | { |
98 | bug->write_replace_frame_out = frame; |
99 | } |
100 | |
101 | SWITCH_DECLARE(switch_frame_t *)__attribute__((visibility("default"))) switch_frame_t * switch_core_media_bug_get_read_replace_frame(switch_media_bug_t *bug) |
102 | { |
103 | return bug->read_replace_frame_in; |
104 | } |
105 | |
106 | SWITCH_DECLARE(switch_frame_t *)__attribute__((visibility("default"))) switch_frame_t * switch_core_media_bug_get_native_read_frame(switch_media_bug_t *bug) |
107 | { |
108 | return bug->native_read_frame; |
109 | } |
110 | |
111 | SWITCH_DECLARE(switch_frame_t *)__attribute__((visibility("default"))) switch_frame_t * switch_core_media_bug_get_native_write_frame(switch_media_bug_t *bug) |
112 | { |
113 | return bug->native_write_frame; |
114 | } |
115 | |
116 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_bug_set_read_replace_frame(switch_media_bug_t *bug, switch_frame_t *frame) |
117 | { |
118 | bug->read_replace_frame_out = frame; |
119 | } |
120 | |
121 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_bug_set_read_demux_frame(switch_media_bug_t *bug, switch_frame_t *frame) |
122 | { |
123 | bug->read_demux_frame = frame; |
124 | } |
125 | |
126 | SWITCH_DECLARE(void *)__attribute__((visibility("default"))) void * switch_core_media_bug_get_user_data(switch_media_bug_t *bug) |
127 | { |
128 | return bug->user_data; |
129 | } |
130 | |
131 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_bug_flush(switch_media_bug_t *bug) |
132 | { |
133 | |
134 | bug->record_pre_buffer_count = 0; |
135 | |
136 | if (bug->raw_read_buffer) { |
137 | switch_mutex_lock(bug->read_mutex); |
138 | switch_buffer_zero(bug->raw_read_buffer); |
139 | switch_mutex_unlock(bug->read_mutex); |
140 | } |
141 | |
142 | if (bug->raw_write_buffer) { |
143 | switch_mutex_lock(bug->write_mutex); |
144 | switch_buffer_zero(bug->raw_write_buffer); |
145 | switch_mutex_unlock(bug->write_mutex); |
146 | } |
147 | |
148 | bug->record_frame_size = 0; |
149 | bug->record_pre_buffer_count = 0; |
150 | } |
151 | |
152 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_bug_inuse(switch_media_bug_t *bug, switch_size_t *readp, switch_size_t *writep) |
153 | { |
154 | if (switch_test_flag(bug, SMBF_READ_STREAM)((bug)->flags & SMBF_READ_STREAM)) { |
155 | switch_mutex_lock(bug->read_mutex); |
156 | *readp = bug->raw_read_buffer ? switch_buffer_inuse(bug->raw_read_buffer) : 0; |
157 | switch_mutex_unlock(bug->read_mutex); |
158 | } else { |
159 | *readp = 0; |
160 | } |
161 | |
162 | if (switch_test_flag(bug, SMBF_WRITE_STREAM)((bug)->flags & SMBF_WRITE_STREAM)) { |
163 | switch_mutex_lock(bug->write_mutex); |
164 | *writep = bug->raw_write_buffer ? switch_buffer_inuse(bug->raw_write_buffer) : 0; |
165 | switch_mutex_unlock(bug->write_mutex); |
166 | } else { |
167 | *writep = 0; |
168 | } |
169 | } |
170 | |
171 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_set_pre_buffer_framecount(switch_media_bug_t *bug, uint32_t framecount) |
172 | { |
173 | bug->record_pre_buffer_max = framecount; |
174 | |
175 | return SWITCH_STATUS_SUCCESS; |
176 | } |
177 | |
178 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_read(switch_media_bug_t *bug, switch_frame_t *frame, switch_bool_t fill) |
179 | { |
180 | switch_size_t bytes = 0, datalen = 0; |
181 | int16_t *dp, *fp; |
182 | uint32_t x; |
183 | size_t rlen = 0; |
184 | size_t wlen = 0; |
185 | uint32_t blen; |
186 | switch_codec_implementation_t read_impl = { 0 }; |
187 | int16_t *tp; |
188 | switch_size_t do_read = 0, do_write = 0, has_read = 0, has_write = 0, fill_read = 0, fill_write = 0; |
189 | |
190 | switch_core_session_get_read_impl(bug->session, &read_impl); |
191 | |
192 | bytes = read_impl.decoded_bytes_per_packet; |
193 | |
194 | if (frame->buflen < bytes) { |
195 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug))SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 195, (const char*)(switch_core_media_bug_get_session (bug)), SWITCH_LOG_ERROR, "%s frame buffer too small!\n", |
196 | switch_channel_get_name(bug->session->channel)); |
197 | return SWITCH_STATUS_FALSE; |
198 | } |
199 | |
200 | if ((!bug->raw_read_buffer && (!bug->raw_write_buffer || !switch_test_flag(bug, SMBF_WRITE_STREAM)((bug)->flags & SMBF_WRITE_STREAM)))) { |
201 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug))SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 201, (const char*)(switch_core_media_bug_get_session (bug)), SWITCH_LOG_ERROR, |
202 | "%s Buffer Error (raw_read_buffer=%p, raw_write_buffer=%p, read=%s, write=%s)\n", |
203 | switch_channel_get_name(bug->session->channel), |
204 | (void *)bug->raw_read_buffer, (void *)bug->raw_write_buffer, |
205 | switch_test_flag(bug, SMBF_READ_STREAM)((bug)->flags & SMBF_READ_STREAM) ? "yes" : "no", |
206 | switch_test_flag(bug, SMBF_WRITE_STREAM)((bug)->flags & SMBF_WRITE_STREAM) ? "yes" : "no"); |
207 | return SWITCH_STATUS_FALSE; |
208 | } |
209 | |
210 | frame->flags = 0; |
211 | frame->datalen = 0; |
212 | |
213 | if (switch_test_flag(bug, SMBF_READ_STREAM)((bug)->flags & SMBF_READ_STREAM)) { |
214 | has_read = 1; |
215 | switch_mutex_lock(bug->read_mutex); |
216 | do_read = switch_buffer_inuse(bug->raw_read_buffer); |
217 | switch_mutex_unlock(bug->read_mutex); |
218 | } |
219 | |
220 | if (switch_test_flag(bug, SMBF_WRITE_STREAM)((bug)->flags & SMBF_WRITE_STREAM)) { |
221 | has_write = 1; |
222 | switch_mutex_lock(bug->write_mutex); |
223 | do_write = switch_buffer_inuse(bug->raw_write_buffer); |
224 | switch_mutex_unlock(bug->write_mutex); |
225 | } |
226 | |
227 | |
228 | if (bug->record_frame_size && bug->record_pre_buffer_max && (do_read || do_write) && bug->record_pre_buffer_count < bug->record_pre_buffer_max) { |
229 | bug->record_pre_buffer_count++; |
230 | return SWITCH_STATUS_FALSE; |
231 | } else { |
232 | uint32_t frame_size; |
233 | switch_codec_implementation_t read_impl = { 0 }; |
234 | |
235 | switch_core_session_get_read_impl(bug->session, &read_impl); |
236 | frame_size = read_impl.decoded_bytes_per_packet; |
237 | bug->record_frame_size = frame_size; |
238 | } |
239 | |
240 | if (bug->record_frame_size && do_write > do_read && do_write > (bug->record_frame_size * 2)) { |
241 | switch_mutex_lock(bug->write_mutex); |
242 | switch_buffer_toss(bug->raw_write_buffer, bug->record_frame_size); |
243 | do_write = switch_buffer_inuse(bug->raw_write_buffer); |
244 | switch_mutex_unlock(bug->write_mutex); |
245 | } |
246 | |
247 | |
248 | |
249 | if ((has_read && !do_read)) { |
250 | fill_read = 1; |
251 | } |
252 | |
253 | if ((has_write && !do_write)) { |
254 | fill_write = 1; |
255 | } |
256 | |
257 | |
258 | if (bug->record_frame_size) { |
259 | if ((do_read && do_read < bug->record_frame_size) || (do_write && do_write < bug->record_frame_size)) { |
260 | return SWITCH_STATUS_FALSE; |
261 | } |
262 | |
263 | if (do_read && do_read > bug->record_frame_size) { |
264 | do_read = bug->record_frame_size; |
265 | } |
266 | |
267 | if (do_write && do_write > bug->record_frame_size) { |
268 | do_write = bug->record_frame_size; |
269 | } |
270 | } |
271 | |
272 | if ((fill_read && fill_write) || (fill && (fill_read || fill_write))) { |
273 | return SWITCH_STATUS_FALSE; |
274 | } |
275 | |
276 | if (do_read && do_read > SWITCH_RECOMMENDED_BUFFER_SIZE8192) { |
277 | do_read = 1280; |
278 | } |
279 | |
280 | if (do_write && do_write > SWITCH_RECOMMENDED_BUFFER_SIZE8192) { |
281 | do_write = 1280; |
282 | } |
283 | |
284 | if (do_read) { |
285 | switch_mutex_lock(bug->read_mutex); |
286 | frame->datalen = (uint32_t) switch_buffer_read(bug->raw_read_buffer, frame->data, do_read); |
287 | if (frame->datalen != do_read) { |
288 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug))SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 288, (const char*)(switch_core_media_bug_get_session (bug)), SWITCH_LOG_ERROR, "Framing Error Reading!\n"); |
289 | switch_core_media_bug_flush(bug); |
290 | switch_mutex_unlock(bug->read_mutex); |
291 | return SWITCH_STATUS_FALSE; |
292 | } |
293 | switch_mutex_unlock(bug->read_mutex); |
294 | } else if (fill_read) { |
295 | frame->datalen = (uint32_t)bytes; |
296 | memset(frame->data, 255, frame->datalen); |
297 | } |
298 | |
299 | if (do_write) { |
300 | switch_assert(bug->raw_write_buffer)((bug->raw_write_buffer) ? (void) (0) : __assert_fail ("bug->raw_write_buffer" , "src/switch_core_media_bug.c", 300, __PRETTY_FUNCTION__)); |
301 | switch_mutex_lock(bug->write_mutex); |
302 | datalen = (uint32_t) switch_buffer_read(bug->raw_write_buffer, bug->data, do_write); |
303 | if (datalen != do_write) { |
304 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug))SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 304, (const char*)(switch_core_media_bug_get_session (bug)), SWITCH_LOG_ERROR, "Framing Error Writing!\n"); |
305 | switch_core_media_bug_flush(bug); |
306 | switch_mutex_unlock(bug->write_mutex); |
307 | return SWITCH_STATUS_FALSE; |
308 | } |
309 | switch_mutex_unlock(bug->write_mutex); |
310 | } else if (fill_write) { |
311 | datalen = bytes; |
312 | memset(bug->data, 255, datalen); |
313 | } |
314 | |
315 | tp = bug->tmp; |
316 | dp = (int16_t *) bug->data; |
317 | fp = (int16_t *) frame->data; |
318 | rlen = frame->datalen / 2; |
319 | wlen = datalen / 2; |
320 | blen = (uint32_t)(bytes / 2); |
321 | |
322 | if (switch_test_flag(bug, SMBF_STEREO)((bug)->flags & SMBF_STEREO)) { |
323 | int16_t *left, *right; |
324 | size_t left_len, right_len; |
325 | if (switch_test_flag(bug, SMBF_STEREO_SWAP)((bug)->flags & SMBF_STEREO_SWAP)) { |
326 | left = dp; /* write stream */ |
327 | left_len = wlen; |
328 | right = fp; /* read stream */ |
329 | right_len = rlen; |
330 | } else { |
331 | left = fp; /* read stream */ |
332 | left_len = rlen; |
333 | right = dp; /* write stream */ |
334 | right_len = wlen; |
335 | } |
336 | for (x = 0; x < blen; x++) { |
337 | if (x < left_len) { |
338 | *(tp++) = *(left + x); |
339 | } else { |
340 | *(tp++) = 0; |
341 | } |
342 | if (x < right_len) { |
343 | *(tp++) = *(right + x); |
344 | } else { |
345 | *(tp++) = 0; |
346 | } |
347 | } |
348 | memcpy(frame->data, bug->tmp, bytes * 2); |
349 | } else { |
350 | for (x = 0; x < blen; x++) { |
351 | int32_t w = 0, r = 0, z = 0; |
352 | |
353 | if (x < rlen) { |
354 | r = (int32_t) * (fp + x); |
355 | } |
356 | |
357 | if (x < wlen) { |
358 | w = (int32_t) * (dp + x); |
359 | } |
360 | |
361 | z = w + r; |
362 | |
363 | if (z > SWITCH_SMAX32767 || z < SWITCH_SMIN-32768) { |
364 | if (r) z += (r/2); |
365 | if (w) z += (w/2); |
366 | } |
367 | |
368 | switch_normalize_to_16bit(z)if (z > 32767) z = 32767; else if (z < -32768) z = -32768 ;; |
369 | |
370 | *(fp + x) = (int16_t) z; |
371 | } |
372 | } |
373 | |
374 | frame->datalen = (uint32_t)bytes; |
375 | frame->samples = (uint32_t)(bytes / sizeof(int16_t)); |
376 | frame->rate = read_impl.actual_samples_per_second; |
377 | frame->codec = NULL((void*)0); |
378 | |
379 | if (switch_test_flag(bug, SMBF_STEREO)((bug)->flags & SMBF_STEREO)) { |
380 | frame->datalen *= 2; |
381 | frame->channels = 2; |
382 | } else { |
383 | frame->channels = 1; |
384 | } |
385 | |
386 | memcpy(bug->session->recur_buffer, frame->data, frame->datalen); |
387 | bug->session->recur_buffer_len = frame->datalen; |
388 | |
389 | if (has_read) { |
390 | switch_mutex_lock(bug->read_mutex); |
391 | do_read = switch_buffer_inuse(bug->raw_read_buffer); |
Value stored to 'do_read' is never read | |
392 | switch_mutex_unlock(bug->read_mutex); |
393 | } |
394 | |
395 | if (has_write) { |
396 | switch_mutex_lock(bug->write_mutex); |
397 | do_write = switch_buffer_inuse(bug->raw_write_buffer); |
398 | switch_mutex_unlock(bug->write_mutex); |
399 | } |
400 | |
401 | return SWITCH_STATUS_SUCCESS; |
402 | } |
403 | |
404 | #define MAX_BUG_BUFFER1024 * 512 1024 * 512 |
405 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_add(switch_core_session_t *session, |
406 | const char *function, |
407 | const char *target, |
408 | switch_media_bug_callback_t callback, |
409 | void *user_data, time_t stop_time, |
410 | switch_media_bug_flag_t flags, |
411 | switch_media_bug_t **new_bug) |
412 | { |
413 | switch_media_bug_t *bug, *bp; |
414 | switch_size_t bytes; |
415 | switch_event_t *event; |
416 | int tap_only = 1, punt = 0; |
417 | |
418 | const char *p; |
419 | |
420 | if (!zstr(function)_zstr(function)) { |
421 | if ((flags & SMBF_ONE_ONLY)) { |
422 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
423 | for (bp = session->bugs; bp; bp = bp->next) { |
424 | if (!zstr(bp->function)_zstr(bp->function) && !strcasecmp(function, bp->function)) { |
425 | punt = 1; |
426 | break; |
427 | } |
428 | } |
429 | switch_thread_rwlock_unlock(session->bug_rwlock); |
430 | } |
431 | } |
432 | |
433 | if (punt) { |
434 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 434, (const char*)(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n"); |
435 | return SWITCH_STATUS_GENERR; |
436 | } |
437 | |
438 | |
439 | if (!switch_channel_media_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_TRUE )) { |
440 | if (switch_channel_pre_answer(session->channel)switch_channel_perform_pre_answer(session->channel, "src/switch_core_media_bug.c" , (const char *)__func__, 440) != SWITCH_STATUS_SUCCESS) { |
441 | return SWITCH_STATUS_FALSE; |
442 | } |
443 | } |
444 | |
445 | |
446 | |
447 | *new_bug = NULL((void*)0); |
448 | |
449 | |
450 | if ((p = switch_channel_get_variable(session->channel, "media_bug_answer_req")switch_channel_get_variable_dup(session->channel, "media_bug_answer_req" , SWITCH_TRUE, -1)) && switch_true(p)) { |
451 | flags |= SMBF_ANSWER_REQ; |
452 | } |
453 | #if 0 |
454 | if (flags & SMBF_WRITE_REPLACE) { |
455 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
456 | for (bp = session->bugs; bp; bp = bp->next) { |
457 | if (switch_test_flag(bp, SMBF_WRITE_REPLACE)((bp)->flags & SMBF_WRITE_REPLACE)) { |
458 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 458, (const char*)(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n"); |
459 | switch_thread_rwlock_unlock(session->bug_rwlock); |
460 | return SWITCH_STATUS_GENERR; |
461 | } |
462 | } |
463 | switch_thread_rwlock_unlock(session->bug_rwlock); |
464 | } |
465 | |
466 | if (flags & SMBF_READ_REPLACE) { |
467 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
468 | for (bp = session->bugs; bp; bp = bp->next) { |
469 | if (switch_test_flag(bp, SMBF_READ_REPLACE)((bp)->flags & SMBF_READ_REPLACE)) { |
470 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 470, (const char*)(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n"); |
471 | switch_thread_rwlock_unlock(session->bug_rwlock); |
472 | return SWITCH_STATUS_GENERR; |
473 | } |
474 | } |
475 | switch_thread_rwlock_unlock(session->bug_rwlock); |
476 | } |
477 | #endif |
478 | |
479 | if (!(bug = switch_core_session_alloc(session, sizeof(*bug))switch_core_perform_session_alloc(session, sizeof(*bug), "src/switch_core_media_bug.c" , (const char *)__func__, 479))) { |
480 | return SWITCH_STATUS_MEMERR; |
481 | } |
482 | |
483 | bug->callback = callback; |
484 | bug->user_data = user_data; |
485 | bug->session = session; |
486 | bug->flags = flags; |
487 | bug->function = "N/A"; |
488 | bug->target = "N/A"; |
489 | |
490 | switch_core_session_get_read_impl(session, &bug->read_impl); |
491 | switch_core_session_get_write_impl(session, &bug->write_impl); |
492 | |
493 | if (function) { |
494 | bug->function = switch_core_session_strdup(session, function)switch_core_perform_session_strdup(session, function, "src/switch_core_media_bug.c" , (const char *)__func__, 494); |
495 | } |
496 | |
497 | if (target) { |
498 | bug->target = switch_core_session_strdup(session, target)switch_core_perform_session_strdup(session, target, "src/switch_core_media_bug.c" , (const char *)__func__, 498); |
499 | } |
500 | |
501 | bug->stop_time = stop_time; |
502 | bytes = bug->read_impl.decoded_bytes_per_packet; |
503 | |
504 | if (!bug->flags) { |
505 | bug->flags = (SMBF_READ_STREAM | SMBF_WRITE_STREAM); |
506 | } |
507 | |
508 | if (switch_test_flag(bug, SMBF_READ_STREAM)((bug)->flags & SMBF_READ_STREAM) || switch_test_flag(bug, SMBF_READ_PING)((bug)->flags & SMBF_READ_PING)) { |
509 | switch_buffer_create_dynamic(&bug->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES25, bytes * SWITCH_BUFFER_START_FRAMES50, MAX_BUG_BUFFER1024 * 512); |
510 | switch_mutex_init(&bug->read_mutex, SWITCH_MUTEX_NESTED0x1, session->pool); |
511 | } |
512 | |
513 | bytes = bug->write_impl.decoded_bytes_per_packet; |
514 | |
515 | if (switch_test_flag(bug, SMBF_WRITE_STREAM)((bug)->flags & SMBF_WRITE_STREAM)) { |
516 | switch_buffer_create_dynamic(&bug->raw_write_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES25, bytes * SWITCH_BUFFER_START_FRAMES50, MAX_BUG_BUFFER1024 * 512); |
517 | switch_mutex_init(&bug->write_mutex, SWITCH_MUTEX_NESTED0x1, session->pool); |
518 | } |
519 | |
520 | if ((bug->flags & SMBF_THREAD_LOCK)) { |
521 | bug->thread_id = switch_thread_self(); |
522 | } |
523 | |
524 | if (bug->callback) { |
525 | switch_bool_t result = bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_INIT); |
526 | if (result == SWITCH_FALSE) { |
527 | switch_core_media_bug_destroy(bug); |
528 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 528, (const char*)(session), SWITCH_LOG_ERROR, "Error attaching BUG to %s\n", |
529 | switch_channel_get_name(session->channel)); |
530 | return SWITCH_STATUS_GENERR; |
531 | } |
532 | } |
533 | |
534 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 534, (const char*)(session), SWITCH_LOG_DEBUG, "Attaching BUG to %s\n", switch_channel_get_name(session->channel)); |
535 | bug->ready = 1; |
536 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
537 | bug->next = session->bugs; |
538 | session->bugs = bug; |
539 | |
540 | for(bp = session->bugs; bp; bp = bp->next) { |
541 | if (bp->ready && !switch_test_flag(bp, SMBF_TAP_NATIVE_READ)((bp)->flags & SMBF_TAP_NATIVE_READ) && !switch_test_flag(bp, SMBF_TAP_NATIVE_WRITE)((bp)->flags & SMBF_TAP_NATIVE_WRITE)) { |
542 | tap_only = 0; |
543 | } |
544 | } |
545 | |
546 | switch_thread_rwlock_unlock(session->bug_rwlock); |
547 | *new_bug = bug; |
548 | |
549 | |
550 | if (tap_only) { |
551 | switch_set_flag(session, SSF_MEDIA_BUG_TAP_ONLY)(session)->flags |= (SSF_MEDIA_BUG_TAP_ONLY); |
552 | } else { |
553 | switch_clear_flag(session, SSF_MEDIA_BUG_TAP_ONLY)(session)->flags &= ~(SSF_MEDIA_BUG_TAP_ONLY); |
554 | } |
555 | |
556 | if (switch_event_create(&event, SWITCH_EVENT_MEDIA_BUG_START)switch_event_create_subclass_detailed("src/switch_core_media_bug.c" , (const char * )(const char *)__func__, 556, &event, SWITCH_EVENT_MEDIA_BUG_START , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
557 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bug->function); |
558 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bug->target); |
559 | switch_channel_event_set_data(session->channel, event); |
560 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_media_bug.c", (const char * )(const char *)__func__, 560, &event, ((void*)0)); |
561 | } |
562 | |
563 | return SWITCH_STATUS_SUCCESS; |
564 | } |
565 | |
566 | |
567 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_flush_all(switch_core_session_t *session) |
568 | { |
569 | switch_media_bug_t *bp; |
570 | |
571 | if (session->bugs) { |
572 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
573 | for (bp = session->bugs; bp; bp = bp->next) { |
574 | switch_core_media_bug_flush(bp); |
575 | } |
576 | switch_thread_rwlock_unlock(session->bug_rwlock); |
577 | return SWITCH_STATUS_SUCCESS; |
578 | } |
579 | |
580 | return SWITCH_STATUS_FALSE; |
581 | } |
582 | |
583 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_transfer_recordings(switch_core_session_t *orig_session, switch_core_session_t *new_session) |
584 | { |
585 | switch_media_bug_t *bp; |
586 | char *list[100] = { 0 }; |
587 | int stop_times[100] = { 0 }; |
588 | int i = 0, x = 0; |
589 | |
590 | if (orig_session->bugs) { |
591 | switch_channel_t *new_channel = switch_core_session_get_channel(new_session); |
592 | const char *save = switch_channel_get_variable(new_channel, "record_append")switch_channel_get_variable_dup(new_channel, "record_append", SWITCH_TRUE, -1); |
593 | |
594 | switch_thread_rwlock_wrlock(orig_session->bug_rwlock); |
595 | |
596 | switch_channel_set_variable(new_channel, "record_append", "true")switch_channel_set_variable_var_check(new_channel, "record_append" , "true", SWITCH_TRUE); |
597 | |
598 | for (bp = orig_session->bugs; bp; bp = bp->next) { |
599 | if (!strcmp(bp->function, "session_record")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (bp->function) && __builtin_constant_p ("session_record" ) && (__s1_len = __builtin_strlen (bp->function), __s2_len = __builtin_strlen ("session_record"), (!((size_t)(const void *)((bp->function) + 1) - (size_t)(const void *)(bp->function ) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("session_record") + 1) - (size_t)(const void *)("session_record" ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (bp->function , "session_record") : (__builtin_constant_p (bp->function) && ((size_t)(const void *)((bp->function) + 1) - ( size_t)(const void *)(bp->function) == 1) && (__s1_len = __builtin_strlen (bp->function), __s1_len < 4) ? (__builtin_constant_p ("session_record") && ((size_t)(const void *)(("session_record" ) + 1) - (size_t)(const void *)("session_record") == 1) ? __builtin_strcmp (bp->function, "session_record") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("session_record"); int __result = (((const unsigned char *) (const char *) (bp->function))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (bp->function))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (bp->function))[2] - __s2 [2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (bp->function))[ 3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("session_record" ) && ((size_t)(const void *)(("session_record") + 1) - (size_t)(const void *)("session_record") == 1) && (__s2_len = __builtin_strlen ("session_record"), __s2_len < 4) ? (__builtin_constant_p (bp->function) && ((size_t)(const void *)((bp-> function) + 1) - (size_t)(const void *)(bp->function) == 1 ) ? __builtin_strcmp (bp->function, "session_record") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (bp->function); int __result = ((( const unsigned char *) (const char *) ("session_record"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("session_record" ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("session_record" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("session_record" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (bp-> function, "session_record")))); })) { |
600 | list[x] = switch_core_session_strdup(new_session, bp->target)switch_core_perform_session_strdup(new_session, bp->target , "src/switch_core_media_bug.c", (const char *)__func__, 600); |
601 | if (bp->stop_time > 0) { |
602 | stop_times[x] = (int)(bp->stop_time - switch_epoch_time_now(NULL((void*)0))); |
603 | } |
604 | x++; |
605 | } |
606 | } |
607 | |
608 | switch_thread_rwlock_unlock(orig_session->bug_rwlock); |
609 | |
610 | for(i = 0; i < x; i++) { |
611 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(orig_session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 611, (const char*)(orig_session), SWITCH_LOG_DEBUG, "Transfering %s from %s to %s\n", list[i], |
612 | switch_core_session_get_name(orig_session)switch_channel_get_name(switch_core_session_get_channel(orig_session )), switch_core_session_get_name(new_session)switch_channel_get_name(switch_core_session_get_channel(new_session ))); |
613 | switch_ivr_stop_record_session(orig_session, list[i]); |
614 | switch_ivr_record_session(new_session, list[i], stop_times[i], NULL((void*)0)); |
615 | } |
616 | |
617 | switch_channel_set_variable(new_channel, "record_append", save)switch_channel_set_variable_var_check(new_channel, "record_append" , save, SWITCH_TRUE); |
618 | |
619 | } |
620 | |
621 | return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; |
622 | } |
623 | |
624 | |
625 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_transfer_callback(switch_core_session_t *orig_session, switch_core_session_t *new_session, |
626 | switch_media_bug_callback_t callback, void * (*user_data_dup_func) (switch_core_session_t *, void *)) |
627 | { |
628 | switch_media_bug_t *new_bug = NULL((void*)0), *cur = NULL((void*)0), *bp = NULL((void*)0), *last = NULL((void*)0); |
629 | int total = 0; |
630 | |
631 | switch_thread_rwlock_wrlock(orig_session->bug_rwlock); |
632 | bp = orig_session->bugs; |
633 | while (bp) { |
634 | cur = bp; |
635 | bp = bp->next; |
636 | |
637 | if (cur->callback == callback) { |
638 | if (last) { |
639 | last->next = cur->next; |
640 | } else { |
641 | orig_session->bugs = cur->next; |
642 | } |
643 | |
644 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(orig_session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 644, (const char*)(orig_session), SWITCH_LOG_DEBUG, "Transfering %s from %s to %s\n", cur->target, |
645 | switch_core_session_get_name(orig_session)switch_channel_get_name(switch_core_session_get_channel(orig_session )), switch_core_session_get_name(new_session)switch_channel_get_name(switch_core_session_get_channel(new_session ))); |
646 | |
647 | switch_core_media_bug_add(new_session, cur->function, cur->target, cur->callback, |
648 | user_data_dup_func(new_session, cur->user_data), |
649 | cur->stop_time, cur->flags, &new_bug); |
650 | switch_core_media_bug_destroy(cur); |
651 | total++; |
652 | } else { |
653 | last = cur; |
654 | } |
655 | } |
656 | |
657 | if (!orig_session->bugs && switch_core_codec_ready(&orig_session->bug_codec)) { |
658 | switch_core_codec_destroy(&orig_session->bug_codec); |
659 | } |
660 | |
661 | switch_thread_rwlock_unlock(orig_session->bug_rwlock); |
662 | |
663 | |
664 | return total ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; |
665 | } |
666 | |
667 | |
668 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_pop(switch_core_session_t *orig_session, const char *function, switch_media_bug_t **pop) |
669 | { |
670 | switch_media_bug_t *bp; |
671 | |
672 | if (orig_session->bugs) { |
673 | switch_thread_rwlock_wrlock(orig_session->bug_rwlock); |
674 | for (bp = orig_session->bugs; bp; bp = bp->next) { |
675 | if (!strcmp(bp->function, function)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (bp->function) && __builtin_constant_p (function) && (__s1_len = __builtin_strlen (bp->function), __s2_len = __builtin_strlen (function), (!((size_t)(const void *)((bp ->function) + 1) - (size_t)(const void *)(bp->function) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((function) + 1) - (size_t)(const void *)(function) == 1) || __s2_len >= 4)) ? __builtin_strcmp (bp->function, function ) : (__builtin_constant_p (bp->function) && ((size_t )(const void *)((bp->function) + 1) - (size_t)(const void * )(bp->function) == 1) && (__s1_len = __builtin_strlen (bp->function), __s1_len < 4) ? (__builtin_constant_p ( function) && ((size_t)(const void *)((function) + 1) - (size_t)(const void *)(function) == 1) ? __builtin_strcmp (bp ->function, function) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (function); int __result = (((const unsigned char *) (const char *) (bp-> function))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( bp->function))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (bp->function))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (bp->function))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (function) && ((size_t )(const void *)((function) + 1) - (size_t)(const void *)(function ) == 1) && (__s2_len = __builtin_strlen (function), __s2_len < 4) ? (__builtin_constant_p (bp->function) && ((size_t)(const void *)((bp->function) + 1) - (size_t)(const void *)(bp->function) == 1) ? __builtin_strcmp (bp->function , function) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (bp->function); int __result = (((const unsigned char *) (const char *) (function ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (function ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (function ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (function ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (bp-> function, function)))); })) { |
676 | switch_set_flag(bp, SMBF_LOCK)(bp)->flags |= (SMBF_LOCK); |
677 | break; |
678 | } |
679 | } |
680 | switch_thread_rwlock_unlock(orig_session->bug_rwlock); |
681 | |
682 | if (bp) { |
683 | *pop = bp; |
684 | return SWITCH_STATUS_SUCCESS; |
685 | } else { |
686 | *pop = NULL((void*)0); |
687 | } |
688 | } |
689 | |
690 | return SWITCH_STATUS_FALSE; |
691 | } |
692 | |
693 | SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_media_bug_count(switch_core_session_t *orig_session, const char *function) |
694 | { |
695 | switch_media_bug_t *bp; |
696 | uint32_t x = 0; |
697 | |
698 | if (orig_session->bugs) { |
699 | switch_thread_rwlock_rdlock(orig_session->bug_rwlock); |
700 | for (bp = orig_session->bugs; bp; bp = bp->next) { |
701 | if (!switch_test_flag(bp, SMBF_PRUNE)((bp)->flags & SMBF_PRUNE) && !switch_test_flag(bp, SMBF_LOCK)((bp)->flags & SMBF_LOCK) && !strcmp(bp->function, function)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (bp->function) && __builtin_constant_p (function) && (__s1_len = __builtin_strlen (bp->function), __s2_len = __builtin_strlen (function), (!((size_t)(const void *)((bp ->function) + 1) - (size_t)(const void *)(bp->function) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((function) + 1) - (size_t)(const void *)(function) == 1) || __s2_len >= 4)) ? __builtin_strcmp (bp->function, function ) : (__builtin_constant_p (bp->function) && ((size_t )(const void *)((bp->function) + 1) - (size_t)(const void * )(bp->function) == 1) && (__s1_len = __builtin_strlen (bp->function), __s1_len < 4) ? (__builtin_constant_p ( function) && ((size_t)(const void *)((function) + 1) - (size_t)(const void *)(function) == 1) ? __builtin_strcmp (bp ->function, function) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (function); int __result = (((const unsigned char *) (const char *) (bp-> function))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( bp->function))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (bp->function))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (bp->function))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (function) && ((size_t )(const void *)((function) + 1) - (size_t)(const void *)(function ) == 1) && (__s2_len = __builtin_strlen (function), __s2_len < 4) ? (__builtin_constant_p (bp->function) && ((size_t)(const void *)((bp->function) + 1) - (size_t)(const void *)(bp->function) == 1) ? __builtin_strcmp (bp->function , function) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (bp->function); int __result = (((const unsigned char *) (const char *) (function ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (function ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (function ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (function ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (bp-> function, function)))); })) { |
702 | x++; |
703 | } |
704 | } |
705 | switch_thread_rwlock_unlock(orig_session->bug_rwlock); |
706 | } |
707 | |
708 | return x; |
709 | } |
710 | |
711 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_exec_all(switch_core_session_t *orig_session, |
712 | const char *function, switch_media_bug_exec_cb_t cb, void *user_data) |
713 | { |
714 | switch_media_bug_t *bp; |
715 | int x = 0; |
716 | |
717 | switch_assert(cb)((cb) ? (void) (0) : __assert_fail ("cb", "src/switch_core_media_bug.c" , 717, __PRETTY_FUNCTION__)); |
718 | |
719 | if (orig_session->bugs) { |
720 | switch_thread_rwlock_wrlock(orig_session->bug_rwlock); |
721 | for (bp = orig_session->bugs; bp; bp = bp->next) { |
722 | if (!switch_test_flag(bp, SMBF_PRUNE)((bp)->flags & SMBF_PRUNE) && !switch_test_flag(bp, SMBF_LOCK)((bp)->flags & SMBF_LOCK) && !strcmp(bp->function, function)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (bp->function) && __builtin_constant_p (function) && (__s1_len = __builtin_strlen (bp->function), __s2_len = __builtin_strlen (function), (!((size_t)(const void *)((bp ->function) + 1) - (size_t)(const void *)(bp->function) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((function) + 1) - (size_t)(const void *)(function) == 1) || __s2_len >= 4)) ? __builtin_strcmp (bp->function, function ) : (__builtin_constant_p (bp->function) && ((size_t )(const void *)((bp->function) + 1) - (size_t)(const void * )(bp->function) == 1) && (__s1_len = __builtin_strlen (bp->function), __s1_len < 4) ? (__builtin_constant_p ( function) && ((size_t)(const void *)((function) + 1) - (size_t)(const void *)(function) == 1) ? __builtin_strcmp (bp ->function, function) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (function); int __result = (((const unsigned char *) (const char *) (bp-> function))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( bp->function))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (bp->function))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (bp->function))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (function) && ((size_t )(const void *)((function) + 1) - (size_t)(const void *)(function ) == 1) && (__s2_len = __builtin_strlen (function), __s2_len < 4) ? (__builtin_constant_p (bp->function) && ((size_t)(const void *)((bp->function) + 1) - (size_t)(const void *)(bp->function) == 1) ? __builtin_strcmp (bp->function , function) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (bp->function); int __result = (((const unsigned char *) (const char *) (function ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (function ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (function ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (function ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (bp-> function, function)))); })) { |
723 | cb(bp, user_data); |
724 | x++; |
725 | } |
726 | } |
727 | switch_thread_rwlock_unlock(orig_session->bug_rwlock); |
728 | } |
729 | |
730 | return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; |
731 | } |
732 | |
733 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_enumerate(switch_core_session_t *session, switch_stream_handle_t *stream) |
734 | { |
735 | switch_media_bug_t *bp; |
736 | |
737 | stream->write_function(stream, "<media-bugs>\n"); |
738 | |
739 | if (session->bugs) { |
740 | switch_thread_rwlock_rdlock(session->bug_rwlock); |
741 | for (bp = session->bugs; bp; bp = bp->next) { |
742 | int thread_locked = (bp->thread_id && bp->thread_id == switch_thread_self()); |
743 | stream->write_function(stream, |
744 | " <media-bug>\n" |
745 | " <function>%s</function>\n" |
746 | " <target>%s</target>\n" |
747 | " <thread-locked>%d</thread-locked>\n" |
748 | " </media-bug>\n", |
749 | bp->function, bp->target, thread_locked); |
750 | |
751 | } |
752 | switch_thread_rwlock_unlock(session->bug_rwlock); |
753 | } |
754 | |
755 | stream->write_function(stream, "</media-bugs>\n"); |
756 | |
757 | return SWITCH_STATUS_SUCCESS; |
758 | } |
759 | |
760 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_remove_all_function(switch_core_session_t *session, const char *function) |
761 | { |
762 | switch_media_bug_t *bp; |
763 | switch_status_t status = SWITCH_STATUS_FALSE; |
764 | |
765 | if (session->bugs) { |
766 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
767 | for (bp = session->bugs; bp; bp = bp->next) { |
768 | if ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK)((bp)->flags & SMBF_LOCK)) { |
769 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 769, (const char*)(session), SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n"); |
770 | continue; |
771 | } |
772 | |
773 | if (!zstr(function)_zstr(function) && strcmp(bp->function, function)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (bp->function) && __builtin_constant_p (function) && (__s1_len = __builtin_strlen (bp->function), __s2_len = __builtin_strlen (function), (!((size_t)(const void *)((bp ->function) + 1) - (size_t)(const void *)(bp->function) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((function) + 1) - (size_t)(const void *)(function) == 1) || __s2_len >= 4)) ? __builtin_strcmp (bp->function, function ) : (__builtin_constant_p (bp->function) && ((size_t )(const void *)((bp->function) + 1) - (size_t)(const void * )(bp->function) == 1) && (__s1_len = __builtin_strlen (bp->function), __s1_len < 4) ? (__builtin_constant_p ( function) && ((size_t)(const void *)((function) + 1) - (size_t)(const void *)(function) == 1) ? __builtin_strcmp (bp ->function, function) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (function); int __result = (((const unsigned char *) (const char *) (bp-> function))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( bp->function))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (bp->function))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (bp->function))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (function) && ((size_t )(const void *)((function) + 1) - (size_t)(const void *)(function ) == 1) && (__s2_len = __builtin_strlen (function), __s2_len < 4) ? (__builtin_constant_p (bp->function) && ((size_t)(const void *)((bp->function) + 1) - (size_t)(const void *)(bp->function) == 1) ? __builtin_strcmp (bp->function , function) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (bp->function); int __result = (((const unsigned char *) (const char *) (function ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (function ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (function ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (function ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (bp-> function, function)))); })) { |
774 | continue; |
775 | } |
776 | |
777 | |
778 | if (bp->callback) { |
779 | bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE); |
780 | } |
781 | switch_core_media_bug_destroy(bp); |
782 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 782, (const char*)(session), SWITCH_LOG_DEBUG, "Removing BUG from %s\n", switch_channel_get_name(session->channel)); |
783 | } |
784 | session->bugs = NULL((void*)0); |
785 | switch_thread_rwlock_unlock(session->bug_rwlock); |
786 | status = SWITCH_STATUS_SUCCESS; |
787 | } |
788 | |
789 | if (switch_core_codec_ready(&session->bug_codec)) { |
790 | switch_core_codec_destroy(&session->bug_codec); |
791 | } |
792 | |
793 | return status; |
794 | } |
795 | |
796 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_close(switch_media_bug_t **bug) |
797 | { |
798 | switch_media_bug_t *bp = *bug; |
799 | if (bp) { |
800 | if ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK)((bp)->flags & SMBF_LOCK)) { |
801 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(*bug))SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 801, (const char*)(switch_core_media_bug_get_session (*bug)), SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n"); |
802 | return SWITCH_STATUS_FALSE; |
803 | } |
804 | |
805 | if (bp->callback) { |
806 | bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE); |
807 | bp->ready = 0; |
808 | } |
809 | switch_core_media_bug_destroy(bp); |
810 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(*bug))SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media_bug.c", (const char *)__func__, 810, (const char*)(switch_core_media_bug_get_session (*bug)), SWITCH_LOG_DEBUG, "Removing BUG from %s\n", |
811 | switch_channel_get_name(bp->session->channel)); |
812 | *bug = NULL((void*)0); |
813 | return SWITCH_STATUS_SUCCESS; |
814 | } |
815 | |
816 | return SWITCH_STATUS_FALSE; |
817 | } |
818 | |
819 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_remove(switch_core_session_t *session, switch_media_bug_t **bug) |
820 | { |
821 | switch_media_bug_t *bp = NULL((void*)0), *bp2 = NULL((void*)0), *last = NULL((void*)0); |
822 | switch_status_t status = SWITCH_STATUS_FALSE; |
823 | int tap_only = 0; |
824 | |
825 | if (switch_core_media_bug_test_flag(*bug, SMBF_LOCK)) { |
826 | return status; |
827 | } |
828 | |
829 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
830 | if (session->bugs) { |
831 | for (bp = session->bugs; bp; bp = bp->next) { |
832 | if ((!bp->thread_id || bp->thread_id == switch_thread_self()) && bp->ready && bp == *bug) { |
833 | if (last) { |
834 | last->next = bp->next; |
835 | } else { |
836 | session->bugs = bp->next; |
837 | } |
838 | break; |
839 | } |
840 | |
841 | last = bp; |
842 | } |
843 | } |
844 | |
845 | if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) { |
846 | switch_core_codec_destroy(&session->bug_codec); |
847 | } |
848 | |
849 | if (session->bugs) { |
850 | for(bp2 = session->bugs; bp2; bp2 = bp2->next) { |
851 | if (bp2->ready && !switch_test_flag(bp2, SMBF_TAP_NATIVE_READ)((bp2)->flags & SMBF_TAP_NATIVE_READ) && !switch_test_flag(bp2, SMBF_TAP_NATIVE_WRITE)((bp2)->flags & SMBF_TAP_NATIVE_WRITE)) { |
852 | tap_only = 0; |
853 | } |
854 | } |
855 | } |
856 | |
857 | if (tap_only) { |
858 | switch_set_flag(session, SSF_MEDIA_BUG_TAP_ONLY)(session)->flags |= (SSF_MEDIA_BUG_TAP_ONLY); |
859 | } else { |
860 | switch_clear_flag(session, SSF_MEDIA_BUG_TAP_ONLY)(session)->flags &= ~(SSF_MEDIA_BUG_TAP_ONLY); |
861 | } |
862 | |
863 | switch_thread_rwlock_unlock(session->bug_rwlock); |
864 | |
865 | if (bp) { |
866 | status = switch_core_media_bug_close(&bp); |
867 | } |
868 | |
869 | return status; |
870 | } |
871 | |
872 | |
873 | SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_core_media_bug_prune(switch_core_session_t *session) |
874 | { |
875 | switch_media_bug_t *bp = NULL((void*)0), *last = NULL((void*)0); |
876 | int ttl = 0; |
877 | |
878 | |
879 | top: |
880 | |
881 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
882 | if (session->bugs) { |
883 | for (bp = session->bugs; bp; bp = bp->next) { |
884 | if (switch_core_media_bug_test_flag(bp, SMBF_PRUNE)) { |
885 | if (last) { |
886 | last->next = bp->next; |
887 | } else { |
888 | session->bugs = bp->next; |
889 | } |
890 | break; |
891 | } |
892 | |
893 | last = bp; |
894 | } |
895 | } |
896 | |
897 | if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) { |
898 | switch_core_codec_destroy(&session->bug_codec); |
899 | } |
900 | |
901 | switch_thread_rwlock_unlock(session->bug_rwlock); |
902 | |
903 | if (bp) { |
904 | switch_clear_flag(bp, SMBF_LOCK)(bp)->flags &= ~(SMBF_LOCK); |
905 | bp->thread_id = 0; |
906 | switch_core_media_bug_close(&bp); |
907 | ttl++; |
908 | goto top; |
909 | } |
910 | |
911 | return ttl; |
912 | } |
913 | |
914 | |
915 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_bug_remove_callback(switch_core_session_t *session, switch_media_bug_callback_t callback) |
916 | { |
917 | switch_media_bug_t *cur = NULL((void*)0), *bp = NULL((void*)0), *last = NULL((void*)0); |
918 | int total = 0; |
919 | |
920 | switch_thread_rwlock_wrlock(session->bug_rwlock); |
921 | if (session->bugs) { |
922 | bp = session->bugs; |
923 | while (bp) { |
924 | cur = bp; |
925 | bp = bp->next; |
926 | |
927 | if ((!cur->thread_id || cur->thread_id == switch_thread_self()) && cur->ready && cur->callback == callback) { |
928 | if (last) { |
929 | last->next = cur->next; |
930 | } else { |
931 | session->bugs = cur->next; |
932 | } |
933 | if (switch_core_media_bug_close(&cur) == SWITCH_STATUS_SUCCESS) { |
934 | total++; |
935 | } |
936 | } else { |
937 | last = cur; |
938 | } |
939 | } |
940 | } |
941 | |
942 | if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) { |
943 | switch_core_codec_destroy(&session->bug_codec); |
944 | } |
945 | |
946 | switch_thread_rwlock_unlock(session->bug_rwlock); |
947 | |
948 | |
949 | return total ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; |
950 | } |
951 | |
952 | /* For Emacs: |
953 | * Local Variables: |
954 | * mode:c |
955 | * indent-tabs-mode:t |
956 | * tab-width:4 |
957 | * c-basic-offset:4 |
958 | * End: |
959 | * For VIM: |
960 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: |
961 | */ |