Bug Summary

File:src/switch_core_media_bug.c
Location:line 397, column 3
Description:Value stored to 'do_write' is never read

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 *
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
38static 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
58SWITCH_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
63SWITCH_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
68SWITCH_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
73SWITCH_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
81SWITCH_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
86SWITCH_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
91SWITCH_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
96SWITCH_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
101SWITCH_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
106SWITCH_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
111SWITCH_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
116SWITCH_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
121SWITCH_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
126SWITCH_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
131SWITCH_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
152SWITCH_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
171SWITCH_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
178SWITCH_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);
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);
Value stored to 'do_write' is never read
398 switch_mutex_unlock(bug->write_mutex);
399 }
400
401 return SWITCH_STATUS_SUCCESS;
402}
403
404#define MAX_BUG_BUFFER1024 * 512 1024 * 512
405SWITCH_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
567SWITCH_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
583SWITCH_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
625SWITCH_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
668SWITCH_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
693SWITCH_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
711SWITCH_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
733SWITCH_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
760SWITCH_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
796SWITCH_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
819SWITCH_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
873SWITCH_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
915SWITCH_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 */