File: | src/mod/applications/mod_conference/mod_conference.c |
Location: | line 4665, column 5 |
Description: | Value stored to 'file_data_len' 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 | * Neal Horman <neal at wanlink dot com> |
28 | * Bret McDanel <trixter at 0xdecafbad dot com> |
29 | * Dale Thatcher <freeswitch at dalethatcher dot com> |
30 | * Chris Danielson <chris at maxpowersoft dot com> |
31 | * Rupa Schomaker <rupa@rupa.com> |
32 | * David Weekly <david@weekly.org> |
33 | * Joao Mesquita <jmesquita@gmail.com> |
34 | * Raymond Chandler <intralanman@freeswitch.org> |
35 | * Seven Du <dujinfang@gmail.com> |
36 | * Emmanuel Schmidbauer <e.schmidbauer@gmail.com> |
37 | * |
38 | * mod_conference.c -- Software Conference Bridge |
39 | * |
40 | */ |
41 | #include <switch.h> |
42 | |
43 | #ifdef OPENAL_POSITIONING |
44 | #define AL_ALEXT_PROTOTYPES |
45 | #include <AL/al.h> |
46 | #include <AL/alc.h> |
47 | #include <AL/alext.h> |
48 | #endif |
49 | |
50 | #define DEFAULT_AGC_LEVEL1100 1100 |
51 | #define CONFERENCE_UUID_VARIABLE"conference_uuid" "conference_uuid" |
52 | |
53 | SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load)switch_status_t mod_conference_load (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool); |
54 | SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_conference_shutdown)switch_status_t mod_conference_shutdown (void); |
55 | SWITCH_MODULE_DEFINITION(mod_conference, mod_conference_load, mod_conference_shutdown, NULL)static const char modname[] = "mod_conference" ; __attribute__ ((visibility("default"))) switch_loadable_module_function_table_t mod_conference_module_interface = { 5, mod_conference_load, mod_conference_shutdown , ((void*)0), SMODF_NONE }; |
56 | |
57 | typedef enum { |
58 | CONF_SILENT_REQ = (1 << 0), |
59 | CONF_SILENT_DONE = (1 << 1) |
60 | } conf_app_flag_t; |
61 | |
62 | static const char global_app_name[] = "conference"; |
63 | static char *global_cf_name = "conference.conf"; |
64 | static char *cf_pin_url_param_name = "X-ConfPin="; |
65 | static char *api_syntax; |
66 | static int EC = 0; |
67 | |
68 | /* Size to allocate for audio buffers */ |
69 | #define CONF_BUFFER_SIZE1024 * 128 1024 * 128 |
70 | #define CONF_EVENT_MAINT"conference::maintenance" "conference::maintenance" |
71 | #define CONF_EVENT_CDR"conference::cdr" "conference::cdr" |
72 | #define CONF_DEFAULT_LEADIN20 20 |
73 | |
74 | #define CONF_DBLOCK_SIZE1024 * 128 CONF_BUFFER_SIZE1024 * 128 |
75 | #define CONF_DBUFFER_SIZE1024 * 128 CONF_BUFFER_SIZE1024 * 128 |
76 | #define CONF_DBUFFER_MAX0 0 |
77 | #define CONF_CHAT_PROTO"conf" "conf" |
78 | |
79 | #ifndef MIN |
80 | #define MIN(a, b)((a)<(b)?(a):(b)) ((a)<(b)?(a):(b)) |
81 | #endif |
82 | |
83 | /* the rate at which the infinite impulse response filter on speaker score will decay. */ |
84 | #define SCORE_DECAY0.8 0.8 |
85 | /* the maximum value for the IIR score [keeps loud & longwinded people from getting overweighted] */ |
86 | #define SCORE_MAX_IIR25000 25000 |
87 | /* the minimum score for which you can be considered to be loud enough to now have the floor */ |
88 | #define SCORE_IIR_SPEAKING_MAX300 300 |
89 | /* the threshold below which you cede the floor to someone loud (see above value). */ |
90 | #define SCORE_IIR_SPEAKING_MIN100 100 |
91 | |
92 | |
93 | #define test_eflag(conference, flag)((conference)->eflags & flag) ((conference)->eflags & flag) |
94 | |
95 | typedef enum { |
96 | FILE_STOP_CURRENT, |
97 | FILE_STOP_ALL, |
98 | FILE_STOP_ASYNC |
99 | } file_stop_t; |
100 | |
101 | /* Global Values */ |
102 | static struct { |
103 | switch_memory_pool_t *conference_pool; |
104 | switch_mutex_t *conference_mutex; |
105 | switch_hash_t *conference_hash; |
106 | switch_mutex_t *id_mutex; |
107 | switch_mutex_t *hash_mutex; |
108 | switch_mutex_t *setup_mutex; |
109 | uint32_t id_pool; |
110 | int32_t running; |
111 | uint32_t threads; |
112 | switch_event_channel_id_t event_channel_id; |
113 | } globals; |
114 | |
115 | /* forward declaration for conference_obj and caller_control */ |
116 | struct conference_member; |
117 | typedef struct conference_member conference_member_t; |
118 | |
119 | |
120 | typedef struct conference_cdr_node_s { |
121 | switch_caller_profile_t *cp; |
122 | char *record_path; |
123 | switch_time_t join_time; |
124 | switch_time_t leave_time; |
125 | uint32_t flags; |
126 | uint32_t id; |
127 | conference_member_t *member; |
128 | switch_event_t *var_event; |
129 | struct conference_cdr_node_s *next; |
130 | } conference_cdr_node_t; |
131 | |
132 | typedef enum { |
133 | CDRR_LOCKED = 1, |
134 | CDRR_PIN, |
135 | CDRR_MAXMEMBERS |
136 | } cdr_reject_reason_t; |
137 | |
138 | typedef struct conference_cdr_reject_s { |
139 | switch_caller_profile_t *cp; |
140 | switch_time_t reject_time; |
141 | cdr_reject_reason_t reason; |
142 | struct conference_cdr_reject_s *next; |
143 | } conference_cdr_reject_t; |
144 | |
145 | typedef enum { |
146 | CDRE_NONE, |
147 | CDRE_AS_CONTENT, |
148 | CDRE_AS_FILE |
149 | } cdr_event_mode_t; |
150 | |
151 | |
152 | struct call_list { |
153 | char *string; |
154 | int iteration; |
155 | struct call_list *next; |
156 | }; |
157 | typedef struct call_list call_list_t; |
158 | |
159 | struct caller_control_actions; |
160 | |
161 | typedef struct caller_control_actions { |
162 | char *binded_dtmf; |
163 | char *data; |
164 | char *expanded_data; |
165 | } caller_control_action_t; |
166 | |
167 | typedef struct caller_control_menu_info { |
168 | switch_ivr_menu_t *stack; |
169 | char *name; |
170 | } caller_control_menu_info_t; |
171 | |
172 | typedef enum { |
173 | MFLAG_RUNNING = (1 << 0), |
174 | MFLAG_CAN_SPEAK = (1 << 1), |
175 | MFLAG_CAN_HEAR = (1 << 2), |
176 | MFLAG_KICKED = (1 << 3), |
177 | MFLAG_ITHREAD = (1 << 4), |
178 | MFLAG_NOCHANNEL = (1 << 5), |
179 | MFLAG_INTREE = (1 << 6), |
180 | MFLAG_WASTE_FLAG = (1 << 7), |
181 | MFLAG_FLUSH_BUFFER = (1 << 8), |
182 | MFLAG_ENDCONF = (1 << 9), |
183 | MFLAG_HAS_AUDIO = (1 << 10), |
184 | MFLAG_TALKING = (1 << 11), |
185 | MFLAG_RESTART = (1 << 12), |
186 | MFLAG_MINTWO = (1 << 13), |
187 | MFLAG_MUTE_DETECT = (1 << 14), |
188 | MFLAG_DIST_DTMF = (1 << 15), |
189 | MFLAG_MOD = (1 << 16), |
190 | MFLAG_INDICATE_MUTE = (1 << 17), |
191 | MFLAG_INDICATE_UNMUTE = (1 << 18), |
192 | MFLAG_NOMOH = (1 << 19), |
193 | MFLAG_VIDEO_BRIDGE = (1 << 20), |
194 | MFLAG_INDICATE_MUTE_DETECT = (1 << 21), |
195 | MFLAG_PAUSE_RECORDING = (1 << 22), |
196 | MFLAG_ACK_VIDEO = (1 << 23), |
197 | MFLAG_GHOST = (1 << 24), |
198 | MFLAG_JOIN_ONLY = (1 << 25), |
199 | MFLAG_POSITIONAL = (1 << 26), |
200 | MFLAG_NO_POSITIONAL = (1 << 27) |
201 | } member_flag_t; |
202 | |
203 | typedef enum { |
204 | CFLAG_RUNNING = (1 << 0), |
205 | CFLAG_DYNAMIC = (1 << 1), |
206 | CFLAG_ENFORCE_MIN = (1 << 2), |
207 | CFLAG_DESTRUCT = (1 << 3), |
208 | CFLAG_LOCKED = (1 << 4), |
209 | CFLAG_ANSWERED = (1 << 5), |
210 | CFLAG_BRIDGE_TO = (1 << 6), |
211 | CFLAG_WAIT_MOD = (1 << 7), |
212 | CFLAG_VID_FLOOR = (1 << 8), |
213 | CFLAG_WASTE_FLAG = (1 << 9), |
214 | CFLAG_OUTCALL = (1 << 10), |
215 | CFLAG_INHASH = (1 << 11), |
216 | CFLAG_EXIT_SOUND = (1 << 12), |
217 | CFLAG_ENTER_SOUND = (1 << 13), |
218 | CFLAG_VIDEO_BRIDGE = (1 << 14), |
219 | CFLAG_AUDIO_ALWAYS = (1 << 15), |
220 | CFLAG_ENDCONF_FORCED = (1 << 16), |
221 | CFLAG_RFC4579 = (1 << 17), |
222 | CFLAG_FLOOR_CHANGE = (1 << 18), |
223 | CFLAG_VID_FLOOR_LOCK = (1 << 19), |
224 | CFLAG_JSON_EVENTS = (1 << 20), |
225 | CFLAG_LIVEARRAY_SYNC = (1 << 21), |
226 | CFLAG_CONF_RESTART_AUTO_RECORD = (1 << 22), |
227 | CFLAG_POSITIONAL = (1 << 23) |
228 | } conf_flag_t; |
229 | |
230 | typedef enum { |
231 | RFLAG_CAN_SPEAK = (1 << 0), |
232 | RFLAG_CAN_HEAR = (1 << 1) |
233 | } relation_flag_t; |
234 | |
235 | typedef enum { |
236 | NODE_TYPE_FILE, |
237 | NODE_TYPE_SPEECH |
238 | } node_type_t; |
239 | |
240 | typedef enum { |
241 | NFLAG_NONE = (1 << 0), |
242 | NFLAG_PAUSE = (1 << 1) |
243 | } node_flag_t; |
244 | |
245 | typedef enum { |
246 | EFLAG_ADD_MEMBER = (1 << 0), |
247 | EFLAG_DEL_MEMBER = (1 << 1), |
248 | EFLAG_ENERGY_LEVEL = (1 << 2), |
249 | EFLAG_VOLUME_LEVEL = (1 << 3), |
250 | EFLAG_GAIN_LEVEL = (1 << 4), |
251 | EFLAG_DTMF = (1 << 5), |
252 | EFLAG_STOP_TALKING = (1 << 6), |
253 | EFLAG_START_TALKING = (1 << 7), |
254 | EFLAG_MUTE_MEMBER = (1 << 8), |
255 | EFLAG_UNMUTE_MEMBER = (1 << 9), |
256 | EFLAG_DEAF_MEMBER = (1 << 10), |
257 | EFLAG_UNDEAF_MEMBER = (1 << 11), |
258 | EFLAG_KICK_MEMBER = (1 << 12), |
259 | EFLAG_DTMF_MEMBER = (1 << 13), |
260 | EFLAG_ENERGY_LEVEL_MEMBER = (1 << 14), |
261 | EFLAG_VOLUME_IN_MEMBER = (1 << 15), |
262 | EFLAG_VOLUME_OUT_MEMBER = (1 << 16), |
263 | EFLAG_PLAY_FILE = (1 << 17), |
264 | EFLAG_PLAY_FILE_MEMBER = (1 << 18), |
265 | EFLAG_SPEAK_TEXT = (1 << 19), |
266 | EFLAG_SPEAK_TEXT_MEMBER = (1 << 20), |
267 | EFLAG_LOCK = (1 << 21), |
268 | EFLAG_UNLOCK = (1 << 22), |
269 | EFLAG_TRANSFER = (1 << 23), |
270 | EFLAG_BGDIAL_RESULT = (1 << 24), |
271 | EFLAG_FLOOR_CHANGE = (1 << 25), |
272 | EFLAG_MUTE_DETECT = (1 << 26), |
273 | EFLAG_RECORD = (1 << 27), |
274 | EFLAG_HUP_MEMBER = (1 << 28), |
275 | EFLAG_PLAY_FILE_DONE = (1 << 29), |
276 | EFLAG_SET_POSITION_MEMBER = (1 << 30) |
277 | } event_type_t; |
278 | |
279 | #ifdef OPENAL_POSITIONING |
280 | typedef struct al_handle_s { |
281 | ALCdevice *device; |
282 | ALCcontext *context; |
283 | ALuint source; |
284 | ALuint buffer_in[2]; |
285 | int setpos; |
286 | ALfloat pos_x; |
287 | ALfloat pos_y; |
288 | ALfloat pos_z; |
289 | } al_handle_t; |
290 | #else |
291 | typedef struct al_handle_s { |
292 | int unsupported; |
293 | } al_handle_t; |
294 | #endif |
295 | |
296 | typedef struct conference_file_node { |
297 | switch_file_handle_t fh; |
298 | switch_speech_handle_t *sh; |
299 | node_flag_t flags; |
300 | node_type_t type; |
301 | uint8_t done; |
302 | uint8_t async; |
303 | switch_memory_pool_t *pool; |
304 | uint32_t leadin; |
305 | struct conference_file_node *next; |
306 | char *file; |
307 | switch_bool_t mux; |
308 | uint32_t member_id; |
309 | al_handle_t *al; |
310 | } conference_file_node_t; |
311 | |
312 | typedef enum { |
313 | REC_ACTION_STOP = 1, |
314 | REC_ACTION_PAUSE, |
315 | REC_ACTION_RESUME |
316 | } recording_action_type_t; |
317 | |
318 | /* conference xml config sections */ |
319 | typedef struct conf_xml_cfg { |
320 | switch_xml_t profile; |
321 | switch_xml_t controls; |
322 | } conf_xml_cfg_t; |
323 | |
324 | struct vid_helper { |
325 | conference_member_t *member_a; |
326 | conference_member_t *member_b; |
327 | int up; |
328 | }; |
329 | |
330 | struct conference_obj; |
331 | |
332 | /* Record Node */ |
333 | typedef struct conference_record { |
334 | struct conference_obj *conference; |
335 | char *path; |
336 | switch_memory_pool_t *pool; |
337 | switch_bool_t autorec; |
338 | struct conference_record *next; |
339 | } conference_record_t; |
340 | |
341 | /* Conference Object */ |
342 | typedef struct conference_obj { |
343 | char *name; |
344 | char *la_name; |
345 | char *la_event_channel; |
346 | char *mod_event_channel; |
347 | char *desc; |
348 | char *timer_name; |
349 | char *tts_engine; |
350 | char *tts_voice; |
351 | char *enter_sound; |
352 | char *exit_sound; |
353 | char *alone_sound; |
354 | char *perpetual_sound; |
355 | char *moh_sound; |
356 | char *ack_sound; |
357 | char *nack_sound; |
358 | char *muted_sound; |
359 | char *mute_detect_sound; |
360 | char *unmuted_sound; |
361 | char *locked_sound; |
362 | char *is_locked_sound; |
363 | char *is_unlocked_sound; |
364 | char *kicked_sound; |
365 | char *join_only_sound; |
366 | char *caller_id_name; |
367 | char *caller_id_number; |
368 | char *sound_prefix; |
369 | char *special_announce; |
370 | char *auto_record; |
371 | char *record_filename; |
372 | char *outcall_templ; |
373 | uint32_t terminate_on_silence; |
374 | uint32_t max_members; |
375 | uint32_t doc_version; |
376 | char *maxmember_sound; |
377 | uint32_t announce_count; |
378 | char *pin; |
379 | char *mpin; |
380 | char *pin_sound; |
381 | char *bad_pin_sound; |
382 | char *profile_name; |
383 | char *domain; |
384 | char *chat_id; |
385 | char *caller_controls; |
386 | char *moderator_controls; |
387 | switch_live_array_t *la; |
388 | uint32_t flags; |
389 | member_flag_t mflags; |
390 | switch_call_cause_t bridge_hangup_cause; |
391 | switch_mutex_t *flag_mutex; |
392 | uint32_t rate; |
393 | uint32_t interval; |
394 | uint32_t channels; |
395 | switch_mutex_t *mutex; |
396 | conference_member_t *members; |
397 | conference_member_t *floor_holder; |
398 | conference_member_t *video_floor_holder; |
399 | switch_mutex_t *member_mutex; |
400 | conference_file_node_t *fnode; |
401 | conference_file_node_t *async_fnode; |
402 | switch_memory_pool_t *pool; |
403 | switch_thread_rwlock_t *rwlock; |
404 | uint32_t count; |
405 | int32_t energy_level; |
406 | uint8_t min; |
407 | switch_speech_handle_t lsh; |
408 | switch_speech_handle_t *sh; |
409 | switch_byte_t *not_talking_buf; |
410 | uint32_t not_talking_buf_len; |
411 | int pin_retries; |
412 | int broadcast_chat_messages; |
413 | int comfort_noise_level; |
414 | int auto_recording; |
415 | int record_count; |
416 | uint32_t min_recording_participants; |
417 | int video_running; |
418 | int ivr_dtmf_timeout; |
419 | int ivr_input_timeout; |
420 | uint32_t eflags; |
421 | uint32_t verbose_events; |
422 | int end_count; |
423 | uint32_t count_ghosts; |
424 | /* allow extra time after 'endconf' member leaves */ |
425 | switch_time_t endconf_time; |
426 | int endconf_grace_time; |
427 | |
428 | uint32_t relationship_total; |
429 | uint32_t score; |
430 | int mux_loop_count; |
431 | int member_loop_count; |
432 | int agc_level; |
433 | |
434 | uint32_t avg_score; |
435 | uint32_t avg_itt; |
436 | uint32_t avg_tally; |
437 | switch_time_t run_time; |
438 | char *uuid_str; |
439 | uint32_t originating; |
440 | switch_call_cause_t cancel_cause; |
441 | conference_cdr_node_t *cdr_nodes; |
442 | conference_cdr_reject_t *cdr_rejected; |
443 | switch_time_t start_time; |
444 | switch_time_t end_time; |
445 | char *log_dir; |
446 | cdr_event_mode_t cdr_event_mode; |
447 | struct vid_helper vh[2]; |
448 | struct vid_helper mh; |
449 | conference_record_t *rec_node_head; |
450 | int last_speech_channels; |
451 | } conference_obj_t; |
452 | |
453 | /* Relationship with another member */ |
454 | typedef struct conference_relationship { |
455 | uint32_t id; |
456 | uint32_t flags; |
457 | struct conference_relationship *next; |
458 | } conference_relationship_t; |
459 | |
460 | /* Conference Member Object */ |
461 | struct conference_member { |
462 | uint32_t id; |
463 | switch_core_session_t *session; |
464 | switch_channel_t *channel; |
465 | conference_obj_t *conference; |
466 | switch_memory_pool_t *pool; |
467 | switch_buffer_t *audio_buffer; |
468 | switch_buffer_t *mux_buffer; |
469 | switch_buffer_t *resample_buffer; |
470 | uint32_t flags; |
471 | uint32_t score; |
472 | uint32_t last_score; |
473 | uint32_t score_iir; |
474 | switch_mutex_t *flag_mutex; |
475 | switch_mutex_t *write_mutex; |
476 | switch_mutex_t *audio_in_mutex; |
477 | switch_mutex_t *audio_out_mutex; |
478 | switch_mutex_t *read_mutex; |
479 | switch_mutex_t *fnode_mutex; |
480 | switch_thread_rwlock_t *rwlock; |
481 | switch_codec_implementation_t read_impl; |
482 | switch_codec_implementation_t orig_read_impl; |
483 | switch_codec_t read_codec; |
484 | switch_codec_t write_codec; |
485 | char *rec_path; |
486 | switch_time_t rec_time; |
487 | conference_record_t *rec; |
488 | uint8_t *frame; |
489 | uint8_t *last_frame; |
490 | uint32_t frame_size; |
491 | uint8_t *mux_frame; |
492 | uint32_t read; |
493 | uint32_t vol_period; |
494 | int32_t energy_level; |
495 | int32_t agc_volume_in_level; |
496 | int32_t volume_in_level; |
497 | int32_t volume_out_level; |
498 | int32_t agc_concur; |
499 | int32_t nt_tally; |
500 | switch_time_t join_time; |
501 | switch_time_t last_talking; |
502 | uint32_t native_rate; |
503 | switch_audio_resampler_t *read_resampler; |
504 | int16_t *resample_out; |
505 | uint32_t resample_out_len; |
506 | conference_file_node_t *fnode; |
507 | conference_relationship_t *relationships; |
508 | switch_speech_handle_t lsh; |
509 | switch_speech_handle_t *sh; |
510 | uint32_t verbose_events; |
511 | uint32_t avg_score; |
512 | uint32_t avg_itt; |
513 | uint32_t avg_tally; |
514 | struct conference_member *next; |
515 | switch_ivr_dmachine_t *dmachine; |
516 | conference_cdr_node_t *cdr_node; |
517 | char *kicked_sound; |
518 | switch_queue_t *dtmf_queue; |
519 | switch_thread_t *input_thread; |
520 | cJSON *json; |
521 | cJSON *status_field; |
522 | uint8_t loop_loop; |
523 | al_handle_t *al; |
524 | int last_speech_channels; |
525 | }; |
526 | |
527 | typedef enum { |
528 | CONF_API_SUB_ARGS_SPLIT, |
529 | CONF_API_SUB_MEMBER_TARGET, |
530 | CONF_API_SUB_ARGS_AS_ONE |
531 | } conference_fntype_t; |
532 | |
533 | typedef void (*void_fn_t) (void); |
534 | |
535 | /* API command parser */ |
536 | typedef struct api_command { |
537 | char *pname; |
538 | void_fn_t pfnapicmd; |
539 | conference_fntype_t fntype; |
540 | char *pcommand; |
541 | char *psyntax; |
542 | } api_command_t; |
543 | |
544 | /* Function Prototypes */ |
545 | static int setup_media(conference_member_t *member, conference_obj_t *conference); |
546 | static uint32_t next_member_id(void); |
547 | static conference_relationship_t *member_get_relationship(conference_member_t *member, conference_member_t *other_member); |
548 | static conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id); |
549 | static conference_relationship_t *member_add_relationship(conference_member_t *member, uint32_t id); |
550 | static switch_status_t member_del_relationship(conference_member_t *member, uint32_t id); |
551 | static switch_status_t conference_add_member(conference_obj_t *conference, conference_member_t *member); |
552 | static switch_status_t conference_del_member(conference_obj_t *conference, conference_member_t *member); |
553 | static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *obj); |
554 | static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thread, void *obj); |
555 | static void conference_loop_output(conference_member_t *member); |
556 | static uint32_t conference_stop_file(conference_obj_t *conference, file_stop_t stop); |
557 | static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel, uint8_t async); |
558 | static void conference_send_all_dtmf(conference_member_t *member, conference_obj_t *conference, const char *dtmf); |
559 | static switch_status_t conference_say(conference_obj_t *conference, const char *text, uint32_t leadin); |
560 | static void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim); |
561 | static conference_obj_t *conference_find(char *name, char *domain); |
562 | static void member_bind_controls(conference_member_t *member, const char *controls); |
563 | static void conference_send_presence(conference_obj_t *conference); |
564 | |
565 | SWITCH_STANDARD_API(conf_api_main)static switch_status_t conf_api_main ( const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream); |
566 | |
567 | static switch_status_t conference_outcall(conference_obj_t *conference, |
568 | char *conference_name, |
569 | switch_core_session_t *session, |
570 | char *bridgeto, uint32_t timeout, |
571 | char *flags, |
572 | char *cid_name, |
573 | char *cid_num, |
574 | char *profile, |
575 | switch_call_cause_t *cause, |
576 | switch_call_cause_t *cancel_cause, switch_event_t *var_event); |
577 | static switch_status_t conference_outcall_bg(conference_obj_t *conference, |
578 | char *conference_name, |
579 | switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name, |
580 | const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause, switch_event_t **var_event); |
581 | SWITCH_STANDARD_APP(conference_function)static void conference_function (switch_core_session_t *session , const char *data); |
582 | static void launch_conference_thread(conference_obj_t *conference); |
583 | static void launch_conference_video_thread(conference_obj_t *conference); |
584 | static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *obj); |
585 | static switch_status_t conference_local_play_file(conference_obj_t *conference, switch_core_session_t *session, char *path, uint32_t leadin, void *buf, |
586 | uint32_t buflen); |
587 | static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin, switch_bool_t mux); |
588 | static switch_status_t conference_member_say(conference_member_t *member, char *text, uint32_t leadin); |
589 | static uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop); |
590 | static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_core_session_t *session, switch_memory_pool_t *pool); |
591 | static switch_status_t chat_send(switch_event_t *message_event); |
592 | |
593 | |
594 | static void launch_conference_record_thread(conference_obj_t *conference, char *path, switch_bool_t autorec); |
595 | static int launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b); |
596 | |
597 | typedef switch_status_t (*conf_api_args_cmd_t) (conference_obj_t *, switch_stream_handle_t *, int, char **); |
598 | typedef switch_status_t (*conf_api_member_cmd_t) (conference_member_t *, switch_stream_handle_t *, void *); |
599 | typedef switch_status_t (*conf_api_text_cmd_t) (conference_obj_t *, switch_stream_handle_t *, const char *); |
600 | |
601 | static void conference_member_itterator(conference_obj_t *conference, switch_stream_handle_t *stream, uint8_t non_mod, conf_api_member_cmd_t pfncallback, void *data); |
602 | static switch_status_t conf_api_sub_mute(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
603 | static switch_status_t conf_api_sub_tmute(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
604 | static switch_status_t conf_api_sub_unmute(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
605 | static switch_status_t conf_api_sub_deaf(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
606 | static switch_status_t conf_api_sub_undeaf(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
607 | static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event); |
608 | static switch_status_t conference_add_event_member_data(conference_member_t *member, switch_event_t *event); |
609 | static switch_status_t conf_api_sub_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
610 | static switch_status_t conf_api_sub_vid_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
611 | static switch_status_t conf_api_sub_clear_vid_floor(conference_obj_t *conference, switch_stream_handle_t *stream, void *data); |
612 | |
613 | |
614 | #define lock_member(_member)switch_mutex_lock(_member->write_mutex); switch_mutex_lock (_member->read_mutex) switch_mutex_lock(_member->write_mutex); switch_mutex_lock(_member->read_mutex) |
615 | #define unlock_member(_member)switch_mutex_unlock(_member->read_mutex); switch_mutex_unlock (_member->write_mutex) switch_mutex_unlock(_member->read_mutex); switch_mutex_unlock(_member->write_mutex) |
616 | |
617 | //#define lock_member(_member) switch_mutex_lock(_member->write_mutex) |
618 | //#define unlock_member(_member) switch_mutex_unlock(_member->write_mutex) |
619 | |
620 | static al_handle_t *create_al(switch_memory_pool_t *pool) |
621 | { |
622 | al_handle_t *al; |
623 | |
624 | al = switch_core_alloc(pool, sizeof(al_handle_t))switch_core_perform_alloc(pool, sizeof(al_handle_t), "mod_conference.c" , (const char *)__func__, 624); |
625 | |
626 | return al; |
627 | } |
628 | |
629 | #ifndef OPENAL_POSITIONING |
630 | static void gen_arc(conference_obj_t *conference, switch_stream_handle_t *stream) |
631 | { |
632 | } |
633 | static void process_al(al_handle_t *al, void *data, switch_size_t datalen, int rate) |
634 | { |
635 | } |
636 | |
637 | #else |
638 | static void gen_arc(conference_obj_t *conference, switch_stream_handle_t *stream) |
639 | { |
640 | float offset; |
641 | float pos; |
642 | float radius; |
643 | float x, z; |
644 | float div = 3.14159f / 180; |
645 | conference_member_t *member; |
646 | uint32_t count = 0; |
647 | |
648 | if (!conference->count) { |
649 | return; |
650 | } |
651 | |
652 | switch_mutex_lock(conference->member_mutex); |
653 | for (member = conference->members; member; member = member->next) { |
654 | if (member->channel && switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) && !switch_test_flag(member, MFLAG_NO_POSITIONAL)((member)->flags & MFLAG_NO_POSITIONAL)) { |
655 | count++; |
656 | } |
657 | } |
658 | |
659 | if (count < 3) { |
660 | for (member = conference->members; member; member = member->next) { |
661 | if (member->channel && !switch_test_flag(member, MFLAG_NO_POSITIONAL)((member)->flags & MFLAG_NO_POSITIONAL) && member->al) { |
662 | member->al->pos_x = 0; |
663 | member->al->pos_y = 0; |
664 | member->al->pos_z = 0; |
665 | member->al->setpos = 1; |
666 | |
667 | if (stream) { |
668 | stream->write_function(stream, "Member %d (%s) 0.0:0.0:0.0\n", member->id, switch_channel_get_name(member->channel)); |
669 | } else { |
670 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 670, ((void*)0), SWITCH_LOG_DEBUG, "Member %d (%s) 0.0:0.0:0.0\n", |
671 | member->id, switch_channel_get_name(member->channel)); |
672 | } |
673 | } |
674 | } |
675 | |
676 | goto end; |
677 | } |
678 | |
679 | offset = 180 / (count - 1); |
680 | |
681 | radius = 1.0f; |
682 | |
683 | pos = -90.0f; |
684 | |
685 | for (member = conference->members; member; member = member->next) { |
686 | |
687 | if (!member->channel || switch_test_flag(member, MFLAG_NO_POSITIONAL)((member)->flags & MFLAG_NO_POSITIONAL) || !switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
688 | continue; |
689 | } |
690 | |
691 | if (!member->al) { |
692 | member->al = create_al(member->pool); |
693 | } |
694 | switch_set_flag(member, MFLAG_POSITIONAL)(member)->flags |= (MFLAG_POSITIONAL); |
695 | |
696 | if (pos == 0) { |
697 | x = 0; |
698 | z = radius; |
699 | } else if (pos == -90) { |
700 | z = 0; |
701 | x = radius * -1; |
702 | } else if (pos == 90) { |
703 | z = 0; |
704 | x = radius; |
705 | } else if (pos < 0) { |
706 | z = cos((90+pos) * div) * radius; |
707 | x = sin((90+pos) * div) * radius * -1.0f; |
708 | } else { |
709 | x = cos(pos * div) * radius; |
710 | z = sin(pos * div) * radius; |
711 | } |
712 | |
713 | member->al->pos_x = x; |
714 | member->al->pos_y = 0; |
715 | member->al->pos_z = z; |
716 | member->al->setpos = 1; |
717 | |
718 | if (stream) { |
719 | stream->write_function(stream, "Member %d (%s) %0.2f:0.0:%0.2f\n", member->id, switch_channel_get_name(member->channel), x, z); |
720 | } else { |
721 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 721, ((void*)0), SWITCH_LOG_DEBUG, "Member %d (%s) %0.2f:0.0:%0.2f\n", |
722 | member->id, switch_channel_get_name(member->channel), x, z); |
723 | } |
724 | |
725 | pos += offset; |
726 | } |
727 | |
728 | end: |
729 | |
730 | switch_mutex_unlock(conference->member_mutex); |
731 | |
732 | return; |
733 | |
734 | } |
735 | |
736 | |
737 | #define ALC_HRTF_SOFT 0x1992 |
738 | |
739 | static void process_al(al_handle_t *al, void *data, switch_size_t datalen, int rate) |
740 | { |
741 | |
742 | if (rate != 48000) { |
743 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 743, ((void*)0), SWITCH_LOG_ERROR, "Only 48khz is supported.\n"); |
744 | return; |
745 | } |
746 | |
747 | if (!al->device) { |
748 | ALCint contextAttr[] = { |
749 | ALC_FORMAT_CHANNELS_SOFT, ALC_STEREO_SOFT, |
750 | ALC_FORMAT_TYPE_SOFT, ALC_SHORT_SOFT, |
751 | ALC_FREQUENCY, rate, |
752 | ALC_HRTF_SOFT, AL_TRUE, |
753 | 0 |
754 | }; |
755 | |
756 | switch_mutex_lock(globals.setup_mutex); |
757 | if ((al->device = alcLoopbackOpenDeviceSOFT(NULL((void*)0)))) { |
758 | static const ALshort silence[16] = { 0 }; |
759 | float orient[6] = { /*fwd:*/ 0., 0., -1., /*up:*/ 0., 1., 0. }; |
760 | |
761 | al->context = alcCreateContext(al->device, contextAttr); |
762 | alcSetThreadContext(al->context); |
763 | |
764 | /* listener at origin, facing down -z (ears at 0.0m height) */ |
765 | alListener3f( AL_POSITION, 0. ,0, 0. ); |
766 | alListener3f( AL_VELOCITY, 0., 0., 0. ); |
767 | alListenerfv( AL_ORIENTATION, orient ); |
768 | |
769 | |
770 | alGenSources(1, &al->source); |
771 | alSourcef( al->source, AL_PITCH, 1.); |
772 | alSourcef( al->source, AL_GAIN, 1.); |
773 | alGenBuffers(2, al->buffer_in); |
774 | |
775 | alBufferData(al->buffer_in[0], AL_FORMAT_MONO16, data, datalen, rate); |
776 | //alBufferData(al->buffer_in[0], AL_FORMAT_MONO16, NULL, 0, rate); |
777 | alBufferData(al->buffer_in[1], AL_FORMAT_MONO16, silence, sizeof(silence), rate); |
778 | alSourceQueueBuffers(al->source, 2, al->buffer_in); |
779 | alSourcePlay(al->source); |
780 | } |
781 | switch_mutex_unlock(globals.setup_mutex); |
782 | } |
783 | |
784 | if (al->device) { |
785 | ALint processed = 0, state = 0; |
786 | |
787 | //alcSetThreadContext(al->context); |
788 | alGetSourcei(al->source, AL_SOURCE_STATE, &state); |
789 | alGetSourcei(al->source, AL_BUFFERS_PROCESSED, &processed); |
790 | |
791 | if (al->setpos) { |
792 | al->setpos = 0; |
793 | alSource3f(al->source, AL_POSITION, al->pos_x, al->pos_y, al->pos_z); |
794 | //alSource3f(al->source, AL_VELOCITY, .01, 0., 0.); |
795 | } |
796 | |
797 | if (processed > 0) { |
798 | ALuint bufid; |
799 | alSourceUnqueueBuffers(al->source, 1, &bufid); |
800 | alBufferData(bufid, AL_FORMAT_MONO16, data, datalen, rate); |
801 | alSourceQueueBuffers(al->source, 1, &bufid); |
802 | } |
803 | |
804 | if (state != AL_PLAYING) { |
805 | alSourcePlay(al->source); |
806 | } |
807 | |
808 | alcRenderSamplesSOFT(al->device, data, datalen / 2); |
809 | } |
810 | } |
811 | #endif |
812 | |
813 | static void conference_cdr_del(conference_member_t *member) |
814 | { |
815 | if (member->channel) { |
816 | switch_channel_get_variables(member->channel, &member->cdr_node->var_event); |
817 | } |
818 | member->cdr_node->leave_time = switch_epoch_time_now(NULL((void*)0)); |
819 | member->cdr_node->flags = member->flags; |
820 | member->cdr_node->member = NULL((void*)0); |
821 | } |
822 | |
823 | static void conference_cdr_add(conference_member_t *member) |
824 | { |
825 | conference_cdr_node_t *np; |
826 | switch_caller_profile_t *cp; |
827 | switch_channel_t *channel; |
828 | |
829 | np = switch_core_alloc(member->conference->pool, sizeof(*np))switch_core_perform_alloc(member->conference->pool, sizeof (*np), "mod_conference.c", (const char *)__func__, 829); |
830 | |
831 | np->next = member->conference->cdr_nodes; |
832 | member->conference->cdr_nodes = member->cdr_node = np; |
833 | member->cdr_node->join_time = switch_epoch_time_now(NULL((void*)0)); |
834 | member->cdr_node->member = member; |
835 | |
836 | if (!member->session) { |
837 | member->cdr_node->record_path = switch_core_strdup(member->conference->pool, member->rec_path)switch_core_perform_strdup(member->conference->pool, member ->rec_path, "mod_conference.c", (const char *)__func__, 837 ); |
838 | return; |
839 | } |
840 | |
841 | channel = switch_core_session_get_channel(member->session); |
842 | |
843 | if (!(cp = switch_channel_get_caller_profile(channel))) { |
844 | return; |
845 | } |
846 | |
847 | member->cdr_node->cp = switch_caller_profile_dup(member->conference->pool, cp); |
848 | |
849 | member->cdr_node->id = member->id; |
850 | |
851 | |
852 | |
853 | } |
854 | |
855 | static void conference_cdr_rejected(conference_obj_t *conference, switch_channel_t *channel, cdr_reject_reason_t reason) |
856 | { |
857 | conference_cdr_reject_t *rp; |
858 | switch_caller_profile_t *cp; |
859 | |
860 | rp = switch_core_alloc(conference->pool, sizeof(*rp))switch_core_perform_alloc(conference->pool, sizeof(*rp), "mod_conference.c" , (const char *)__func__, 860); |
861 | |
862 | rp->next = conference->cdr_rejected; |
863 | conference->cdr_rejected = rp; |
864 | rp->reason = reason; |
865 | rp->reject_time = switch_epoch_time_now(NULL((void*)0)); |
866 | |
867 | if (!(cp = switch_channel_get_caller_profile(channel))) { |
868 | return; |
869 | } |
870 | |
871 | rp->cp = switch_caller_profile_dup(conference->pool, cp); |
872 | } |
873 | |
874 | static const char *audio_flow(conference_member_t *member) |
875 | { |
876 | const char *flow = "sendrecv"; |
877 | |
878 | if (!switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
879 | flow = "recvonly"; |
880 | } |
881 | |
882 | if (member->channel && switch_channel_test_flag(member->channel, CF_HOLD)) { |
883 | flow = switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) ? "sendonly" : "inactive"; |
884 | } |
885 | |
886 | return flow; |
887 | } |
888 | |
889 | static char *conference_rfc4579_render(conference_obj_t *conference, switch_event_t *event, switch_event_t *revent) |
890 | { |
891 | switch_xml_t xml, x_tag, x_tag1, x_tag2, x_tag3, x_tag4; |
892 | char tmp[30]; |
893 | const char *domain; const char *name; |
894 | char *dup_domain = NULL((void*)0); |
895 | char *uri; |
896 | int off = 0, off1 = 0, off2 = 0, off3 = 0, off4 = 0; |
897 | conference_cdr_node_t *np; |
898 | char *tmpp = tmp; |
899 | char *xml_text = NULL((void*)0); |
900 | |
901 | if (!(xml = switch_xml_new("conference-info"))) { |
902 | abort(); |
903 | } |
904 | |
905 | switch_mutex_lock(conference->mutex); |
906 | switch_snprintf(tmp, sizeof(tmp), "%u", conference->doc_version); |
907 | conference->doc_version++; |
908 | switch_mutex_unlock(conference->mutex); |
909 | |
910 | if (!event || !(name = switch_event_get_header(event, "conference-name")switch_event_get_header_idx(event, "conference-name", -1))) { |
911 | if (!(name = conference->name)) { |
912 | name = "conference"; |
913 | } |
914 | } |
915 | |
916 | if (!event || !(domain = switch_event_get_header(event, "conference-domain")switch_event_get_header_idx(event, "conference-domain", -1))) { |
917 | if (!(domain = conference->domain)) { |
918 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
919 | if (!(domain = dup_domain)) { |
920 | domain = "cluecon.com"; |
921 | } |
922 | } |
923 | } |
924 | |
925 | switch_xml_set_attr_d(xml, "version", tmpp)switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), (__extension__ (__builtin_constant_p ("version") && ( (size_t)(const void *)(("version") + 1) - (size_t)(const void *)("version") == 1) ? (((const char *) ("version"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("version") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "version", __len); __retval; })) : __strdup ("version" ))), (__extension__ (__builtin_constant_p ((tmpp ? tmpp : "") ) && ((size_t)(const void *)(((tmpp ? tmpp : "")) + 1 ) - (size_t)(const void *)((tmpp ? tmpp : "")) == 1) ? (((const char *) ((tmpp ? tmpp : "")))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((tmpp ? tmpp : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (tmpp ? tmpp : ""), __len); __retval; })) : __strdup ((tmpp ? tmpp : ""))))); |
926 | |
927 | switch_xml_set_attr_d(xml, "state", "full")switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), (__extension__ (__builtin_constant_p ("state") && (( size_t)(const void *)(("state") + 1) - (size_t)(const void *) ("state") == 1) ? (((const char *) ("state"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("state") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "state", __len); __retval; })) : __strdup ("state"))), (__extension__ (__builtin_constant_p (("full" ? "full" : "")) && (( size_t)(const void *)((("full" ? "full" : "")) + 1) - (size_t )(const void *)(("full" ? "full" : "")) == 1) ? (((const char *) (("full" ? "full" : "")))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("full" ? "full" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("full" ? "full" : ""), __len); __retval; })) : __strdup (("full" ? "full" : ""))))); |
928 | switch_xml_set_attr_d(xml, "xmlns", "urn:ietf:params:xml:ns:conference-info")switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), (__extension__ (__builtin_constant_p ("xmlns") && (( size_t)(const void *)(("xmlns") + 1) - (size_t)(const void *) ("xmlns") == 1) ? (((const char *) ("xmlns"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("xmlns") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "xmlns", __len); __retval; })) : __strdup ("xmlns"))), (__extension__ (__builtin_constant_p (("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")) && ((size_t)(const void *)((("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")) + 1) - (size_t )(const void *)(("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")) == 1) ? (((const char *) (("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : ""), __len); __retval ; })) : __strdup (("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : ""))))); |
929 | |
930 | |
931 | uri = switch_mprintf("sip:%s@%s", name, domain); |
932 | switch_xml_set_attr_d(xml, "entity", uri)switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), (__extension__ (__builtin_constant_p ("entity") && ( (size_t)(const void *)(("entity") + 1) - (size_t)(const void * )("entity") == 1) ? (((const char *) ("entity"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("entity") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "entity", __len); __retval; })) : __strdup ("entity"))), (__extension__ (__builtin_constant_p ((uri ? uri : "")) && ((size_t )(const void *)(((uri ? uri : "")) + 1) - (size_t)(const void *)((uri ? uri : "")) == 1) ? (((const char *) ((uri ? uri : "" )))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ( { size_t __len = strlen ((uri ? uri : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (uri ? uri : ""), __len); __retval ; })) : __strdup ((uri ? uri : ""))))); |
933 | |
934 | if (!(x_tag = switch_xml_add_child_d(xml, "conference-description", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ ( __builtin_constant_p ("conference-description") && (( size_t)(const void *)(("conference-description") + 1) - (size_t )(const void *)("conference-description") == 1) ? (((const char *) ("conference-description"))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference-description" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "conference-description" , __len); __retval; })) : __strdup ("conference-description") )), off++), SWITCH_XML_NAMEM))) { |
935 | abort(); |
936 | } |
937 | |
938 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "display-text", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("display-text") && ((size_t)( const void *)(("display-text") + 1) - (size_t)(const void *)( "display-text") == 1) ? (((const char *) ("display-text"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("display-text") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "display-text", __len); __retval; })) : __strdup ("display-text"))), off1++), SWITCH_XML_NAMEM))) { |
939 | abort(); |
940 | } |
941 | switch_xml_set_txt_d(x_tag1, conference->desc ? conference->desc : "FreeSWITCH Conference")switch_xml_set_flag(switch_xml_set_txt(x_tag1, (__extension__ (__builtin_constant_p (conference->desc ? conference-> desc : "FreeSWITCH Conference") && ((size_t)(const void *)((conference->desc ? conference->desc : "FreeSWITCH Conference" ) + 1) - (size_t)(const void *)(conference->desc ? conference ->desc : "FreeSWITCH Conference") == 1) ? (((const char *) (conference->desc ? conference->desc : "FreeSWITCH Conference" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (conference->desc ? conference-> desc : "FreeSWITCH Conference") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, conference->desc ? conference->desc : "FreeSWITCH Conference", __len); __retval; })) : __strdup ( conference->desc ? conference->desc : "FreeSWITCH Conference" )))), SWITCH_XML_TXTM); |
942 | |
943 | |
944 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "conf-uris", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("conf-uris") && ((size_t)(const void *)(("conf-uris") + 1) - (size_t)(const void *)("conf-uris" ) == 1) ? (((const char *) ("conf-uris"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "conf-uris") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "conf-uris", __len); __retval; })) : __strdup ("conf-uris") )), off1++), SWITCH_XML_NAMEM))) { |
945 | abort(); |
946 | } |
947 | |
948 | if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "entry", off2++)switch_xml_set_flag(switch_xml_add_child(x_tag1, (__extension__ (__builtin_constant_p ("entry") && ((size_t)(const void *)(("entry") + 1) - (size_t)(const void *)("entry") == 1) ? ( ((const char *) ("entry"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("entry") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "entry", __len); __retval ; })) : __strdup ("entry"))), off2++), SWITCH_XML_NAMEM))) { |
949 | abort(); |
950 | } |
951 | |
952 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "uri", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("uri") && ((size_t)(const void *)(("uri") + 1) - (size_t)(const void *)("uri") == 1) ? (((const char *) ("uri"))[0] == '\0' ? (char *) calloc ((size_t) 1, ( size_t) 1) : ({ size_t __len = strlen ("uri") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "uri", __len); __retval; })) : __strdup ("uri"))), off3++), SWITCH_XML_NAMEM))) { |
953 | abort(); |
954 | } |
955 | switch_xml_set_txt_d(x_tag3, uri)switch_xml_set_flag(switch_xml_set_txt(x_tag3, (__extension__ (__builtin_constant_p (uri) && ((size_t)(const void * )((uri) + 1) - (size_t)(const void *)(uri) == 1) ? (((const char *) (uri))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (uri) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, uri, __len); __retval; })) : __strdup ( uri)))), SWITCH_XML_TXTM); |
956 | |
957 | |
958 | |
959 | if (!(x_tag = switch_xml_add_child_d(xml, "conference-state", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ ( __builtin_constant_p ("conference-state") && ((size_t )(const void *)(("conference-state") + 1) - (size_t)(const void *)("conference-state") == 1) ? (((const char *) ("conference-state" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference-state") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "conference-state", __len); __retval ; })) : __strdup ("conference-state"))), off++), SWITCH_XML_NAMEM ))) { |
960 | abort(); |
961 | } |
962 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "user-count", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("user-count") && ((size_t)(const void *)(("user-count") + 1) - (size_t)(const void *)("user-count" ) == 1) ? (((const char *) ("user-count"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("user-count") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "user-count", __len); __retval; })) : __strdup ("user-count" ))), off1++), SWITCH_XML_NAMEM))) { |
963 | abort(); |
964 | } |
965 | switch_snprintf(tmp, sizeof(tmp), "%u", conference->count); |
966 | switch_xml_set_txt_d(x_tag1, tmpp)switch_xml_set_flag(switch_xml_set_txt(x_tag1, (__extension__ (__builtin_constant_p (tmpp) && ((size_t)(const void *)((tmpp) + 1) - (size_t)(const void *)(tmpp) == 1) ? (((const char *) (tmpp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (tmpp) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, tmpp, __len); __retval; })) : __strdup (tmpp)))), SWITCH_XML_TXTM); |
967 | |
968 | #if 0 |
969 | if (conference->count == 0) { |
970 | switch_event_add_header(revent, SWITCH_STACK_BOTTOM, "notfound", "true"); |
971 | } |
972 | #endif |
973 | |
974 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "active", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("active") && ((size_t)(const void *)(("active") + 1) - (size_t)(const void *)("active") == 1) ? (((const char *) ("active"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("active") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "active", __len ); __retval; })) : __strdup ("active"))), off1++), SWITCH_XML_NAMEM ))) { |
975 | abort(); |
976 | } |
977 | switch_xml_set_txt_d(x_tag1, "true")switch_xml_set_flag(switch_xml_set_txt(x_tag1, (__extension__ (__builtin_constant_p ("true") && ((size_t)(const void *)(("true") + 1) - (size_t)(const void *)("true") == 1) ? (( (const char *) ("true"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("true") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "true", __len); __retval ; })) : __strdup ("true")))), SWITCH_XML_TXTM); |
978 | |
979 | off1 = off2 = off3 = off4 = 0; |
980 | |
981 | if (!(x_tag = switch_xml_add_child_d(xml, "users", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ ( __builtin_constant_p ("users") && ((size_t)(const void *)(("users") + 1) - (size_t)(const void *)("users") == 1) ? ( ((const char *) ("users"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("users") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "users", __len); __retval ; })) : __strdup ("users"))), off++), SWITCH_XML_NAMEM))) { |
982 | abort(); |
983 | } |
984 | |
985 | switch_mutex_lock(conference->member_mutex); |
986 | |
987 | for (np = conference->cdr_nodes; np; np = np->next) { |
988 | char *user_uri = NULL((void*)0); |
989 | switch_channel_t *channel = NULL((void*)0); |
990 | |
991 | if (!np->cp || (np->member && !np->member->session) || np->leave_time) { /* for now we'll remove participants when the leave */ |
992 | continue; |
993 | } |
994 | |
995 | if (np->member && np->member->session) { |
996 | channel = switch_core_session_get_channel(np->member->session); |
997 | } |
998 | |
999 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "user", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("user") && ((size_t)(const void *)(("user") + 1) - (size_t)(const void *)("user") == 1) ? (( (const char *) ("user"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("user") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "user", __len); __retval ; })) : __strdup ("user"))), off1++), SWITCH_XML_NAMEM))) { |
1000 | abort(); |
1001 | } |
1002 | |
1003 | if (channel) { |
1004 | const char *uri = switch_channel_get_variable_dup(channel, "conference_invite_uri", SWITCH_FALSE, -1); |
1005 | |
1006 | if (uri) { |
1007 | user_uri = strdup(uri)(__extension__ (__builtin_constant_p (uri) && ((size_t )(const void *)((uri) + 1) - (size_t)(const void *)(uri) == 1 ) ? (((const char *) (uri))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (uri) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, uri, __len); __retval ; })) : __strdup (uri))); |
1008 | } |
1009 | } |
1010 | |
1011 | if (!user_uri) { |
1012 | user_uri = switch_mprintf("sip:%s@%s", np->cp->caller_id_number, domain); |
1013 | } |
1014 | |
1015 | |
1016 | switch_xml_set_attr_d(x_tag1, "state", "full")switch_xml_set_attr(switch_xml_set_flag(x_tag1, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("state") && ( (size_t)(const void *)(("state") + 1) - (size_t)(const void * )("state") == 1) ? (((const char *) ("state"))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("state") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "state", __len); __retval; })) : __strdup ("state"))), (__extension__ (__builtin_constant_p (("full" ? "full" : "")) && (( size_t)(const void *)((("full" ? "full" : "")) + 1) - (size_t )(const void *)(("full" ? "full" : "")) == 1) ? (((const char *) (("full" ? "full" : "")))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("full" ? "full" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("full" ? "full" : ""), __len); __retval; })) : __strdup (("full" ? "full" : ""))))); |
1017 | switch_xml_set_attr_d(x_tag1, "entity", user_uri)switch_xml_set_attr(switch_xml_set_flag(x_tag1, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("entity") && ((size_t)(const void *)(("entity") + 1) - (size_t)(const void *)("entity") == 1) ? (((const char *) ("entity"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("entity") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "entity", __len); __retval; })) : __strdup ("entity"))), (__extension__ (__builtin_constant_p ((user_uri ? user_uri : "")) && ((size_t)(const void *)(((user_uri ? user_uri : "")) + 1) - ( size_t)(const void *)((user_uri ? user_uri : "")) == 1) ? ((( const char *) ((user_uri ? user_uri : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((user_uri ? user_uri : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (user_uri ? user_uri : ""), __len); __retval; })) : __strdup ((user_uri ? user_uri : ""))))); |
1018 | |
1019 | if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "display-text", off2++)switch_xml_set_flag(switch_xml_add_child(x_tag1, (__extension__ (__builtin_constant_p ("display-text") && ((size_t)( const void *)(("display-text") + 1) - (size_t)(const void *)( "display-text") == 1) ? (((const char *) ("display-text"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("display-text") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "display-text", __len); __retval; })) : __strdup ("display-text"))), off2++), SWITCH_XML_NAMEM))) { |
1020 | abort(); |
1021 | } |
1022 | switch_xml_set_txt_d(x_tag2, np->cp->caller_id_name)switch_xml_set_flag(switch_xml_set_txt(x_tag2, (__extension__ (__builtin_constant_p (np->cp->caller_id_name) && ((size_t)(const void *)((np->cp->caller_id_name) + 1) - (size_t)(const void *)(np->cp->caller_id_name) == 1) ? (((const char *) (np->cp->caller_id_name))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (np->cp->caller_id_name) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, np->cp->caller_id_name, __len ); __retval; })) : __strdup (np->cp->caller_id_name)))) , SWITCH_XML_TXTM); |
1023 | |
1024 | |
1025 | if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "endpoint", off2++)switch_xml_set_flag(switch_xml_add_child(x_tag1, (__extension__ (__builtin_constant_p ("endpoint") && ((size_t)(const void *)(("endpoint") + 1) - (size_t)(const void *)("endpoint" ) == 1) ? (((const char *) ("endpoint"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "endpoint") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "endpoint", __len); __retval; })) : __strdup ("endpoint"))) , off2++), SWITCH_XML_NAMEM))) { |
1026 | abort(); |
1027 | } |
1028 | switch_xml_set_attr_d(x_tag2, "entity", user_uri)switch_xml_set_attr(switch_xml_set_flag(x_tag2, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("entity") && ((size_t)(const void *)(("entity") + 1) - (size_t)(const void *)("entity") == 1) ? (((const char *) ("entity"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("entity") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "entity", __len); __retval; })) : __strdup ("entity"))), (__extension__ (__builtin_constant_p ((user_uri ? user_uri : "")) && ((size_t)(const void *)(((user_uri ? user_uri : "")) + 1) - ( size_t)(const void *)((user_uri ? user_uri : "")) == 1) ? ((( const char *) ((user_uri ? user_uri : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((user_uri ? user_uri : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (user_uri ? user_uri : ""), __len); __retval; })) : __strdup ((user_uri ? user_uri : ""))))); |
1029 | |
1030 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "display-text", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("display-text") && ((size_t)( const void *)(("display-text") + 1) - (size_t)(const void *)( "display-text") == 1) ? (((const char *) ("display-text"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("display-text") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "display-text", __len); __retval; })) : __strdup ("display-text"))), off3++), SWITCH_XML_NAMEM))) { |
1031 | abort(); |
1032 | } |
1033 | switch_xml_set_txt_d(x_tag3, np->cp->caller_id_name)switch_xml_set_flag(switch_xml_set_txt(x_tag3, (__extension__ (__builtin_constant_p (np->cp->caller_id_name) && ((size_t)(const void *)((np->cp->caller_id_name) + 1) - (size_t)(const void *)(np->cp->caller_id_name) == 1) ? (((const char *) (np->cp->caller_id_name))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (np->cp->caller_id_name) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, np->cp->caller_id_name, __len ); __retval; })) : __strdup (np->cp->caller_id_name)))) , SWITCH_XML_TXTM); |
1034 | |
1035 | |
1036 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "status", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("status") && ((size_t)(const void *)(("status") + 1) - (size_t)(const void *)("status") == 1) ? (((const char *) ("status"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("status") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "status", __len ); __retval; })) : __strdup ("status"))), off3++), SWITCH_XML_NAMEM ))) { |
1037 | abort(); |
1038 | } |
1039 | switch_xml_set_txt_d(x_tag3, np->leave_time ? "disconnected" : "connected")switch_xml_set_flag(switch_xml_set_txt(x_tag3, (__extension__ (__builtin_constant_p (np->leave_time ? "disconnected" : "connected" ) && ((size_t)(const void *)((np->leave_time ? "disconnected" : "connected") + 1) - (size_t)(const void *)(np->leave_time ? "disconnected" : "connected") == 1) ? (((const char *) (np ->leave_time ? "disconnected" : "connected"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (np->leave_time ? "disconnected" : "connected") + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, np->leave_time ? "disconnected" : "connected", __len); __retval; })) : __strdup (np->leave_time ? "disconnected" : "connected")))), SWITCH_XML_TXTM ); |
1040 | |
1041 | |
1042 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "joining-info", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("joining-info") && ((size_t)( const void *)(("joining-info") + 1) - (size_t)(const void *)( "joining-info") == 1) ? (((const char *) ("joining-info"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("joining-info") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "joining-info", __len); __retval; })) : __strdup ("joining-info"))), off3++), SWITCH_XML_NAMEM))) { |
1043 | abort(); |
1044 | } |
1045 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "when", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("when") && ((size_t)(const void *)(("when") + 1) - (size_t)(const void *)("when") == 1) ? (( (const char *) ("when"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("when") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "when", __len); __retval ; })) : __strdup ("when"))), off4++), SWITCH_XML_NAMEM))) { |
1046 | abort(); |
1047 | } else { |
1048 | switch_time_exp_t tm; |
1049 | switch_size_t retsize; |
1050 | const char *fmt = "%Y-%m-%dT%H:%M:%S%z"; |
1051 | char *p; |
1052 | |
1053 | switch_time_exp_lt(&tm, (switch_time_t) conference->start_time * 1000000); |
1054 | switch_strftime_nocheck(tmp, &retsize, sizeof(tmp), fmt, &tm); |
1055 | p = end_of_p(tmpp)(*tmpp == '\0' ? tmpp : tmpp + strlen(tmpp) - 1) -1; |
1056 | snprintf(p, 4, ":00"); |
1057 | |
1058 | |
1059 | switch_xml_set_txt_d(x_tag4, tmpp)switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (tmpp) && ((size_t)(const void *)((tmpp) + 1) - (size_t)(const void *)(tmpp) == 1) ? (((const char *) (tmpp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (tmpp) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, tmpp, __len); __retval; })) : __strdup (tmpp)))), SWITCH_XML_TXTM); |
1060 | } |
1061 | |
1062 | |
1063 | |
1064 | |
1065 | /** ok so this is in the rfc but not the xsd |
1066 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "joining-method", off3++))) { |
1067 | abort(); |
1068 | } |
1069 | switch_xml_set_txt_d(x_tag3, np->cp->direction == SWITCH_CALL_DIRECTION_INBOUND ? "dialed-in" : "dialed-out"); |
1070 | */ |
1071 | |
1072 | if (np->member) { |
1073 | const char *var; |
1074 | //char buf[1024]; |
1075 | |
1076 | //switch_snprintf(buf, sizeof(buf), "conf_%s_%s_%s", conference->name, conference->domain, np->cp->caller_id_number); |
1077 | //switch_channel_set_variable(channel, "conference_call_key", buf); |
1078 | |
1079 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "media", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("media") && ((size_t)(const void *)(("media") + 1) - (size_t)(const void *)("media") == 1) ? ( ((const char *) ("media"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("media") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "media", __len); __retval ; })) : __strdup ("media"))), off3++), SWITCH_XML_NAMEM))) { |
1080 | abort(); |
1081 | } |
1082 | |
1083 | snprintf(tmp, sizeof(tmp), "%ua", np->member->id); |
1084 | switch_xml_set_attr_d(x_tag3, "id", tmpp)switch_xml_set_attr(switch_xml_set_flag(x_tag3, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("id") && ((size_t )(const void *)(("id") + 1) - (size_t)(const void *)("id") == 1) ? (((const char *) ("id"))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("id") + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, "id", __len) ; __retval; })) : __strdup ("id"))), (__extension__ (__builtin_constant_p ((tmpp ? tmpp : "")) && ((size_t)(const void *)(((tmpp ? tmpp : "")) + 1) - (size_t)(const void *)((tmpp ? tmpp : "" )) == 1) ? (((const char *) ((tmpp ? tmpp : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((tmpp ? tmpp : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (tmpp ? tmpp : ""), __len); __retval; })) : __strdup ((tmpp ? tmpp : ""))))); |
1085 | |
1086 | |
1087 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "type", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("type") && ((size_t)(const void *)(("type") + 1) - (size_t)(const void *)("type") == 1) ? (( (const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "type", __len); __retval ; })) : __strdup ("type"))), off4++), SWITCH_XML_NAMEM))) { |
1088 | abort(); |
1089 | } |
1090 | switch_xml_set_txt_d(x_tag4, "audio")switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p ("audio") && ((size_t)(const void *)(("audio") + 1) - (size_t)(const void *)("audio") == 1) ? ( ((const char *) ("audio"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("audio") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "audio", __len); __retval ; })) : __strdup ("audio")))), SWITCH_XML_TXTM); |
1091 | |
1092 | if ((var = switch_channel_get_variable(channel, "rtp_use_ssrc")switch_channel_get_variable_dup(channel, "rtp_use_ssrc", SWITCH_TRUE , -1))) { |
1093 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "src-id", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("src-id") && ((size_t)(const void *)(("src-id") + 1) - (size_t)(const void *)("src-id") == 1) ? (((const char *) ("src-id"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("src-id") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "src-id", __len ); __retval; })) : __strdup ("src-id"))), off4++), SWITCH_XML_NAMEM ))) { |
1094 | abort(); |
1095 | } |
1096 | switch_xml_set_txt_d(x_tag4, var)switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (var) && ((size_t)(const void * )((var) + 1) - (size_t)(const void *)(var) == 1) ? (((const char *) (var))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (var) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, var, __len); __retval; })) : __strdup ( var)))), SWITCH_XML_TXTM); |
1097 | } |
1098 | |
1099 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "status", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("status") && ((size_t)(const void *)(("status") + 1) - (size_t)(const void *)("status") == 1) ? (((const char *) ("status"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("status") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "status", __len ); __retval; })) : __strdup ("status"))), off4++), SWITCH_XML_NAMEM ))) { |
1100 | abort(); |
1101 | } |
1102 | switch_xml_set_txt_d(x_tag4, audio_flow(np->member))switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (audio_flow(np->member)) && ((size_t)(const void *)((audio_flow(np->member)) + 1) - ( size_t)(const void *)(audio_flow(np->member)) == 1) ? (((const char *) (audio_flow(np->member)))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (audio_flow (np->member)) + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , audio_flow(np->member), __len); __retval; })) : __strdup (audio_flow(np->member))))), SWITCH_XML_TXTM); |
1103 | |
1104 | |
1105 | if (switch_channel_test_flag(channel, CF_VIDEO)) { |
1106 | off4 = 0; |
1107 | |
1108 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "media", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("media") && ((size_t)(const void *)(("media") + 1) - (size_t)(const void *)("media") == 1) ? ( ((const char *) ("media"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("media") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "media", __len); __retval ; })) : __strdup ("media"))), off3++), SWITCH_XML_NAMEM))) { |
1109 | abort(); |
1110 | } |
1111 | |
1112 | snprintf(tmp, sizeof(tmp), "%uv", np->member->id); |
1113 | switch_xml_set_attr_d(x_tag3, "id", tmpp)switch_xml_set_attr(switch_xml_set_flag(x_tag3, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("id") && ((size_t )(const void *)(("id") + 1) - (size_t)(const void *)("id") == 1) ? (((const char *) ("id"))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("id") + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, "id", __len) ; __retval; })) : __strdup ("id"))), (__extension__ (__builtin_constant_p ((tmpp ? tmpp : "")) && ((size_t)(const void *)(((tmpp ? tmpp : "")) + 1) - (size_t)(const void *)((tmpp ? tmpp : "" )) == 1) ? (((const char *) ((tmpp ? tmpp : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((tmpp ? tmpp : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (tmpp ? tmpp : ""), __len); __retval; })) : __strdup ((tmpp ? tmpp : ""))))); |
1114 | |
1115 | |
1116 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "type", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("type") && ((size_t)(const void *)(("type") + 1) - (size_t)(const void *)("type") == 1) ? (( (const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "type", __len); __retval ; })) : __strdup ("type"))), off4++), SWITCH_XML_NAMEM))) { |
1117 | abort(); |
1118 | } |
1119 | switch_xml_set_txt_d(x_tag4, "video")switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p ("video") && ((size_t)(const void *)(("video") + 1) - (size_t)(const void *)("video") == 1) ? ( ((const char *) ("video"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("video") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "video", __len); __retval ; })) : __strdup ("video")))), SWITCH_XML_TXTM); |
1120 | |
1121 | if ((var = switch_channel_get_variable(channel, "rtp_use_video_ssrc")switch_channel_get_variable_dup(channel, "rtp_use_video_ssrc" , SWITCH_TRUE, -1))) { |
1122 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "src-id", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("src-id") && ((size_t)(const void *)(("src-id") + 1) - (size_t)(const void *)("src-id") == 1) ? (((const char *) ("src-id"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("src-id") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "src-id", __len ); __retval; })) : __strdup ("src-id"))), off4++), SWITCH_XML_NAMEM ))) { |
1123 | abort(); |
1124 | } |
1125 | switch_xml_set_txt_d(x_tag4, var)switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (var) && ((size_t)(const void * )((var) + 1) - (size_t)(const void *)(var) == 1) ? (((const char *) (var))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (var) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, var, __len); __retval; })) : __strdup ( var)))), SWITCH_XML_TXTM); |
1126 | } |
1127 | |
1128 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "status", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("status") && ((size_t)(const void *)(("status") + 1) - (size_t)(const void *)("status") == 1) ? (((const char *) ("status"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("status") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "status", __len ); __retval; })) : __strdup ("status"))), off4++), SWITCH_XML_NAMEM ))) { |
1129 | abort(); |
1130 | } |
1131 | switch_xml_set_txt_d(x_tag4, switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv")switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (switch_channel_test_flag(channel, CF_HOLD ) ? "sendonly" : "sendrecv") && ((size_t)(const void * )((switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv" ) + 1) - (size_t)(const void *)(switch_channel_test_flag(channel , CF_HOLD) ? "sendonly" : "sendrecv") == 1) ? (((const char * ) (switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (switch_channel_test_flag(channel, CF_HOLD ) ? "sendonly" : "sendrecv") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv", __len); __retval; })) : __strdup (switch_channel_test_flag (channel, CF_HOLD) ? "sendonly" : "sendrecv")))), SWITCH_XML_TXTM ); |
1132 | |
1133 | } |
1134 | } |
1135 | |
1136 | switch_safe_free(user_uri)if (user_uri) {free(user_uri);user_uri=((void*)0);}; |
1137 | } |
1138 | |
1139 | switch_mutex_unlock(conference->member_mutex); |
1140 | |
1141 | off1 = off2 = off3 = off4 = 0; |
1142 | |
1143 | xml_text = switch_xml_toxml(xml, SWITCH_TRUE); |
1144 | switch_xml_free(xml); |
1145 | |
1146 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
1147 | switch_safe_free(uri)if (uri) {free(uri);uri=((void*)0);}; |
1148 | |
1149 | return xml_text; |
1150 | } |
1151 | |
1152 | static void conference_cdr_render(conference_obj_t *conference) |
1153 | { |
1154 | switch_xml_t cdr, x_ptr, x_member, x_members, x_conference, x_cp, x_flags, x_tag, x_rejected, x_attempt; |
1155 | conference_cdr_node_t *np; |
1156 | conference_cdr_reject_t *rp; |
1157 | int cdr_off = 0, conf_off = 0; |
1158 | char str[512]; |
1159 | char *path = NULL((void*)0), *xml_text; |
1160 | int fd; |
1161 | |
1162 | if (zstr(conference->log_dir)_zstr(conference->log_dir) && (conference->cdr_event_mode == CDRE_NONE)) return; |
1163 | |
1164 | if (!conference->cdr_nodes && !conference->cdr_rejected) return; |
1165 | |
1166 | if (!(cdr = switch_xml_new("cdr"))) { |
1167 | abort(); |
1168 | } |
1169 | |
1170 | if (!(x_conference = switch_xml_add_child_d(cdr, "conference", cdr_off++)switch_xml_set_flag(switch_xml_add_child(cdr, (__extension__ ( __builtin_constant_p ("conference") && ((size_t)(const void *)(("conference") + 1) - (size_t)(const void *)("conference" ) == 1) ? (((const char *) ("conference"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "conference", __len); __retval; })) : __strdup ("conference" ))), cdr_off++), SWITCH_XML_NAMEM))) { |
1171 | abort(); |
1172 | } |
1173 | |
1174 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "name", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("name") && ((size_t)(const void *)(("name") + 1) - (size_t)(const void *)("name") == 1) ? (( (const char *) ("name"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("name") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "name", __len); __retval ; })) : __strdup ("name"))), conf_off++), SWITCH_XML_NAMEM))) { |
1175 | abort(); |
1176 | } |
1177 | switch_xml_set_txt_d(x_ptr, conference->name)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (conference->name) && ((size_t )(const void *)((conference->name) + 1) - (size_t)(const void *)(conference->name) == 1) ? (((const char *) (conference ->name))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (conference->name) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, conference->name , __len); __retval; })) : __strdup (conference->name)))), SWITCH_XML_TXTM ); |
1178 | |
1179 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "hostname", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("hostname") && ((size_t)(const void *)(("hostname") + 1) - (size_t)(const void *)("hostname" ) == 1) ? (((const char *) ("hostname"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "hostname") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "hostname", __len); __retval; })) : __strdup ("hostname"))) , conf_off++), SWITCH_XML_NAMEM))) { |
1180 | abort(); |
1181 | } |
1182 | switch_xml_set_txt_d(x_ptr, switch_core_get_hostname())switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (switch_core_get_hostname()) && ( (size_t)(const void *)((switch_core_get_hostname()) + 1) - (size_t )(const void *)(switch_core_get_hostname()) == 1) ? (((const char *) (switch_core_get_hostname()))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (switch_core_get_hostname ()) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, switch_core_get_hostname (), __len); __retval; })) : __strdup (switch_core_get_hostname ())))), SWITCH_XML_TXTM); |
1183 | |
1184 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "rate", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("rate") && ((size_t)(const void *)(("rate") + 1) - (size_t)(const void *)("rate") == 1) ? (( (const char *) ("rate"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("rate") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "rate", __len); __retval ; })) : __strdup ("rate"))), conf_off++), SWITCH_XML_NAMEM))) { |
1185 | abort(); |
1186 | } |
1187 | switch_snprintf(str, sizeof(str), "%d", conference->rate); |
1188 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
1189 | |
1190 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "interval", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("interval") && ((size_t)(const void *)(("interval") + 1) - (size_t)(const void *)("interval" ) == 1) ? (((const char *) ("interval"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "interval") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "interval", __len); __retval; })) : __strdup ("interval"))) , conf_off++), SWITCH_XML_NAMEM))) { |
1191 | abort(); |
1192 | } |
1193 | switch_snprintf(str, sizeof(str), "%d", conference->interval); |
1194 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
1195 | |
1196 | |
1197 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "start_time", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("start_time") && ((size_t)(const void *)(("start_time") + 1) - (size_t)(const void *)("start_time" ) == 1) ? (((const char *) ("start_time"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("start_time") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "start_time", __len); __retval; })) : __strdup ("start_time" ))), conf_off++), SWITCH_XML_NAMEM))) { |
1198 | abort(); |
1199 | } |
1200 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
1201 | switch_snprintf(str, sizeof(str), "%ld", (long)conference->start_time); |
1202 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
1203 | |
1204 | |
1205 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "end_time", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("end_time") && ((size_t)(const void *)(("end_time") + 1) - (size_t)(const void *)("end_time" ) == 1) ? (((const char *) ("end_time"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "end_time") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "end_time", __len); __retval; })) : __strdup ("end_time"))) , conf_off++), SWITCH_XML_NAMEM))) { |
1206 | abort(); |
1207 | } |
1208 | switch_xml_set_attr_d(x_ptr, "endconf_forced", switch_test_flag(conference, CFLAG_ENDCONF_FORCED) ? "true" : "false")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("endconf_forced") && ((size_t)(const void *)(("endconf_forced") + 1) - (size_t)(const void *)("endconf_forced") == 1) ? (((const char *) ("endconf_forced" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("endconf_forced") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "endconf_forced", __len); __retval ; })) : __strdup ("endconf_forced"))), (__extension__ (__builtin_constant_p ((((conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : "")) && ((size_t)(const void * )(((((conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : "")) + 1) - (size_t)(const void *)(((( conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" : "")) == 1) ? (((const char *) ((((conference)-> flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference )->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" : "" )))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ( { size_t __len = strlen ((((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : ""), __len); __retval; })) : __strdup ( (((conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : ""))))); |
1209 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
1210 | switch_snprintf(str, sizeof(str), "%ld", (long)conference->end_time); |
1211 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
1212 | |
1213 | |
1214 | |
1215 | if (!(x_members = switch_xml_add_child_d(x_conference, "members", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("members") && ((size_t)(const void *)(("members") + 1) - (size_t)(const void *)("members") == 1) ? (((const char *) ("members"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("members" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "members" , __len); __retval; })) : __strdup ("members"))), conf_off++) , SWITCH_XML_NAMEM))) { |
1216 | abort(); |
1217 | } |
1218 | |
1219 | for (np = conference->cdr_nodes; np; np = np->next) { |
1220 | int member_off = 0; |
1221 | int flag_off = 0; |
1222 | |
1223 | |
1224 | if (!(x_member = switch_xml_add_child_d(x_members, "member", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_members, (__extension__ (__builtin_constant_p ("member") && ((size_t)(const void *)(("member") + 1) - (size_t)(const void *)("member") == 1) ? (((const char *) ("member"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("member") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "member", __len ); __retval; })) : __strdup ("member"))), conf_off++), SWITCH_XML_NAMEM ))) { |
1225 | abort(); |
1226 | } |
1227 | |
1228 | switch_xml_set_attr_d(x_member, "type", np->cp ? "caller" : "recording_node")switch_xml_set_attr(switch_xml_set_flag(x_member, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p ((np->cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : "")) && ( (size_t)(const void *)(((np->cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : "")) + 1) - (size_t )(const void *)((np->cp ? "caller" : "recording_node" ? np ->cp ? "caller" : "recording_node" : "")) == 1) ? (((const char *) ((np->cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((np-> cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (np-> cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : ""), __len); __retval; })) : __strdup ((np->cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : ""))))); |
1229 | |
1230 | if (!(x_ptr = switch_xml_add_child_d(x_member, "join_time", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("join_time") && ((size_t)(const void *)(("join_time") + 1) - (size_t)(const void *)("join_time" ) == 1) ? (((const char *) ("join_time"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "join_time") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "join_time", __len); __retval; })) : __strdup ("join_time") )), member_off++), SWITCH_XML_NAMEM))) { |
1231 | abort(); |
1232 | } |
1233 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
1234 | switch_snprintf(str, sizeof(str), "%ld", (long) np->join_time); |
1235 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
1236 | |
1237 | |
1238 | if (!(x_ptr = switch_xml_add_child_d(x_member, "leave_time", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("leave_time") && ((size_t)(const void *)(("leave_time") + 1) - (size_t)(const void *)("leave_time" ) == 1) ? (((const char *) ("leave_time"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("leave_time") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "leave_time", __len); __retval; })) : __strdup ("leave_time" ))), member_off++), SWITCH_XML_NAMEM))) { |
1239 | abort(); |
1240 | } |
1241 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
1242 | switch_snprintf(str, sizeof(str), "%ld", (long) np->leave_time); |
1243 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
1244 | |
1245 | if (np->cp) { |
1246 | x_flags = switch_xml_add_child_d(x_member, "flags", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("flags") && ((size_t)(const void *)(("flags") + 1) - (size_t)(const void *)("flags") == 1) ? ( ((const char *) ("flags"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("flags") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "flags", __len); __retval ; })) : __strdup ("flags"))), member_off++), SWITCH_XML_NAMEM ); |
1247 | switch_assert(x_flags)((x_flags) ? (void) (0) : __assert_fail ("x_flags", "mod_conference.c" , 1247, __PRETTY_FUNCTION__)); |
1248 | |
1249 | x_tag = switch_xml_add_child_d(x_flags, "is_moderator", flag_off++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("is_moderator") && ((size_t)( const void *)(("is_moderator") + 1) - (size_t)(const void *)( "is_moderator") == 1) ? (((const char *) ("is_moderator"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("is_moderator") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "is_moderator", __len); __retval; })) : __strdup ("is_moderator"))), flag_off++), SWITCH_XML_NAMEM); |
1250 | switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_MOD) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((np)->flags & MFLAG_MOD) ? "true" : "false") && ((size_t)(const void *)((((np)->flags & MFLAG_MOD) ? "true" : "false") + 1) - (size_t)(const void *)(((np)->flags & MFLAG_MOD) ? "true" : "false") == 1 ) ? (((const char *) (((np)->flags & MFLAG_MOD) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (((np)->flags & MFLAG_MOD ) ? "true" : "false") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((np)->flags & MFLAG_MOD) ? "true" : "false" , __len); __retval; })) : __strdup (((np)->flags & MFLAG_MOD ) ? "true" : "false")))), SWITCH_XML_TXTM); |
1251 | |
1252 | x_tag = switch_xml_add_child_d(x_flags, "end_conference", flag_off++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("end_conference") && ((size_t )(const void *)(("end_conference") + 1) - (size_t)(const void *)("end_conference") == 1) ? (((const char *) ("end_conference" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("end_conference") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "end_conference", __len); __retval ; })) : __strdup ("end_conference"))), flag_off++), SWITCH_XML_NAMEM ); |
1253 | switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_ENDCONF) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((np)->flags & MFLAG_ENDCONF) ? "true" : "false") && ((size_t)(const void *)((((np)->flags & MFLAG_ENDCONF) ? "true" : "false") + 1) - (size_t)(const void *)(((np)->flags & MFLAG_ENDCONF) ? "true" : "false" ) == 1) ? (((const char *) (((np)->flags & MFLAG_ENDCONF ) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((np)->flags & MFLAG_ENDCONF) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((np)->flags & MFLAG_ENDCONF) ? "true" : "false", __len); __retval; })) : __strdup (((np)->flags & MFLAG_ENDCONF) ? "true" : "false")))), SWITCH_XML_TXTM ); |
1254 | |
1255 | x_tag = switch_xml_add_child_d(x_flags, "was_kicked", flag_off++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("was_kicked") && ((size_t)(const void *)(("was_kicked") + 1) - (size_t)(const void *)("was_kicked" ) == 1) ? (((const char *) ("was_kicked"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("was_kicked") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "was_kicked", __len); __retval; })) : __strdup ("was_kicked" ))), flag_off++), SWITCH_XML_NAMEM); |
1256 | switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_KICKED) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((np)->flags & MFLAG_KICKED) ? "true" : "false") && ((size_t)(const void *)((((np)->flags & MFLAG_KICKED) ? "true" : "false") + 1) - (size_t)(const void *)(((np)->flags & MFLAG_KICKED) ? "true" : "false" ) == 1) ? (((const char *) (((np)->flags & MFLAG_KICKED ) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((np)->flags & MFLAG_KICKED) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((np)->flags & MFLAG_KICKED) ? "true" : "false", __len); __retval; })) : __strdup (((np)->flags & MFLAG_KICKED) ? "true" : "false")))), SWITCH_XML_TXTM); |
1257 | |
1258 | x_tag = switch_xml_add_child_d(x_flags, "is_ghost", flag_off++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("is_ghost") && ((size_t)(const void *)(("is_ghost") + 1) - (size_t)(const void *)("is_ghost" ) == 1) ? (((const char *) ("is_ghost"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "is_ghost") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "is_ghost", __len); __retval; })) : __strdup ("is_ghost"))) , flag_off++), SWITCH_XML_NAMEM); |
1259 | switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_GHOST) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((np)->flags & MFLAG_GHOST) ? "true" : "false") && ((size_t)(const void *)((((np)->flags & MFLAG_GHOST) ? "true" : "false") + 1) - (size_t)(const void *)(((np)->flags & MFLAG_GHOST) ? "true" : "false" ) == 1) ? (((const char *) (((np)->flags & MFLAG_GHOST ) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((np)->flags & MFLAG_GHOST) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((np)->flags & MFLAG_GHOST) ? "true" : "false", __len); __retval; })) : __strdup (((np)->flags & MFLAG_GHOST) ? "true" : "false")))), SWITCH_XML_TXTM); |
1260 | |
1261 | if (!(x_cp = switch_xml_add_child_d(x_member, "caller_profile", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("caller_profile") && ((size_t )(const void *)(("caller_profile") + 1) - (size_t)(const void *)("caller_profile") == 1) ? (((const char *) ("caller_profile" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("caller_profile") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "caller_profile", __len); __retval ; })) : __strdup ("caller_profile"))), member_off++), SWITCH_XML_NAMEM ))) { |
1262 | abort(); |
1263 | } |
1264 | switch_ivr_set_xml_profile_data(x_cp, np->cp, 0); |
1265 | } |
1266 | |
1267 | if (!zstr(np->record_path)_zstr(np->record_path)) { |
1268 | if (!(x_ptr = switch_xml_add_child_d(x_member, "record_path", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("record_path") && ((size_t)(const void *)(("record_path") + 1) - (size_t)(const void *)("record_path" ) == 1) ? (((const char *) ("record_path"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("record_path") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "record_path", __len); __retval; })) : __strdup ("record_path" ))), member_off++), SWITCH_XML_NAMEM))) { |
1269 | abort(); |
1270 | } |
1271 | switch_xml_set_txt_d(x_ptr, np->record_path)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (np->record_path) && ((size_t )(const void *)((np->record_path) + 1) - (size_t)(const void *)(np->record_path) == 1) ? (((const char *) (np->record_path ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (np->record_path) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, np->record_path, __len); __retval ; })) : __strdup (np->record_path)))), SWITCH_XML_TXTM); |
1272 | } |
1273 | |
1274 | |
1275 | } |
1276 | |
1277 | if (!(x_rejected = switch_xml_add_child_d(x_conference, "rejected", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("rejected") && ((size_t)(const void *)(("rejected") + 1) - (size_t)(const void *)("rejected" ) == 1) ? (((const char *) ("rejected"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "rejected") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "rejected", __len); __retval; })) : __strdup ("rejected"))) , conf_off++), SWITCH_XML_NAMEM))) { |
1278 | abort(); |
1279 | } |
1280 | |
1281 | for (rp = conference->cdr_rejected; rp; rp = rp->next) { |
1282 | int attempt_off = 0; |
1283 | int tag_off = 0; |
1284 | |
1285 | if (!(x_attempt = switch_xml_add_child_d(x_rejected, "attempt", attempt_off++)switch_xml_set_flag(switch_xml_add_child(x_rejected, (__extension__ (__builtin_constant_p ("attempt") && ((size_t)(const void *)(("attempt") + 1) - (size_t)(const void *)("attempt") == 1) ? (((const char *) ("attempt"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("attempt" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "attempt" , __len); __retval; })) : __strdup ("attempt"))), attempt_off ++), SWITCH_XML_NAMEM))) { |
1286 | abort(); |
1287 | } |
1288 | |
1289 | if (!(x_ptr = switch_xml_add_child_d(x_attempt, "reason", tag_off++)switch_xml_set_flag(switch_xml_add_child(x_attempt, (__extension__ (__builtin_constant_p ("reason") && ((size_t)(const void *)(("reason") + 1) - (size_t)(const void *)("reason") == 1) ? (((const char *) ("reason"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("reason") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "reason", __len ); __retval; })) : __strdup ("reason"))), tag_off++), SWITCH_XML_NAMEM ))) { |
1290 | abort(); |
1291 | } |
1292 | if (rp->reason == CDRR_LOCKED) { |
1293 | switch_xml_set_txt_d(x_ptr, "conference_locked")switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p ("conference_locked") && ((size_t )(const void *)(("conference_locked") + 1) - (size_t)(const void *)("conference_locked") == 1) ? (((const char *) ("conference_locked" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference_locked") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "conference_locked", __len); __retval ; })) : __strdup ("conference_locked")))), SWITCH_XML_TXTM); |
1294 | } else if (rp->reason == CDRR_MAXMEMBERS) { |
1295 | switch_xml_set_txt_d(x_ptr, "max_members_reached")switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p ("max_members_reached") && ((size_t )(const void *)(("max_members_reached") + 1) - (size_t)(const void *)("max_members_reached") == 1) ? (((const char *) ("max_members_reached" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("max_members_reached") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "max_members_reached", __len); __retval ; })) : __strdup ("max_members_reached")))), SWITCH_XML_TXTM); |
1296 | } else if (rp->reason == CDRR_PIN) { |
1297 | switch_xml_set_txt_d(x_ptr, "invalid_pin")switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p ("invalid_pin") && ((size_t)(const void *)(("invalid_pin") + 1) - (size_t)(const void *)("invalid_pin" ) == 1) ? (((const char *) ("invalid_pin"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("invalid_pin") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "invalid_pin", __len); __retval; })) : __strdup ("invalid_pin" )))), SWITCH_XML_TXTM); |
1298 | } |
1299 | |
1300 | if (!(x_ptr = switch_xml_add_child_d(x_attempt, "reject_time", tag_off++)switch_xml_set_flag(switch_xml_add_child(x_attempt, (__extension__ (__builtin_constant_p ("reject_time") && ((size_t)(const void *)(("reject_time") + 1) - (size_t)(const void *)("reject_time" ) == 1) ? (((const char *) ("reject_time"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("reject_time") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "reject_time", __len); __retval; })) : __strdup ("reject_time" ))), tag_off++), SWITCH_XML_NAMEM))) { |
1301 | abort(); |
1302 | } |
1303 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
1304 | switch_snprintf(str, sizeof(str), "%ld", (long) rp->reject_time); |
1305 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
1306 | |
1307 | if (rp->cp) { |
1308 | if (!(x_cp = switch_xml_add_child_d(x_attempt, "caller_profile", attempt_off++)switch_xml_set_flag(switch_xml_add_child(x_attempt, (__extension__ (__builtin_constant_p ("caller_profile") && ((size_t )(const void *)(("caller_profile") + 1) - (size_t)(const void *)("caller_profile") == 1) ? (((const char *) ("caller_profile" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("caller_profile") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "caller_profile", __len); __retval ; })) : __strdup ("caller_profile"))), attempt_off++), SWITCH_XML_NAMEM ))) { |
1309 | abort(); |
1310 | } |
1311 | switch_ivr_set_xml_profile_data(x_cp, rp->cp, 0); |
1312 | } |
1313 | } |
1314 | |
1315 | xml_text = switch_xml_toxml(cdr, SWITCH_TRUE); |
1316 | |
1317 | |
1318 | if (!zstr(conference->log_dir)_zstr(conference->log_dir)) { |
1319 | path = switch_mprintf("%s%s%s.cdr.xml", conference->log_dir, SWITCH_PATH_SEPARATOR"/", conference->uuid_str); |
1320 | |
1321 | |
1322 | |
1323 | #ifdef _MSC_VER |
1324 | if ((fd = open(path, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, S_IRUSR0400 | S_IWUSR0200)) > -1) { |
1325 | #else |
1326 | if ((fd = open(path, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, S_IRUSR0400 | S_IWUSR0200 | S_IRGRP(0400 >> 3) | S_IWGRP(0200 >> 3) | S_IROTH((0400 >> 3) >> 3) | S_IWOTH((0200 >> 3) >> 3))) > -1) { |
1327 | #endif |
1328 | int wrote; |
1329 | wrote = write(fd, xml_text, (unsigned) strlen(xml_text)); |
1330 | wrote++; |
1331 | close(fd); |
1332 | fd = -1; |
1333 | } else { |
1334 | char ebuf[512] = { 0 }; |
1335 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 1335, ((void*)0), SWITCH_LOG_ERROR, "Error writing [%s][%s]\n", |
1336 | path, switch_strerror_r(errno(*__errno_location ()), ebuf, sizeof(ebuf))); |
1337 | } |
1338 | |
1339 | if (conference->cdr_event_mode != CDRE_NONE) { |
1340 | switch_event_t *event; |
1341 | |
1342 | if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_CDR)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 1342, &event, SWITCH_EVENT_CUSTOM , "conference::cdr") == SWITCH_STATUS_SUCCESS) |
1343 | // if (switch_event_create(&event, SWITCH_EVENT_CDR) == SWITCH_STATUS_SUCCESS) |
1344 | { |
1345 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Source", CONF_EVENT_CDR"conference::cdr"); |
1346 | if (conference->cdr_event_mode == CDRE_AS_CONTENT) { |
1347 | switch_event_set_body(event, xml_text); |
1348 | } else { |
1349 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Path", path); |
1350 | } |
1351 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 1351, &event, ((void*)0)); |
1352 | } else { |
1353 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 1353, ((void*)0), SWITCH_LOG_ERROR, "Could not create CDR event"); |
1354 | } |
1355 | } |
1356 | } |
1357 | |
1358 | switch_safe_free(path)if (path) {free(path);path=((void*)0);}; |
1359 | switch_safe_free(xml_text)if (xml_text) {free(xml_text);xml_text=((void*)0);}; |
1360 | switch_xml_free(cdr); |
1361 | } |
1362 | |
1363 | static cJSON *conference_json_render(conference_obj_t *conference, cJSON *req) |
1364 | { |
1365 | char tmp[30]; |
1366 | const char *domain; const char *name; |
1367 | char *dup_domain = NULL((void*)0); |
1368 | char *uri; |
1369 | conference_cdr_node_t *np; |
1370 | char *tmpp = tmp; |
1371 | cJSON *json = cJSON_CreateObject(), *jusers = NULL((void*)0), *jold_users = NULL((void*)0), *juser = NULL((void*)0), *jvars = NULL((void*)0); |
1372 | |
1373 | switch_assert(json)((json) ? (void) (0) : __assert_fail ("json", "mod_conference.c" , 1373, __PRETTY_FUNCTION__)); |
1374 | |
1375 | switch_mutex_lock(conference->mutex); |
1376 | switch_snprintf(tmp, sizeof(tmp), "%u", conference->doc_version); |
1377 | conference->doc_version++; |
1378 | switch_mutex_unlock(conference->mutex); |
1379 | |
1380 | if (!(name = conference->name)) { |
1381 | name = "conference"; |
1382 | } |
1383 | |
1384 | if (!(domain = conference->domain)) { |
1385 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
1386 | if (!(domain = dup_domain)) { |
1387 | domain = "cluecon.com"; |
1388 | } |
1389 | } |
1390 | |
1391 | |
1392 | uri = switch_mprintf("%s@%s", name, domain); |
1393 | json_add_child_string(json, "entity", uri); |
1394 | json_add_child_string(json, "conferenceDescription", conference->desc ? conference->desc : "FreeSWITCH Conference"); |
1395 | json_add_child_string(json, "conferenceState", "active"); |
1396 | switch_snprintf(tmp, sizeof(tmp), "%u", conference->count); |
1397 | json_add_child_string(json, "userCount", tmp); |
1398 | |
1399 | jusers = json_add_child_array(json, "users"); |
1400 | jold_users = json_add_child_array(json, "oldUsers"); |
1401 | |
1402 | switch_mutex_lock(conference->member_mutex); |
1403 | |
1404 | for (np = conference->cdr_nodes; np; np = np->next) { |
1405 | char *user_uri = NULL((void*)0); |
1406 | switch_channel_t *channel = NULL((void*)0); |
1407 | switch_time_exp_t tm; |
1408 | switch_size_t retsize; |
1409 | const char *fmt = "%Y-%m-%dT%H:%M:%S%z"; |
1410 | char *p; |
1411 | |
1412 | if (np->record_path || !np->cp) { |
1413 | continue; |
1414 | } |
1415 | |
1416 | //if (!np->cp || (np->member && !np->member->session) || np->leave_time) { /* for now we'll remove participants when they leave */ |
1417 | //continue; |
1418 | //} |
1419 | |
1420 | if (np->member && np->member->session) { |
1421 | channel = switch_core_session_get_channel(np->member->session); |
1422 | } |
1423 | |
1424 | juser = cJSON_CreateObject(); |
1425 | |
1426 | if (channel) { |
1427 | const char *uri = switch_channel_get_variable_dup(channel, "conference_invite_uri", SWITCH_FALSE, -1); |
1428 | |
1429 | if (uri) { |
1430 | user_uri = strdup(uri)(__extension__ (__builtin_constant_p (uri) && ((size_t )(const void *)((uri) + 1) - (size_t)(const void *)(uri) == 1 ) ? (((const char *) (uri))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (uri) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, uri, __len); __retval ; })) : __strdup (uri))); |
1431 | } |
1432 | } |
1433 | |
1434 | if (np->cp) { |
1435 | |
1436 | if (!user_uri) { |
1437 | user_uri = switch_mprintf("%s@%s", np->cp->caller_id_number, domain); |
1438 | } |
1439 | |
1440 | json_add_child_string(juser, "entity", user_uri); |
1441 | json_add_child_string(juser, "displayText", np->cp->caller_id_name); |
1442 | } |
1443 | |
1444 | //if (np->record_path) { |
1445 | //json_add_child_string(juser, "recordingPATH", np->record_path); |
1446 | //} |
1447 | |
1448 | json_add_child_string(juser, "status", np->leave_time ? "disconnected" : "connected"); |
1449 | |
1450 | switch_time_exp_lt(&tm, (switch_time_t) conference->start_time * 1000000); |
1451 | switch_strftime_nocheck(tmp, &retsize, sizeof(tmp), fmt, &tm); |
1452 | p = end_of_p(tmpp)(*tmpp == '\0' ? tmpp : tmpp + strlen(tmpp) - 1) -1; |
1453 | snprintf(p, 4, ":00"); |
1454 | |
1455 | json_add_child_string(juser, "joinTime", tmpp); |
1456 | |
1457 | snprintf(tmp, sizeof(tmp), "%u", np->id); |
1458 | json_add_child_string(juser, "memberId", tmp); |
1459 | |
1460 | jvars = cJSON_CreateObject(); |
1461 | |
1462 | if (!np->member && np->var_event) { |
1463 | switch_json_add_presence_data_cols(np->var_event, jvars, "PD-"); |
1464 | } else if (np->member) { |
1465 | const char *var; |
1466 | const char *prefix = NULL((void*)0); |
1467 | switch_event_t *var_event = NULL((void*)0); |
1468 | switch_event_header_t *hp; |
1469 | int all = 0; |
1470 | |
1471 | switch_channel_get_variables(channel, &var_event); |
1472 | |
1473 | if ((prefix = switch_event_get_header(var_event, "json_conf_var_prefix")switch_event_get_header_idx(var_event, "json_conf_var_prefix" , -1))) { |
1474 | all = strcasecmp(prefix, "__all__"); |
1475 | } else { |
1476 | prefix = "json_"; |
1477 | } |
1478 | |
1479 | for(hp = var_event->headers; hp; hp = hp->next) { |
1480 | if (all || !strncasecmp(hp->name, prefix, strlen(prefix))) { |
1481 | json_add_child_string(jvars, hp->name, hp->value); |
1482 | } |
1483 | } |
1484 | |
1485 | switch_json_add_presence_data_cols(var_event, jvars, "PD-"); |
1486 | |
1487 | switch_event_destroy(&var_event); |
1488 | |
1489 | if ((var = switch_channel_get_variable(channel, "rtp_use_ssrc")switch_channel_get_variable_dup(channel, "rtp_use_ssrc", SWITCH_TRUE , -1))) { |
1490 | json_add_child_string(juser, "rtpAudioSSRC", var); |
1491 | } |
1492 | |
1493 | json_add_child_string(juser, "rtpAudioDirection", audio_flow(np->member)); |
1494 | |
1495 | |
1496 | if (switch_channel_test_flag(channel, CF_VIDEO)) { |
1497 | if ((var = switch_channel_get_variable(channel, "rtp_use_video_ssrc")switch_channel_get_variable_dup(channel, "rtp_use_video_ssrc" , SWITCH_TRUE, -1))) { |
1498 | json_add_child_string(juser, "rtpVideoSSRC", var); |
1499 | } |
1500 | |
1501 | json_add_child_string(juser, "rtpVideoDirection", switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv"); |
1502 | } |
1503 | } |
1504 | |
1505 | if (jvars) { |
1506 | json_add_child_obj(juser, "variables", jvars); |
1507 | } |
1508 | |
1509 | cJSON_AddItemToArray(np->leave_time ? jold_users : jusers, juser); |
1510 | |
1511 | switch_safe_free(user_uri)if (user_uri) {free(user_uri);user_uri=((void*)0);}; |
1512 | } |
1513 | |
1514 | switch_mutex_unlock(conference->member_mutex); |
1515 | |
1516 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
1517 | switch_safe_free(uri)if (uri) {free(uri);uri=((void*)0);}; |
1518 | |
1519 | return json; |
1520 | } |
1521 | |
1522 | static void conference_mod_event_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id) |
1523 | { |
1524 | cJSON *data; |
1525 | const char *action = NULL((void*)0); |
1526 | char *value = NULL((void*)0); |
1527 | cJSON *jid = 0; |
1528 | char *conf_name = strdup(event_channel + 15)(__extension__ (__builtin_constant_p (event_channel + 15) && ((size_t)(const void *)((event_channel + 15) + 1) - (size_t) (const void *)(event_channel + 15) == 1) ? (((const char *) ( event_channel + 15))[0] == '\0' ? (char *) calloc ((size_t) 1 , (size_t) 1) : ({ size_t __len = strlen (event_channel + 15) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, event_channel + 15, __len); __retval; })) : __strdup (event_channel + 15)) ); |
1529 | int cid = 0; |
1530 | char *p; |
1531 | switch_stream_handle_t stream = { 0 }; |
1532 | char *exec = NULL((void*)0); |
1533 | cJSON *msg, *jdata, *jvalue; |
1534 | char *argv[10] = {0}; |
1535 | int argc = 0; |
1536 | |
1537 | if (conf_name && (p = strchr(conf_name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conf_name) && ('@') == '\0' ? (char *) __rawmemchr ( conf_name, '@') : __builtin_strchr (conf_name, '@'))))) { |
1538 | *p = '\0'; |
1539 | } |
1540 | |
1541 | if ((data = cJSON_GetObjectItem(json, "data"))) { |
1542 | action = cJSON_GetObjectCstr(data, "command"); |
1543 | if ((jid = cJSON_GetObjectItem(data, "id"))) { |
1544 | cid = jid->valueint; |
1545 | } |
1546 | |
1547 | if ((jvalue = cJSON_GetObjectItem(data, "value"))) { |
1548 | |
1549 | if (jvalue->type == cJSON_Array5) { |
1550 | int i; |
1551 | argc = cJSON_GetArraySize(jvalue); |
1552 | if (argc > 10) argc = 10; |
1553 | |
1554 | for (i = 0; i < argc; i++) { |
1555 | cJSON *str = cJSON_GetArrayItem(jvalue, i); |
1556 | if (str->type == cJSON_String4) { |
1557 | argv[i] = str->valuestring; |
1558 | } |
1559 | } |
1560 | } else if (jvalue->type == cJSON_String4) { |
1561 | value = jvalue->valuestring; |
1562 | argv[argc++] = value; |
1563 | } |
1564 | } |
1565 | } |
1566 | |
1567 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 1567, ((void*)0), SWITCH_LOG_ALERT, "conf %s CMD %s [%s] %d\n", conf_name, key, action, cid); |
1568 | |
1569 | if (zstr(action)_zstr(action)) { |
1570 | goto end; |
1571 | } |
1572 | |
1573 | SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc( 1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data" , "mod_conference.c", 1573, __PRETTY_FUNCTION__)); memset(stream .data, 0, 1024); stream.end = stream.data; stream.data_size = 1024; stream.write_function = switch_console_stream_write; stream .raw_write_function = switch_console_stream_raw_write; stream .alloc_len = 1024; stream.alloc_chunk = 1024; |
1574 | |
1575 | if (!strcasecmp(action, "kick") || !strcasecmp(action, "mute") || !strcasecmp(action, "unmute") || !strcasecmp(action, "tmute")) { |
1576 | exec = switch_mprintf("%s %s %d", conf_name, action, cid); |
1577 | } else if (!strcasecmp(action, "volume_in") || !strcasecmp(action, "volume_out")) { |
1578 | exec = switch_mprintf("%s %s %d %s", conf_name, action, cid, argv[0]); |
1579 | } else if (!strcasecmp(action, "play") || !strcasecmp(action, "stop")) { |
1580 | exec = switch_mprintf("%s %s %s", conf_name, action, argv[0]); |
1581 | } else if (!strcasecmp(action, "recording")) { |
1582 | if (!argv[1]) { |
1583 | argv[1] = "all"; |
1584 | } |
1585 | exec = switch_mprintf("%s %s %s %s", conf_name, action, argv[0], argv[1]); |
1586 | |
1587 | } else if (!strcasecmp(action, "transfer") && cid) { |
1588 | conference_member_t *member; |
1589 | conference_obj_t *conference; |
1590 | |
1591 | exec = switch_mprintf("%s %s %s", argv[0], switch_str_nil(argv[1])(argv[1] ? argv[1] : ""), switch_str_nil(argv[2])(argv[2] ? argv[2] : "")); |
1592 | stream.write_function(&stream, "+OK Call transferred to %s", argv[0]); |
1593 | |
1594 | if ((conference = conference_find(conf_name, NULL((void*)0)))) { |
1595 | if ((member = conference_member_get(conference, cid))) { |
1596 | switch_ivr_session_transfer(member->session, argv[0], argv[1], argv[2]); |
1597 | switch_thread_rwlock_unlock(member->rwlock); |
1598 | } |
1599 | switch_thread_rwlock_unlock(conference->rwlock); |
1600 | } |
1601 | goto end; |
1602 | } |
1603 | |
1604 | if (exec) { |
1605 | conf_api_main(exec, NULL((void*)0), &stream); |
1606 | } |
1607 | |
1608 | end: |
1609 | |
1610 | msg = cJSON_CreateObject(); |
1611 | jdata = json_add_child_obj(msg, "data", NULL((void*)0)); |
1612 | |
1613 | cJSON_AddItemToObject(msg, "eventChannel", cJSON_CreateString(event_channel)); |
1614 | cJSON_AddItemToObject(jdata, "action", cJSON_CreateString("response")); |
1615 | |
1616 | if (exec) { |
1617 | cJSON_AddItemToObject(jdata, "conf-command", cJSON_CreateString(exec)); |
1618 | cJSON_AddItemToObject(jdata, "response", cJSON_CreateString((char *)stream.data)); |
1619 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 1619, ((void*)0), SWITCH_LOG_ALERT,"RES [%s][%s]\n", exec, (char *)stream.data); |
1620 | } else { |
1621 | cJSON_AddItemToObject(jdata, "error", cJSON_CreateString("Invalid Command")); |
1622 | } |
1623 | |
1624 | switch_event_channel_broadcast(event_channel, &msg, __FILE__"mod_conference.c", globals.event_channel_id); |
1625 | |
1626 | |
1627 | switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);}; |
1628 | switch_safe_free(exec)if (exec) {free(exec);exec=((void*)0);}; |
1629 | |
1630 | switch_safe_free(conf_name)if (conf_name) {free(conf_name);conf_name=((void*)0);}; |
1631 | |
1632 | } |
1633 | |
1634 | static void conference_la_event_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id) |
1635 | { |
1636 | switch_live_array_parse_json(json, globals.event_channel_id); |
1637 | } |
1638 | |
1639 | static void conference_event_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id) |
1640 | { |
1641 | char *domain = NULL((void*)0), *name = NULL((void*)0); |
1642 | conference_obj_t *conference = NULL((void*)0); |
1643 | cJSON *data, *reply = NULL((void*)0), *conf_desc = NULL((void*)0); |
1644 | const char *action = NULL((void*)0); |
1645 | char *dup = NULL((void*)0); |
1646 | |
1647 | if ((data = cJSON_GetObjectItem(json, "data"))) { |
1648 | action = cJSON_GetObjectCstr(data, "action"); |
1649 | } |
1650 | |
1651 | if (!action) action = ""; |
1652 | |
1653 | reply = cJSON_Duplicate(json, 1); |
1654 | cJSON_DeleteItemFromObject(reply, "data"); |
1655 | |
1656 | if ((name = strchr(event_channel, '.')(__extension__ (__builtin_constant_p ('.') && !__builtin_constant_p (event_channel) && ('.') == '\0' ? (char *) __rawmemchr (event_channel, '.') : __builtin_strchr (event_channel, '.') )))) { |
1657 | dup = strdup(name + 1)(__extension__ (__builtin_constant_p (name + 1) && (( size_t)(const void *)((name + 1) + 1) - (size_t)(const void * )(name + 1) == 1) ? (((const char *) (name + 1))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (name + 1) + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , name + 1, __len); __retval; })) : __strdup (name + 1))); |
1658 | switch_assert(dup)((dup) ? (void) (0) : __assert_fail ("dup", "mod_conference.c" , 1658, __PRETTY_FUNCTION__)); |
1659 | name = dup; |
1660 | |
1661 | if ((domain = strchr(name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (name) && ('@') == '\0' ? (char *) __rawmemchr (name , '@') : __builtin_strchr (name, '@'))))) { |
1662 | *domain++ = '\0'; |
1663 | } |
1664 | } |
1665 | |
1666 | if (!strcasecmp(action, "bootstrap")) { |
1667 | if (!zstr(name)_zstr(name) && (conference = conference_find(name, domain))) { |
1668 | conf_desc = conference_json_render(conference, json); |
1669 | } else { |
1670 | conf_desc = cJSON_CreateObject(); |
1671 | json_add_child_string(conf_desc, "conferenceDescription", "FreeSWITCH Conference"); |
1672 | json_add_child_string(conf_desc, "conferenceState", "inactive"); |
1673 | json_add_child_array(conf_desc, "users"); |
1674 | json_add_child_array(conf_desc, "oldUsers"); |
1675 | } |
1676 | } else { |
1677 | conf_desc = cJSON_CreateObject(); |
1678 | json_add_child_string(conf_desc, "error", "Invalid action"); |
1679 | } |
1680 | |
1681 | json_add_child_string(conf_desc, "action", "conferenceDescription"); |
1682 | |
1683 | cJSON_AddItemToObject(reply, "data", conf_desc); |
1684 | |
1685 | switch_safe_free(dup)if (dup) {free(dup);dup=((void*)0);}; |
1686 | |
1687 | switch_event_channel_broadcast(event_channel, &reply, modname, globals.event_channel_id); |
1688 | } |
1689 | |
1690 | |
1691 | static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event) |
1692 | { |
1693 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
1694 | |
1695 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Name", conference->name); |
1696 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Size", "%u", conference->count); |
1697 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Ghosts", "%u", conference->count_ghosts); |
1698 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Profile-Name", conference->profile_name); |
1699 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Unique-ID", conference->uuid_str); |
1700 | |
1701 | return status; |
1702 | } |
1703 | |
1704 | static switch_status_t conference_add_event_member_data(conference_member_t *member, switch_event_t *event) |
1705 | { |
1706 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
1707 | |
1708 | if (!member) |
1709 | return status; |
1710 | |
1711 | if (member->conference) { |
1712 | status = conference_add_event_data(member->conference, event); |
1713 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Floor", "%s", (member == member->conference->floor_holder) ? "true" : "false" ); |
1714 | } |
1715 | |
1716 | if (member->session) { |
1717 | switch_channel_t *channel = switch_core_session_get_channel(member->session); |
1718 | |
1719 | if (member->verbose_events) { |
1720 | switch_channel_event_set_data(channel, event); |
1721 | } else { |
1722 | switch_channel_event_set_basic_data(channel, event); |
1723 | } |
1724 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Video", "%s", |
1725 | switch_channel_test_flag(switch_core_session_get_channel(member->session), CF_VIDEO) ? "true" : "false" ); |
1726 | |
1727 | } |
1728 | |
1729 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Hear", "%s", switch_test_flag(member, MFLAG_CAN_HEAR)((member)->flags & MFLAG_CAN_HEAR) ? "true" : "false" ); |
1730 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Speak", "%s", switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) ? "true" : "false" ); |
1731 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Talking", "%s", switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING) ? "true" : "false" ); |
1732 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Mute-Detect", "%s", switch_test_flag(member, MFLAG_MUTE_DETECT)((member)->flags & MFLAG_MUTE_DETECT) ? "true" : "false" ); |
1733 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id); |
1734 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Type", "%s", switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD) ? "moderator" : "member"); |
1735 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Ghost", "%s", switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST) ? "true" : "false"); |
1736 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Energy-Level", "%d", member->energy_level); |
1737 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Current-Energy", "%d", member->score); |
1738 | |
1739 | return status; |
1740 | } |
1741 | |
1742 | /* Return a Distinct ID # */ |
1743 | static uint32_t next_member_id(void) |
1744 | { |
1745 | uint32_t id; |
1746 | |
1747 | switch_mutex_lock(globals.id_mutex); |
1748 | id = ++globals.id_pool; |
1749 | switch_mutex_unlock(globals.id_mutex); |
1750 | |
1751 | return id; |
1752 | } |
1753 | |
1754 | /* if other_member has a relationship with member, produce it */ |
1755 | static conference_relationship_t *member_get_relationship(conference_member_t *member, conference_member_t *other_member) |
1756 | { |
1757 | conference_relationship_t *rel = NULL((void*)0), *global = NULL((void*)0); |
1758 | |
1759 | if (member == NULL((void*)0) || other_member == NULL((void*)0) || member->relationships == NULL((void*)0)) |
1760 | return NULL((void*)0); |
1761 | |
1762 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
1763 | lock_member(other_member)switch_mutex_lock(other_member->write_mutex); switch_mutex_lock (other_member->read_mutex); |
1764 | |
1765 | for (rel = member->relationships; rel; rel = rel->next) { |
1766 | if (rel->id == other_member->id) { |
1767 | break; |
1768 | } |
1769 | |
1770 | /* 0 matches everyone. (We will still test the others because a real match carries more clout) */ |
1771 | if (rel->id == 0) { |
1772 | global = rel; |
1773 | } |
1774 | } |
1775 | |
1776 | unlock_member(other_member)switch_mutex_unlock(other_member->read_mutex); switch_mutex_unlock (other_member->write_mutex); |
1777 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
1778 | |
1779 | return rel ? rel : global; |
1780 | } |
1781 | |
1782 | /* traverse the conference member list for the specified member id and return it's pointer */ |
1783 | static conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id) |
1784 | { |
1785 | conference_member_t *member = NULL((void*)0); |
1786 | |
1787 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 1787, __PRETTY_FUNCTION__)); |
1788 | if (!id) { |
1789 | return NULL((void*)0); |
1790 | } |
1791 | |
1792 | switch_mutex_lock(conference->member_mutex); |
1793 | for (member = conference->members; member; member = member->next) { |
1794 | |
1795 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
1796 | continue; |
1797 | } |
1798 | |
1799 | if (member->id == id) { |
1800 | break; |
1801 | } |
1802 | } |
1803 | |
1804 | if (member) { |
1805 | if (!switch_test_flag(member, MFLAG_INTREE)((member)->flags & MFLAG_INTREE) || |
1806 | switch_test_flag(member, MFLAG_KICKED)((member)->flags & MFLAG_KICKED) || |
1807 | (member->session && !switch_channel_up(switch_core_session_get_channel(member->session))(switch_channel_check_signal(switch_core_session_get_channel( member->session), SWITCH_TRUE) || switch_channel_get_state (switch_core_session_get_channel(member->session)) < CS_HANGUP ))) { |
1808 | |
1809 | /* member is kicked or hanging up so forget it */ |
1810 | member = NULL((void*)0); |
1811 | } |
1812 | } |
1813 | |
1814 | if (member) { |
1815 | if (switch_thread_rwlock_tryrdlock(member->rwlock) != SWITCH_STATUS_SUCCESS) { |
1816 | /* if you cant readlock it's way to late to do anything */ |
1817 | member = NULL((void*)0); |
1818 | } |
1819 | } |
1820 | |
1821 | switch_mutex_unlock(conference->member_mutex); |
1822 | |
1823 | return member; |
1824 | } |
1825 | |
1826 | /* stop the specified recording */ |
1827 | static switch_status_t conference_record_stop(conference_obj_t *conference, switch_stream_handle_t *stream, char *path) |
1828 | { |
1829 | conference_member_t *member = NULL((void*)0); |
1830 | int count = 0; |
1831 | |
1832 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 1832, __PRETTY_FUNCTION__)); |
1833 | switch_mutex_lock(conference->member_mutex); |
1834 | for (member = conference->members; member; member = member->next) { |
1835 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (path) && __builtin_constant_p (member->rec_path) && (__s1_len = __builtin_strlen (path), __s2_len = __builtin_strlen (member->rec_path), (!((size_t)(const void *)((path) + 1) - (size_t)(const void *)(path) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((member->rec_path) + 1) - (size_t )(const void *)(member->rec_path) == 1) || __s2_len >= 4 )) ? __builtin_strcmp (path, member->rec_path) : (__builtin_constant_p (path) && ((size_t)(const void *)((path) + 1) - (size_t )(const void *)(path) == 1) && (__s1_len = __builtin_strlen (path), __s1_len < 4) ? (__builtin_constant_p (member-> rec_path) && ((size_t)(const void *)((member->rec_path ) + 1) - (size_t)(const void *)(member->rec_path) == 1) ? __builtin_strcmp (path, member->rec_path) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (member-> rec_path); int __result = (((const unsigned char *) (const char *) (path))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( path))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( path))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (path ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( member->rec_path) && ((size_t)(const void *)((member ->rec_path) + 1) - (size_t)(const void *)(member->rec_path ) == 1) && (__s2_len = __builtin_strlen (member->rec_path ), __s2_len < 4) ? (__builtin_constant_p (path) && ((size_t)(const void *)((path) + 1) - (size_t)(const void *) (path) == 1) ? __builtin_strcmp (path, member->rec_path) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (path); int __result = (((const unsigned char *) (const char *) (member->rec_path))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = ( ((const unsigned char *) (const char *) (member->rec_path) )[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (member ->rec_path))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (member->rec_path))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (path, member->rec_path)))); }))) { |
1836 | if (!switch_test_flag(conference, CFLAG_CONF_RESTART_AUTO_RECORD)((conference)->flags & CFLAG_CONF_RESTART_AUTO_RECORD) && member->rec && member->rec->autorec) { |
1837 | stream->write_function(stream, "Stopped AUTO recording file %s (Auto Recording Now Disabled)\n", member->rec_path); |
1838 | conference->auto_record = 0; |
1839 | } else { |
1840 | stream->write_function(stream, "Stopped recording file %s\n", member->rec_path); |
1841 | } |
1842 | |
1843 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
1844 | count++; |
1845 | |
1846 | } |
1847 | } |
1848 | |
1849 | conference->record_count -= count; |
1850 | |
1851 | switch_mutex_unlock(conference->member_mutex); |
1852 | return count; |
1853 | } |
1854 | /* stop/pause/resume the specified recording */ |
1855 | static switch_status_t conference_record_action(conference_obj_t *conference, char *path, recording_action_type_t action) |
1856 | { |
1857 | conference_member_t *member = NULL((void*)0); |
1858 | int count = 0; |
1859 | //switch_file_handle_t *fh = NULL; |
1860 | |
1861 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 1861, __PRETTY_FUNCTION__)); |
1862 | switch_mutex_lock(conference->member_mutex); |
1863 | for (member = conference->members; member; member = member->next) |
1864 | { |
1865 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (path) && __builtin_constant_p (member->rec_path) && (__s1_len = __builtin_strlen (path), __s2_len = __builtin_strlen (member->rec_path), (!((size_t)(const void *)((path) + 1) - (size_t)(const void *)(path) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((member->rec_path) + 1) - (size_t )(const void *)(member->rec_path) == 1) || __s2_len >= 4 )) ? __builtin_strcmp (path, member->rec_path) : (__builtin_constant_p (path) && ((size_t)(const void *)((path) + 1) - (size_t )(const void *)(path) == 1) && (__s1_len = __builtin_strlen (path), __s1_len < 4) ? (__builtin_constant_p (member-> rec_path) && ((size_t)(const void *)((member->rec_path ) + 1) - (size_t)(const void *)(member->rec_path) == 1) ? __builtin_strcmp (path, member->rec_path) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (member-> rec_path); int __result = (((const unsigned char *) (const char *) (path))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( path))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( path))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (path ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( member->rec_path) && ((size_t)(const void *)((member ->rec_path) + 1) - (size_t)(const void *)(member->rec_path ) == 1) && (__s2_len = __builtin_strlen (member->rec_path ), __s2_len < 4) ? (__builtin_constant_p (path) && ((size_t)(const void *)((path) + 1) - (size_t)(const void *) (path) == 1) ? __builtin_strcmp (path, member->rec_path) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (path); int __result = (((const unsigned char *) (const char *) (member->rec_path))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = ( ((const unsigned char *) (const char *) (member->rec_path) )[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (member ->rec_path))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (member->rec_path))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (path, member->rec_path)))); }))) |
1866 | { |
1867 | //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Action: %d\n", action); |
1868 | switch (action) |
1869 | { |
1870 | case REC_ACTION_STOP: |
1871 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
1872 | count++; |
1873 | break; |
1874 | case REC_ACTION_PAUSE: |
1875 | switch_set_flag_locked(member, MFLAG_PAUSE_RECORDING)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 1875 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_PAUSE_RECORDING);switch_mutex_unlock (member->flag_mutex);; |
1876 | count = 1; |
1877 | break; |
1878 | case REC_ACTION_RESUME: |
1879 | switch_clear_flag_locked(member, MFLAG_PAUSE_RECORDING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_PAUSE_RECORDING); switch_mutex_unlock(member->flag_mutex );; |
1880 | count = 1; |
1881 | break; |
1882 | } |
1883 | } |
1884 | } |
1885 | switch_mutex_unlock(conference->member_mutex); |
1886 | return count; |
1887 | } |
1888 | |
1889 | |
1890 | /* Add a custom relationship to a member */ |
1891 | static conference_relationship_t *member_add_relationship(conference_member_t *member, uint32_t id) |
1892 | { |
1893 | conference_relationship_t *rel = NULL((void*)0); |
1894 | |
1895 | if (member == NULL((void*)0) || id == 0 || !(rel = switch_core_alloc(member->pool, sizeof(*rel))switch_core_perform_alloc(member->pool, sizeof(*rel), "mod_conference.c" , (const char *)__func__, 1895))) |
1896 | return NULL((void*)0); |
1897 | |
1898 | rel->id = id; |
1899 | |
1900 | |
1901 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
1902 | switch_mutex_lock(member->conference->member_mutex); |
1903 | member->conference->relationship_total++; |
1904 | switch_mutex_unlock(member->conference->member_mutex); |
1905 | rel->next = member->relationships; |
1906 | member->relationships = rel; |
1907 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
1908 | |
1909 | return rel; |
1910 | } |
1911 | |
1912 | /* Remove a custom relationship from a member */ |
1913 | static switch_status_t member_del_relationship(conference_member_t *member, uint32_t id) |
1914 | { |
1915 | switch_status_t status = SWITCH_STATUS_FALSE; |
1916 | conference_relationship_t *rel, *last = NULL((void*)0); |
1917 | |
1918 | if (member == NULL((void*)0) || id == 0) |
1919 | return status; |
1920 | |
1921 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
1922 | for (rel = member->relationships; rel; rel = rel->next) { |
1923 | if (rel->id == id) { |
1924 | /* we just forget about rel here cos it was allocated by the member's pool |
1925 | it will be freed when the member is */ |
1926 | status = SWITCH_STATUS_SUCCESS; |
1927 | if (last) { |
1928 | last->next = rel->next; |
1929 | } else { |
1930 | member->relationships = rel->next; |
1931 | } |
1932 | |
1933 | switch_mutex_lock(member->conference->member_mutex); |
1934 | member->conference->relationship_total--; |
1935 | switch_mutex_unlock(member->conference->member_mutex); |
1936 | |
1937 | } |
1938 | last = rel; |
1939 | } |
1940 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
1941 | |
1942 | return status; |
1943 | } |
1944 | |
1945 | static void send_json_event(conference_obj_t *conference) |
1946 | { |
1947 | cJSON *event, *conf_desc = NULL((void*)0); |
1948 | char *name = NULL((void*)0), *domain = NULL((void*)0), *dup_domain = NULL((void*)0); |
1949 | char *event_channel = NULL((void*)0); |
1950 | |
1951 | if (!switch_test_flag(conference, CFLAG_JSON_EVENTS)((conference)->flags & CFLAG_JSON_EVENTS)) { |
1952 | return; |
1953 | } |
1954 | |
1955 | conf_desc = conference_json_render(conference, NULL((void*)0)); |
1956 | |
1957 | if (!(name = conference->name)) { |
1958 | name = "conference"; |
1959 | } |
1960 | |
1961 | if (!(domain = conference->domain)) { |
1962 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
1963 | if (!(domain = dup_domain)) { |
1964 | domain = "cluecon.com"; |
1965 | } |
1966 | } |
1967 | |
1968 | event_channel = switch_mprintf("conference.%q@%q", name, domain); |
1969 | |
1970 | event = cJSON_CreateObject(); |
1971 | |
1972 | json_add_child_string(event, "eventChannel", event_channel); |
1973 | cJSON_AddItemToObject(event, "data", conf_desc); |
1974 | |
1975 | switch_event_channel_broadcast(event_channel, &event, modname, globals.event_channel_id); |
1976 | |
1977 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
1978 | switch_safe_free(event_channel)if (event_channel) {free(event_channel);event_channel=((void* )0);}; |
1979 | } |
1980 | |
1981 | static void send_rfc_event(conference_obj_t *conference) |
1982 | { |
1983 | switch_event_t *event; |
1984 | char *body; |
1985 | char *name = NULL((void*)0), *domain = NULL((void*)0), *dup_domain = NULL((void*)0); |
1986 | |
1987 | if (!switch_test_flag(conference, CFLAG_RFC4579)((conference)->flags & CFLAG_RFC4579)) { |
1988 | return; |
1989 | } |
1990 | |
1991 | if (!(name = conference->name)) { |
1992 | name = "conference"; |
1993 | } |
1994 | |
1995 | if (!(domain = conference->domain)) { |
1996 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
1997 | if (!(domain = dup_domain)) { |
1998 | domain = "cluecon.com"; |
1999 | } |
2000 | } |
2001 | |
2002 | |
2003 | if (switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2003, &event, SWITCH_EVENT_CONFERENCE_DATA , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
2004 | event->flags |= EF_UNIQ_HEADERS; |
2005 | |
2006 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-name", name); |
2007 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-domain", domain); |
2008 | |
2009 | body = conference_rfc4579_render(conference, NULL((void*)0), event); |
2010 | switch_event_add_body(event, "%s", body); |
2011 | free(body); |
2012 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2012, &event, ((void*)0)); |
2013 | } |
2014 | |
2015 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
2016 | |
2017 | } |
2018 | |
2019 | |
2020 | |
2021 | static void send_conference_notify(conference_obj_t *conference, const char *status, const char *call_id, switch_bool_t final) |
2022 | { |
2023 | switch_event_t *event; |
2024 | char *name = NULL((void*)0), *domain = NULL((void*)0), *dup_domain = NULL((void*)0); |
2025 | |
2026 | if (!switch_test_flag(conference, CFLAG_RFC4579)((conference)->flags & CFLAG_RFC4579)) { |
2027 | return; |
2028 | } |
2029 | |
2030 | if (!(name = conference->name)) { |
2031 | name = "conference"; |
2032 | } |
2033 | |
2034 | if (!(domain = conference->domain)) { |
2035 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
2036 | if (!(domain = dup_domain)) { |
2037 | domain = "cluecon.com"; |
2038 | } |
2039 | } |
2040 | |
2041 | |
2042 | if (switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2042, &event, SWITCH_EVENT_CONFERENCE_DATA , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
2043 | event->flags |= EF_UNIQ_HEADERS; |
2044 | |
2045 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-name", name); |
2046 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-domain", domain); |
2047 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-event", "refer"); |
2048 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", call_id); |
2049 | |
2050 | if (final) { |
2051 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "final", "true"); |
2052 | } |
2053 | |
2054 | |
2055 | switch_event_add_body(event, "%s", status); |
2056 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2056, &event, ((void*)0)); |
2057 | } |
2058 | |
2059 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
2060 | |
2061 | } |
2062 | |
2063 | static void member_update_status_field(conference_member_t *member) |
2064 | { |
2065 | char *str, *vstr = "", display[128] = ""; |
2066 | |
2067 | if (!member->conference->la || !member->json || !member->status_field) { |
2068 | return; |
2069 | } |
2070 | |
2071 | switch_live_array_lock(member->conference->la); |
2072 | |
2073 | if (!switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
2074 | str = "MUTE"; |
2075 | } else if (switch_channel_test_flag(member->channel, CF_HOLD)) { |
2076 | str = "HOLD"; |
2077 | } else if (member == member->conference->floor_holder) { |
2078 | if (switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING)) { |
2079 | str = "TALKING (FLOOR)"; |
2080 | } else { |
2081 | str = "FLOOR"; |
2082 | } |
2083 | } else if (switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING)) { |
2084 | str = "TALKING"; |
2085 | } else { |
2086 | str = "ACTIVE"; |
2087 | } |
2088 | |
2089 | if (switch_channel_test_flag(member->channel, CF_VIDEO)) { |
2090 | vstr = " VIDEO"; |
2091 | if (member == member->conference->video_floor_holder) { |
2092 | vstr = " VIDEO (FLOOR)"; |
2093 | } |
2094 | } |
2095 | |
2096 | switch_snprintf(display, sizeof(display), "%s%s", str, vstr); |
2097 | |
2098 | |
2099 | free(member->status_field->valuestring); |
2100 | member->status_field->valuestring = strdup(display)(__extension__ (__builtin_constant_p (display) && ((size_t )(const void *)((display) + 1) - (size_t)(const void *)(display ) == 1) ? (((const char *) (display))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (display ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, display , __len); __retval; })) : __strdup (display))); |
2101 | |
2102 | switch_live_array_add(member->conference->la, switch_core_session_get_uuid(member->session), -1, &member->json, SWITCH_FALSE); |
2103 | switch_live_array_unlock(member->conference->la); |
2104 | } |
2105 | |
2106 | static void adv_la(conference_obj_t *conference, conference_member_t *member, switch_bool_t join) |
2107 | { |
2108 | if (conference && conference->la && member->session) { |
2109 | cJSON *msg, *data; |
2110 | const char *uuid = switch_core_session_get_uuid(member->session); |
2111 | const char *cookie = switch_channel_get_variable(member->channel, "event_channel_cookie")switch_channel_get_variable_dup(member->channel, "event_channel_cookie" , SWITCH_TRUE, -1); |
2112 | const char *event_channel = cookie ? cookie : uuid; |
2113 | |
2114 | msg = cJSON_CreateObject(); |
2115 | data = json_add_child_obj(msg, "pvtData", NULL((void*)0)); |
2116 | |
2117 | cJSON_AddItemToObject(msg, "eventChannel", cJSON_CreateString(event_channel)); |
2118 | cJSON_AddItemToObject(msg, "eventType", cJSON_CreateString("channelPvtData")); |
2119 | |
2120 | cJSON_AddItemToObject(data, "action", cJSON_CreateString(join ? "conference-liveArray-join" : "conference-liveArray-part")); |
2121 | cJSON_AddItemToObject(data, "laChannel", cJSON_CreateString(conference->la_event_channel)); |
2122 | cJSON_AddItemToObject(data, "laName", cJSON_CreateString(conference->la_name)); |
2123 | cJSON_AddItemToObject(data, "role", cJSON_CreateString(switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD) ? "moderator" : "participant")); |
2124 | cJSON_AddItemToObject(data, "chatID", cJSON_CreateString(conference->chat_id)); |
2125 | if (switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD)) { |
2126 | cJSON_AddItemToObject(data, "modChannel", cJSON_CreateString(conference->mod_event_channel)); |
2127 | } |
2128 | |
2129 | switch_event_channel_broadcast(event_channel, &msg, modname, globals.event_channel_id); |
2130 | |
2131 | if (cookie) { |
2132 | switch_event_channel_permission_modify(cookie, conference->la_event_channel, join); |
2133 | switch_event_channel_permission_modify(cookie, conference->mod_event_channel, join); |
2134 | } |
2135 | } |
2136 | } |
2137 | |
2138 | #ifndef OPENAL_POSITIONING |
2139 | static switch_status_t parse_position(al_handle_t *al, const char *data) |
2140 | { |
2141 | return SWITCH_STATUS_FALSE; |
2142 | } |
2143 | |
2144 | #else |
2145 | static switch_status_t parse_position(al_handle_t *al, const char *data) |
2146 | { |
2147 | char *args[3]; |
2148 | int num; |
2149 | char *dup; |
2150 | |
2151 | |
2152 | dup = strdup((char *)data)(__extension__ (__builtin_constant_p ((char *)data) && ((size_t)(const void *)(((char *)data) + 1) - (size_t)(const void *)((char *)data) == 1) ? (((const char *) ((char *)data ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((char *)data) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (char *)data, __len); __retval; } )) : __strdup ((char *)data))); |
2153 | switch_assert(dup)((dup) ? (void) (0) : __assert_fail ("dup", "mod_conference.c" , 2153, __PRETTY_FUNCTION__)); |
2154 | |
2155 | if ((num = switch_split(dup, ':', args)switch_separate_string(dup, ':', args, (sizeof(args) / sizeof (args[0])))) != 3) { |
2156 | return SWITCH_STATUS_FALSE; |
2157 | } |
2158 | |
2159 | al->pos_x = atof(args[0]); |
2160 | al->pos_y = atof(args[1]); |
2161 | al->pos_z = atof(args[2]); |
2162 | al->setpos = 1; |
2163 | |
2164 | switch_safe_free(dup)if (dup) {free(dup);dup=((void*)0);}; |
2165 | |
2166 | return SWITCH_STATUS_SUCCESS; |
2167 | } |
2168 | #endif |
2169 | |
2170 | #ifndef OPENAL_POSITIONING |
2171 | static switch_status_t member_parse_position(conference_member_t *member, const char *data) |
2172 | { |
2173 | return SWITCH_STATUS_FALSE; |
2174 | } |
2175 | #else |
2176 | static switch_status_t member_parse_position(conference_member_t *member, const char *data) |
2177 | { |
2178 | switch_status_t status; |
2179 | |
2180 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
2181 | status = parse_position(member->al, data); |
2182 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
2183 | |
2184 | return status; |
2185 | |
2186 | } |
2187 | #endif |
2188 | |
2189 | /* Gain exclusive access and add the member to the list */ |
2190 | static switch_status_t conference_add_member(conference_obj_t *conference, conference_member_t *member) |
2191 | { |
2192 | switch_status_t status = SWITCH_STATUS_FALSE; |
2193 | switch_event_t *event; |
2194 | char msg[512]; /* conference count announcement */ |
2195 | call_list_t *call_list = NULL((void*)0); |
2196 | switch_channel_t *channel; |
2197 | const char *controls = NULL((void*)0), *position = NULL((void*)0); |
2198 | |
2199 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 2199, __PRETTY_FUNCTION__)); |
2200 | switch_assert(member != NULL)((member != ((void*)0)) ? (void) (0) : __assert_fail ("member != ((void*)0)" , "mod_conference.c", 2200, __PRETTY_FUNCTION__)); |
2201 | |
2202 | switch_mutex_lock(conference->mutex); |
2203 | switch_mutex_lock(member->audio_in_mutex); |
2204 | switch_mutex_lock(member->audio_out_mutex); |
2205 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
2206 | switch_mutex_lock(conference->member_mutex); |
2207 | |
2208 | |
2209 | member->join_time = switch_epoch_time_now(NULL((void*)0)); |
2210 | member->conference = conference; |
2211 | member->next = conference->members; |
2212 | member->energy_level = conference->energy_level; |
2213 | member->score_iir = 0; |
2214 | member->verbose_events = conference->verbose_events; |
2215 | switch_queue_create(&member->dtmf_queue, 100, member->pool); |
2216 | conference->members = member; |
2217 | switch_set_flag_locked(member, MFLAG_INTREE)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 2217 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_INTREE);switch_mutex_unlock(member ->flag_mutex);; |
2218 | switch_mutex_unlock(conference->member_mutex); |
2219 | conference_cdr_add(member); |
2220 | |
2221 | |
2222 | if (!switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
2223 | if (switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST)) { |
2224 | conference->count_ghosts++; |
2225 | } else { |
2226 | conference->count++; |
2227 | } |
2228 | |
2229 | if (switch_test_flag(member, MFLAG_ENDCONF)((member)->flags & MFLAG_ENDCONF)) { |
2230 | if (conference->end_count++) { |
2231 | conference->endconf_time = 0; |
2232 | } |
2233 | } |
2234 | |
2235 | conference_send_presence(conference); |
2236 | |
2237 | channel = switch_core_session_get_channel(member->session); |
2238 | |
2239 | if (switch_channel_test_flag(channel, CF_VIDEO)) { |
2240 | switch_set_flag_locked(member, MFLAG_ACK_VIDEO)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 2240 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_ACK_VIDEO);switch_mutex_unlock (member->flag_mutex);; |
2241 | } |
2242 | |
2243 | switch_channel_set_variable_printf(channel, "conference_member_id", "%d", member->id); |
2244 | switch_channel_set_variable_printf(channel, "conference_moderator", "%s", switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD) ? "true" : "false"); |
2245 | switch_channel_set_variable_printf(channel, "conference_ghost", "%s", switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST) ? "true" : "false"); |
2246 | switch_channel_set_variable(channel, "conference_recording", conference->record_filename)switch_channel_set_variable_var_check(channel, "conference_recording" , conference->record_filename, SWITCH_TRUE); |
2247 | switch_channel_set_variable(channel, CONFERENCE_UUID_VARIABLE, conference->uuid_str)switch_channel_set_variable_var_check(channel, "conference_uuid" , conference->uuid_str, SWITCH_TRUE); |
2248 | |
2249 | if (switch_channel_test_flag(channel, CF_VIDEO)) { |
2250 | if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE)) { |
2251 | switch_channel_set_flag(channel, CF_VIDEO_ECHO)switch_channel_set_flag_value(channel, CF_VIDEO_ECHO, 1); |
2252 | switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE); |
2253 | } else { |
2254 | switch_channel_clear_flag(channel, CF_VIDEO_ECHO); |
2255 | } |
2256 | /* Tell the channel to request a fresh vid frame */ |
2257 | switch_core_session_refresh_video(member->session); |
2258 | |
2259 | if (conference->video_floor_holder) { |
2260 | switch_mutex_lock(conference->mutex); |
2261 | if (conference->video_floor_holder) { |
2262 | switch_core_session_refresh_video(conference->video_floor_holder->session); |
2263 | } |
2264 | switch_mutex_unlock(conference->mutex); |
2265 | } |
2266 | } |
2267 | |
2268 | if (!switch_channel_get_variable(channel, "conference_call_key")switch_channel_get_variable_dup(channel, "conference_call_key" , SWITCH_TRUE, -1)) { |
2269 | char *key = switch_core_session_sprintf(member->session, "conf_%s_%s_%s", |
2270 | conference->name, conference->domain, switch_channel_get_variable(channel, "caller_id_number")switch_channel_get_variable_dup(channel, "caller_id_number", SWITCH_TRUE , -1)); |
2271 | switch_channel_set_variable(channel, "conference_call_key", key)switch_channel_set_variable_var_check(channel, "conference_call_key" , key, SWITCH_TRUE); |
2272 | } |
2273 | |
2274 | |
2275 | if (switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD) && switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD)) { |
2276 | switch_clear_flag(conference, CFLAG_WAIT_MOD)(conference)->flags &= ~(CFLAG_WAIT_MOD); |
2277 | } |
2278 | |
2279 | if (conference->count > 1) { |
2280 | if ((conference->moh_sound && !switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) || |
2281 | (switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD) && !switch_true(switch_channel_get_variable(channel, "conference_permanent_wait_mod_moh")switch_channel_get_variable_dup(channel, "conference_permanent_wait_mod_moh" , SWITCH_TRUE, -1)))) { |
2282 | /* stop MoH if any */ |
2283 | conference_stop_file(conference, FILE_STOP_ASYNC); |
2284 | } |
2285 | |
2286 | if (!switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ) && !zstr(conference->enter_sound)_zstr(conference->enter_sound)) { |
2287 | const char * enter_sound = switch_channel_get_variable(channel, "conference_enter_sound")switch_channel_get_variable_dup(channel, "conference_enter_sound" , SWITCH_TRUE, -1); |
2288 | if (switch_test_flag(conference, CFLAG_ENTER_SOUND)((conference)->flags & CFLAG_ENTER_SOUND)) { |
2289 | if (!zstr(enter_sound)_zstr(enter_sound)) { |
2290 | conference_play_file(conference, (char *)enter_sound, CONF_DEFAULT_LEADIN20, |
2291 | switch_core_session_get_channel(member->session), 0); |
2292 | } else { |
2293 | conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN20, switch_core_session_get_channel(member->session), 0); |
2294 | } |
2295 | } |
2296 | } |
2297 | } |
2298 | |
2299 | |
2300 | call_list = (call_list_t *) switch_channel_get_private(channel, "_conference_autocall_list_"); |
2301 | |
2302 | if (call_list) { |
2303 | char saymsg[1024]; |
2304 | switch_snprintf(saymsg, sizeof(saymsg), "Auto Calling %d parties", call_list->iteration); |
2305 | conference_member_say(member, saymsg, 0); |
2306 | } else { |
2307 | |
2308 | if (!switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ)) { |
2309 | /* announce the total number of members in the conference */ |
2310 | if (conference->count >= conference->announce_count && conference->announce_count > 1) { |
2311 | switch_snprintf(msg, sizeof(msg), "There are %d callers", conference->count); |
2312 | conference_member_say(member, msg, CONF_DEFAULT_LEADIN20); |
2313 | } else if (conference->count == 1 && !conference->perpetual_sound && !switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) { |
2314 | /* as long as its not a bridge_to conference, announce if person is alone */ |
2315 | if (!switch_test_flag(conference, CFLAG_BRIDGE_TO)((conference)->flags & CFLAG_BRIDGE_TO)) { |
2316 | if (conference->alone_sound && !switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST)) { |
2317 | conference_stop_file(conference, FILE_STOP_ASYNC); |
2318 | conference_play_file(conference, conference->alone_sound, CONF_DEFAULT_LEADIN20, |
2319 | switch_core_session_get_channel(member->session), 0); |
2320 | } else { |
2321 | switch_snprintf(msg, sizeof(msg), "You are currently the only person in this conference."); |
2322 | conference_member_say(member, msg, CONF_DEFAULT_LEADIN20); |
2323 | } |
2324 | } |
2325 | } |
2326 | } |
2327 | } |
2328 | |
2329 | if (conference->min && conference->count >= conference->min) { |
2330 | switch_set_flag(conference, CFLAG_ENFORCE_MIN)(conference)->flags |= (CFLAG_ENFORCE_MIN); |
2331 | } |
2332 | |
2333 | if (!switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ) && |
2334 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2334, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
2335 | conference_add_event_member_data(member, event); |
2336 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "add-member"); |
2337 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2337, &event, ((void*)0)); |
2338 | } |
2339 | |
2340 | switch_channel_clear_app_flag_key("conf_silent", channel, CONF_SILENT_REQ); |
2341 | switch_channel_set_app_flag_key("conf_silent", channel, CONF_SILENT_DONE); |
2342 | |
2343 | |
2344 | if ((position = switch_channel_get_variable(channel, "conference_position")switch_channel_get_variable_dup(channel, "conference_position" , SWITCH_TRUE, -1))) { |
2345 | |
2346 | if (conference->channels == 2) { |
2347 | if (switch_test_flag(member, MFLAG_NO_POSITIONAL)((member)->flags & MFLAG_NO_POSITIONAL)) { |
2348 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2348, ((void*)0), SWITCH_LOG_WARNING, |
2349 | "%s has positional audio blocked.\n", switch_channel_get_name(channel)); |
2350 | } else { |
2351 | if (member_parse_position(member, position) != SWITCH_STATUS_SUCCESS) { |
2352 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2352, ((void*)0), SWITCH_LOG_WARNING, "%s invalid position data\n", switch_channel_get_name(channel)); |
2353 | } else { |
2354 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2354, ((void*)0), SWITCH_LOG_INFO, "%s position data set\n", switch_channel_get_name(channel)); |
2355 | } |
2356 | |
2357 | switch_set_flag(member, MFLAG_POSITIONAL)(member)->flags |= (MFLAG_POSITIONAL); |
2358 | member->al = create_al(member->pool); |
2359 | } |
2360 | } else { |
2361 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2361, ((void*)0), SWITCH_LOG_WARNING, "%s cannot set position data on mono conference.\n", switch_channel_get_name(channel)); |
2362 | } |
2363 | } |
2364 | |
2365 | |
2366 | |
2367 | controls = switch_channel_get_variable(channel, "conference_controls")switch_channel_get_variable_dup(channel, "conference_controls" , SWITCH_TRUE, -1); |
2368 | |
2369 | if (zstr(controls)_zstr(controls)) { |
2370 | if (!switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD) || !conference->moderator_controls) { |
2371 | controls = conference->caller_controls; |
2372 | } else { |
2373 | controls = conference->moderator_controls; |
2374 | } |
2375 | } |
2376 | |
2377 | if (zstr(controls)_zstr(controls)) { |
2378 | controls = "default"; |
2379 | } |
2380 | |
2381 | if (strcasecmp(controls, "none")) { |
2382 | switch_ivr_dmachine_create(&member->dmachine, "mod_conference", NULL((void*)0), |
2383 | conference->ivr_dtmf_timeout, conference->ivr_input_timeout, NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
2384 | member_bind_controls(member, controls); |
2385 | } |
2386 | |
2387 | } |
2388 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
2389 | switch_mutex_unlock(member->audio_out_mutex); |
2390 | switch_mutex_unlock(member->audio_in_mutex); |
2391 | |
2392 | if (conference->la && member->channel) { |
2393 | member->json = cJSON_CreateArray(); |
2394 | cJSON_AddItemToArray(member->json, cJSON_CreateStringPrintf("%0.4d", member->id)); |
2395 | cJSON_AddItemToArray(member->json, cJSON_CreateString(switch_channel_get_variable(member->channel, "caller_id_number")switch_channel_get_variable_dup(member->channel, "caller_id_number" , SWITCH_TRUE, -1))); |
2396 | cJSON_AddItemToArray(member->json, cJSON_CreateString(switch_channel_get_variable(member->channel, "caller_id_name")switch_channel_get_variable_dup(member->channel, "caller_id_name" , SWITCH_TRUE, -1))); |
2397 | |
2398 | cJSON_AddItemToArray(member->json, cJSON_CreateStringPrintf("%s@%s", |
2399 | switch_channel_get_variable(member->channel, "original_read_codec")switch_channel_get_variable_dup(member->channel, "original_read_codec" , SWITCH_TRUE, -1), |
2400 | switch_channel_get_variable(member->channel, "original_read_rate")switch_channel_get_variable_dup(member->channel, "original_read_rate" , SWITCH_TRUE, -1) |
2401 | )); |
2402 | |
2403 | |
2404 | |
2405 | |
2406 | member->status_field = cJSON_CreateString(""); |
2407 | cJSON_AddItemToArray(member->json, member->status_field); |
2408 | |
2409 | cJSON_AddItemToArray(member->json, cJSON_CreateNull()); |
2410 | |
2411 | member_update_status_field(member); |
2412 | //switch_live_array_add_alias(conference->la, switch_core_session_get_uuid(member->session), "conference"); |
2413 | adv_la(conference, member, SWITCH_TRUE); |
2414 | switch_live_array_add(conference->la, switch_core_session_get_uuid(member->session), -1, &member->json, SWITCH_FALSE); |
2415 | |
2416 | } |
2417 | |
2418 | |
2419 | if (switch_test_flag(conference, CFLAG_POSITIONAL)((conference)->flags & CFLAG_POSITIONAL)) { |
2420 | gen_arc(conference, NULL((void*)0)); |
2421 | } |
2422 | |
2423 | |
2424 | send_rfc_event(conference); |
2425 | send_json_event(conference); |
2426 | |
2427 | switch_mutex_unlock(conference->mutex); |
2428 | status = SWITCH_STATUS_SUCCESS; |
2429 | |
2430 | |
2431 | |
2432 | |
2433 | return status; |
2434 | } |
2435 | |
2436 | static void conference_set_video_floor_holder(conference_obj_t *conference, conference_member_t *member, switch_bool_t force) |
2437 | { |
2438 | switch_event_t *event; |
2439 | conference_member_t *old_member = NULL((void*)0), *imember = NULL((void*)0); |
2440 | int old_id = 0; |
2441 | |
2442 | if (!member) { |
2443 | switch_clear_flag(conference, CFLAG_VID_FLOOR_LOCK)(conference)->flags &= ~(CFLAG_VID_FLOOR_LOCK); |
2444 | } |
2445 | |
2446 | if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE) || (!force && switch_test_flag(conference, CFLAG_VID_FLOOR_LOCK)((conference)->flags & CFLAG_VID_FLOOR_LOCK))) { |
2447 | return; |
2448 | } |
2449 | |
2450 | if (conference->video_floor_holder) { |
2451 | if (conference->video_floor_holder == member) { |
2452 | return; |
2453 | } else { |
2454 | old_member = conference->video_floor_holder; |
2455 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2455, ((void*)0), SWITCH_LOG_DEBUG1, "Dropping video floor %s\n", |
2456 | switch_channel_get_name(old_member->channel)); |
2457 | } |
2458 | } |
2459 | |
2460 | |
2461 | switch_mutex_lock(conference->mutex); |
2462 | if (!member) { |
2463 | for (imember = conference->members; imember; imember = imember->next) { |
2464 | if (imember != conference->video_floor_holder && imember->channel && switch_channel_test_flag(imember->channel, CF_VIDEO)) { |
2465 | member = imember; |
2466 | break; |
2467 | } |
2468 | } |
2469 | } |
2470 | |
2471 | if (member) { |
2472 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2472, ((void*)0), SWITCH_LOG_DEBUG1, "Adding video floor %s\n", |
2473 | switch_channel_get_name(member->channel)); |
2474 | //switch_channel_set_flag(member->channel, CF_VIDEO_PASSIVE); |
2475 | switch_core_session_refresh_video(member->session); |
2476 | conference->video_floor_holder = member; |
2477 | member_update_status_field(member); |
2478 | } else { |
2479 | conference->video_floor_holder = NULL((void*)0); |
2480 | } |
2481 | |
2482 | if (old_member) { |
2483 | old_id = old_member->id; |
2484 | member_update_status_field(old_member); |
2485 | //switch_channel_clear_flag(old_member->channel, CF_VIDEO_PASSIVE); |
2486 | } |
2487 | |
2488 | for (imember = conference->members; imember; imember = imember->next) { |
2489 | if (!imember->channel || !switch_channel_test_flag(imember->channel, CF_VIDEO)) { |
2490 | continue; |
2491 | } |
2492 | switch_channel_clear_flag(imember->channel, CF_VIDEO_ECHO); |
2493 | |
2494 | if (imember == conference->video_floor_holder) { |
2495 | switch_channel_set_flag(imember->channel, CF_VIDEO_PASSIVE)switch_channel_set_flag_value(imember->channel, CF_VIDEO_PASSIVE , 1); |
2496 | } else { |
2497 | switch_channel_clear_flag(imember->channel, CF_VIDEO_PASSIVE); |
2498 | } |
2499 | |
2500 | switch_channel_set_flag(imember->channel, CF_VIDEO_BREAK)switch_channel_set_flag_value(imember->channel, CF_VIDEO_BREAK , 1); |
2501 | switch_core_session_kill_channel(imember->session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(imember->session, "mod_conference.c", (const char *)__func__, 2501, SWITCH_SIG_BREAK ); |
2502 | switch_core_session_refresh_video(imember->session); |
2503 | } |
2504 | |
2505 | switch_set_flag(conference, CFLAG_FLOOR_CHANGE)(conference)->flags |= (CFLAG_FLOOR_CHANGE); |
2506 | switch_mutex_unlock(conference->mutex); |
2507 | |
2508 | if (test_eflag(conference, EFLAG_FLOOR_CHANGE)((conference)->eflags & EFLAG_FLOOR_CHANGE)) { |
2509 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2509, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance"); |
2510 | conference_add_event_data(conference, event); |
2511 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "video-floor-change"); |
2512 | if (old_id) { |
2513 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-ID", "%d", old_id); |
2514 | } else { |
2515 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-ID", "none"); |
2516 | } |
2517 | if (conference->video_floor_holder) { |
2518 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", conference->video_floor_holder->id); |
2519 | } else { |
2520 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "New-ID", "none"); |
2521 | } |
2522 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2522, &event, ((void*)0)); |
2523 | } |
2524 | |
2525 | } |
2526 | |
2527 | static void conference_set_floor_holder(conference_obj_t *conference, conference_member_t *member) |
2528 | { |
2529 | switch_event_t *event; |
2530 | conference_member_t *old_member = NULL((void*)0); |
2531 | int old_id = 0; |
2532 | |
2533 | if (!switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE) && |
2534 | ((conference->video_floor_holder && !member && !switch_test_flag(conference, CFLAG_VID_FLOOR_LOCK)((conference)->flags & CFLAG_VID_FLOOR_LOCK)) || |
2535 | (member && member->channel && switch_channel_test_flag(member->channel, CF_VIDEO)))) { |
2536 | conference_set_video_floor_holder(conference, member, SWITCH_FALSE); |
2537 | } |
2538 | |
2539 | if (conference->floor_holder) { |
2540 | if (conference->floor_holder == member) { |
2541 | return; |
2542 | } else { |
2543 | old_member = conference->floor_holder; |
2544 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2544, ((void*)0), SWITCH_LOG_DEBUG1, "Dropping floor %s\n", |
2545 | switch_channel_get_name(old_member->channel)); |
2546 | |
2547 | } |
2548 | } |
2549 | |
2550 | switch_mutex_lock(conference->mutex); |
2551 | if (member) { |
2552 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2552, ((void*)0), SWITCH_LOG_DEBUG1, "Adding floor %s\n", |
2553 | switch_channel_get_name(member->channel)); |
2554 | |
2555 | conference->floor_holder = member; |
2556 | member_update_status_field(member); |
2557 | } else { |
2558 | conference->floor_holder = NULL((void*)0); |
2559 | } |
2560 | |
2561 | |
2562 | if (old_member) { |
2563 | old_id = old_member->id; |
2564 | member_update_status_field(old_member); |
2565 | } |
2566 | |
2567 | switch_set_flag(conference, CFLAG_FLOOR_CHANGE)(conference)->flags |= (CFLAG_FLOOR_CHANGE); |
2568 | switch_mutex_unlock(conference->mutex); |
2569 | |
2570 | if (test_eflag(conference, EFLAG_FLOOR_CHANGE)((conference)->eflags & EFLAG_FLOOR_CHANGE)) { |
2571 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2571, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance"); |
2572 | conference_add_event_data(conference, event); |
2573 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "floor-change"); |
2574 | if (old_id) { |
2575 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-ID", "%d", old_id); |
2576 | } else { |
2577 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-ID", "none"); |
2578 | } |
2579 | |
2580 | if (conference->floor_holder) { |
2581 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", conference->floor_holder->id); |
2582 | } else { |
2583 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "New-ID", "none"); |
2584 | } |
2585 | |
2586 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2586, &event, ((void*)0)); |
2587 | } |
2588 | |
2589 | } |
2590 | |
2591 | #ifdef OPENAL_POSITIONING |
2592 | static void close_al(al_handle_t *al) |
2593 | { |
2594 | if (!al) return; |
2595 | |
2596 | switch_mutex_lock(globals.setup_mutex); |
2597 | if (al->source) { |
2598 | alDeleteSources(1, &al->source); |
2599 | al->source = 0; |
2600 | } |
2601 | |
2602 | if (al->buffer_in[0]) { |
2603 | alDeleteBuffers(2, al->buffer_in); |
2604 | al->buffer_in[0] = 0; |
2605 | al->buffer_in[1] = 0; |
2606 | } |
2607 | |
2608 | if (al->context) { |
2609 | alcDestroyContext(al->context); |
2610 | al->context = 0; |
2611 | } |
2612 | |
2613 | if (al->device) { |
2614 | alcCloseDevice(al->device); |
2615 | al->device = NULL((void*)0); |
2616 | } |
2617 | switch_mutex_unlock(globals.setup_mutex); |
2618 | } |
2619 | #endif |
2620 | |
2621 | static switch_status_t conference_file_close(conference_obj_t *conference, conference_file_node_t *node) |
2622 | { |
2623 | switch_event_t *event; |
2624 | conference_member_t *member = NULL((void*)0); |
2625 | |
2626 | if (test_eflag(conference, EFLAG_PLAY_FILE_DONE)((conference)->eflags & EFLAG_PLAY_FILE_DONE) && |
2627 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2627, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
2628 | |
2629 | conference_add_event_data(conference, event); |
2630 | |
2631 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "seconds", "%ld", (long) node->fh.samples_in / node->fh.native_rate); |
2632 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "milliseconds", "%ld", (long) node->fh.samples_in / (node->fh.native_rate / 1000)); |
2633 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "samples", "%ld", (long) node->fh.samples_in); |
2634 | |
2635 | if (node->fh.params) { |
2636 | switch_event_merge(event, node->fh.params); |
2637 | } |
2638 | |
2639 | if (node->member_id) { |
2640 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member-done"); |
2641 | |
2642 | if ((member = conference_member_get(conference, node->member_id))) { |
2643 | conference_add_event_member_data(member, event); |
2644 | switch_thread_rwlock_unlock(member->rwlock); |
2645 | } |
2646 | |
2647 | } else { |
2648 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-done"); |
2649 | } |
2650 | |
2651 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", node->file); |
2652 | |
2653 | if (node->async) { |
2654 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", "true"); |
2655 | } |
2656 | |
2657 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2657, &event, ((void*)0)); |
2658 | } |
2659 | |
2660 | #ifdef OPENAL_POSITIONING |
2661 | if (node->al && node->al->device) { |
2662 | close_al(node->al); |
2663 | } |
2664 | #endif |
2665 | |
2666 | return switch_core_file_close(&node->fh); |
2667 | } |
2668 | |
2669 | /* Gain exclusive access and remove the member from the list */ |
2670 | static switch_status_t conference_del_member(conference_obj_t *conference, conference_member_t *member) |
2671 | { |
2672 | switch_status_t status = SWITCH_STATUS_FALSE; |
2673 | conference_member_t *imember, *last = NULL((void*)0); |
2674 | switch_event_t *event; |
2675 | conference_file_node_t *member_fnode; |
2676 | switch_speech_handle_t *member_sh; |
2677 | const char *exit_sound = NULL((void*)0); |
2678 | |
2679 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 2679, __PRETTY_FUNCTION__)); |
2680 | switch_assert(member != NULL)((member != ((void*)0)) ? (void) (0) : __assert_fail ("member != ((void*)0)" , "mod_conference.c", 2680, __PRETTY_FUNCTION__)); |
2681 | |
2682 | switch_thread_rwlock_wrlock(member->rwlock); |
2683 | |
2684 | if (member->session && (exit_sound = switch_channel_get_variable(switch_core_session_get_channel(member->session), "conference_exit_sound")switch_channel_get_variable_dup(switch_core_session_get_channel (member->session), "conference_exit_sound", SWITCH_TRUE, - 1))) { |
2685 | conference_play_file(conference, (char *)exit_sound, CONF_DEFAULT_LEADIN20, |
2686 | switch_core_session_get_channel(member->session), 0); |
2687 | } |
2688 | |
2689 | |
2690 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
2691 | |
2692 | |
2693 | conference_cdr_del(member); |
2694 | |
2695 | #ifdef OPENAL_POSITIONING |
2696 | if (member->al && member->al->device) { |
2697 | close_al(member->al); |
2698 | } |
2699 | #endif |
2700 | |
2701 | member_fnode = member->fnode; |
2702 | member_sh = member->sh; |
2703 | member->fnode = NULL((void*)0); |
2704 | member->sh = NULL((void*)0); |
2705 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
2706 | |
2707 | if (member->dmachine) { |
2708 | switch_ivr_dmachine_destroy(&member->dmachine); |
2709 | } |
2710 | |
2711 | switch_mutex_lock(conference->mutex); |
2712 | switch_mutex_lock(conference->member_mutex); |
2713 | switch_mutex_lock(member->audio_in_mutex); |
2714 | switch_mutex_lock(member->audio_out_mutex); |
2715 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
2716 | switch_clear_flag(member, MFLAG_INTREE)(member)->flags &= ~(MFLAG_INTREE); |
2717 | |
2718 | for (imember = conference->members; imember; imember = imember->next) { |
2719 | if (imember == member) { |
2720 | if (last) { |
2721 | last->next = imember->next; |
2722 | } else { |
2723 | conference->members = imember->next; |
2724 | } |
2725 | break; |
2726 | } |
2727 | last = imember; |
2728 | } |
2729 | |
2730 | switch_thread_rwlock_unlock(member->rwlock); |
2731 | |
2732 | /* Close Unused Handles */ |
2733 | if (member_fnode) { |
2734 | conference_file_node_t *fnode, *cur; |
2735 | switch_memory_pool_t *pool; |
2736 | |
2737 | fnode = member_fnode; |
2738 | while (fnode) { |
2739 | cur = fnode; |
2740 | fnode = fnode->next; |
2741 | |
2742 | if (cur->type != NODE_TYPE_SPEECH) { |
2743 | conference_file_close(conference, cur); |
2744 | } |
2745 | |
2746 | pool = cur->pool; |
2747 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 2747); |
2748 | } |
2749 | } |
2750 | |
2751 | if (member_sh) { |
2752 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; |
2753 | switch_core_speech_close(&member->lsh, &flags); |
2754 | } |
2755 | |
2756 | if (member == member->conference->floor_holder) { |
2757 | conference_set_floor_holder(member->conference, NULL((void*)0)); |
2758 | } |
2759 | |
2760 | |
2761 | if (member == member->conference->video_floor_holder) { |
2762 | conference_set_video_floor_holder(member->conference, NULL((void*)0), SWITCH_TRUE); |
2763 | } |
2764 | |
2765 | member->conference = NULL((void*)0); |
2766 | |
2767 | if (!switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
2768 | switch_channel_t *channel = switch_core_session_get_channel(member->session); |
2769 | if (switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST)) { |
2770 | conference->count_ghosts--; |
2771 | } else { |
2772 | conference->count--; |
2773 | } |
2774 | |
2775 | if (switch_test_flag(member, MFLAG_ENDCONF)((member)->flags & MFLAG_ENDCONF)) { |
2776 | if (!--conference->end_count) { |
2777 | //switch_set_flag_locked(conference, CFLAG_DESTRUCT); |
2778 | conference->endconf_time = switch_epoch_time_now(NULL((void*)0)); |
2779 | } |
2780 | } |
2781 | |
2782 | conference_send_presence(conference); |
2783 | switch_channel_set_variable(channel, "conference_call_key", NULL)switch_channel_set_variable_var_check(channel, "conference_call_key" , ((void*)0), SWITCH_TRUE); |
2784 | |
2785 | if ((conference->min && switch_test_flag(conference, CFLAG_ENFORCE_MIN)((conference)->flags & CFLAG_ENFORCE_MIN) && (conference->count + conference->count_ghosts) < conference->min) |
2786 | || (switch_test_flag(conference, CFLAG_DYNAMIC)((conference)->flags & CFLAG_DYNAMIC) && (conference->count + conference->count_ghosts == 0))) { |
2787 | switch_set_flag(conference, CFLAG_DESTRUCT)(conference)->flags |= (CFLAG_DESTRUCT); |
2788 | } else { |
2789 | if (!switch_true(switch_channel_get_variable(channel, "conference_permanent_wait_mod_moh")switch_channel_get_variable_dup(channel, "conference_permanent_wait_mod_moh" , SWITCH_TRUE, -1)) && switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) { |
2790 | /* Stop MOH if any */ |
2791 | conference_stop_file(conference, FILE_STOP_ASYNC); |
2792 | } |
2793 | if (!exit_sound && conference->exit_sound && switch_test_flag(conference, CFLAG_EXIT_SOUND)((conference)->flags & CFLAG_EXIT_SOUND)) { |
2794 | conference_play_file(conference, conference->exit_sound, 0, channel, 0); |
2795 | } |
2796 | if (conference->count == 1 && conference->alone_sound && !switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD) && !switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST)) { |
2797 | conference_stop_file(conference, FILE_STOP_ASYNC); |
2798 | conference_play_file(conference, conference->alone_sound, 0, channel, 0); |
2799 | } |
2800 | } |
2801 | |
2802 | if (test_eflag(conference, EFLAG_DEL_MEMBER)((conference)->eflags & EFLAG_DEL_MEMBER) && |
2803 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2803, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
2804 | conference_add_event_member_data(member, event); |
2805 | conference_add_event_data(conference, event); |
2806 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "del-member"); |
2807 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2807, &event, ((void*)0)); |
2808 | } |
2809 | } |
2810 | switch_mutex_unlock(conference->member_mutex); |
2811 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
2812 | switch_mutex_unlock(member->audio_out_mutex); |
2813 | switch_mutex_unlock(member->audio_in_mutex); |
2814 | |
2815 | |
2816 | if (conference->la && member->session) { |
2817 | switch_live_array_del(conference->la, switch_core_session_get_uuid(member->session)); |
2818 | //switch_live_array_clear_alias(conference->la, switch_core_session_get_uuid(member->session), "conference"); |
2819 | adv_la(conference, member, SWITCH_FALSE); |
2820 | } |
2821 | |
2822 | send_rfc_event(conference); |
2823 | send_json_event(conference); |
2824 | |
2825 | if (switch_test_flag(conference, CFLAG_POSITIONAL)((conference)->flags & CFLAG_POSITIONAL)) { |
2826 | gen_arc(conference, NULL((void*)0)); |
2827 | } |
2828 | |
2829 | if (member->session) { |
2830 | switch_core_media_hard_mute(member->session, SWITCH_FALSE); |
2831 | } |
2832 | |
2833 | switch_mutex_unlock(conference->mutex); |
2834 | status = SWITCH_STATUS_SUCCESS; |
2835 | |
2836 | return status; |
2837 | } |
2838 | |
2839 | /* Thread bridging video between two members, there will be two threads if video briding is used */ |
2840 | static void *SWITCH_THREAD_FUNC conference_video_bridge_thread_run(switch_thread_t *thread, void *obj) |
2841 | { |
2842 | struct vid_helper *vh = obj; |
2843 | switch_core_session_t *session_a = vh->member_a->session; |
2844 | switch_core_session_t *session_b = vh->member_b->session; |
2845 | switch_channel_t *channel_a = switch_core_session_get_channel(session_a); |
2846 | switch_channel_t *channel_b = switch_core_session_get_channel(session_b); |
2847 | switch_status_t status; |
2848 | switch_frame_t *read_frame; |
2849 | conference_obj_t *conference = vh->member_a->conference; |
2850 | |
2851 | switch_thread_rwlock_rdlock(conference->rwlock); |
2852 | switch_thread_rwlock_rdlock(vh->member_a->rwlock); |
2853 | switch_thread_rwlock_rdlock(vh->member_b->rwlock); |
2854 | |
2855 | |
2856 | switch_channel_set_flag(channel_a, CF_VIDEO_PASSIVE)switch_channel_set_flag_value(channel_a, CF_VIDEO_PASSIVE, 1); |
2857 | |
2858 | /* Acquire locks for both sessions so the helper object and member structures don't get destroyed before we exit */ |
2859 | switch_core_session_read_lock(session_a); |
2860 | switch_core_session_read_lock(session_b); |
2861 | |
2862 | vh->up = 1; |
2863 | while (vh->up == 1 && switch_test_flag(vh->member_a, MFLAG_RUNNING)((vh->member_a)->flags & MFLAG_RUNNING) && switch_test_flag(vh->member_b, MFLAG_RUNNING)((vh->member_b)->flags & MFLAG_RUNNING) && |
2864 | switch_channel_ready(channel_a)switch_channel_test_ready(channel_a, SWITCH_TRUE, SWITCH_FALSE ) && switch_channel_ready(channel_b)switch_channel_test_ready(channel_b, SWITCH_TRUE, SWITCH_FALSE )) { |
2865 | |
2866 | if (switch_channel_test_flag(channel_a, CF_VIDEO_REFRESH_REQ)) { |
2867 | switch_core_session_refresh_video(session_b); |
2868 | switch_channel_clear_flag(channel_a, CF_VIDEO_REFRESH_REQ); |
2869 | } |
2870 | |
2871 | status = switch_core_session_read_video_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0); |
2872 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { |
2873 | break; |
2874 | } |
2875 | |
2876 | if (!switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) { |
2877 | if (switch_core_session_write_video_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { |
2878 | break; |
2879 | } |
2880 | } |
2881 | } |
2882 | switch_channel_clear_flag(channel_a, CF_VIDEO_PASSIVE); |
2883 | |
2884 | switch_thread_rwlock_unlock(vh->member_b->rwlock); |
2885 | switch_thread_rwlock_unlock(vh->member_a->rwlock); |
2886 | |
2887 | switch_core_session_rwunlock(session_a); |
2888 | switch_core_session_rwunlock(session_b); |
2889 | |
2890 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2890, ((void*)0), SWITCH_LOG_DEBUG, "%s video thread ended.\n", switch_channel_get_name(channel_a)); |
2891 | |
2892 | switch_thread_rwlock_unlock(conference->rwlock); |
2893 | |
2894 | vh->up = 0; |
2895 | return NULL((void*)0); |
2896 | } |
2897 | |
2898 | |
2899 | /* Main video monitor thread (1 per distinct conference room) */ |
2900 | static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thread, void *obj) |
2901 | { |
2902 | conference_obj_t *conference = (conference_obj_t *) obj; |
2903 | conference_member_t *imember; |
2904 | switch_frame_t *vid_frame = NULL((void*)0); |
2905 | switch_status_t status; |
2906 | int want_refresh = 0; |
2907 | int yield = 0; |
2908 | switch_core_session_t *session; |
2909 | char buf[65536]; |
2910 | conference_member_t *floor_holder = NULL((void*)0); |
2911 | |
2912 | conference->video_running = 1; |
2913 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2913, ((void*)0), SWITCH_LOG_DEBUG, "Video thread started for conference %s\n", conference->name); |
2914 | |
2915 | while (conference->video_running == 1 && globals.running && !switch_test_flag(conference, CFLAG_DESTRUCT)((conference)->flags & CFLAG_DESTRUCT)) { |
2916 | if (yield) { |
2917 | switch_yield(yield)switch_sleep(yield);; |
2918 | yield = 0; |
2919 | } |
2920 | |
2921 | switch_mutex_lock(conference->mutex); |
2922 | |
2923 | if (conference->video_floor_holder) { |
2924 | floor_holder = conference->video_floor_holder; |
2925 | } else { |
2926 | floor_holder = NULL((void*)0); |
2927 | } |
2928 | |
2929 | |
2930 | if (!floor_holder) { |
2931 | yield = 100000; |
2932 | goto do_continue; |
2933 | } |
2934 | |
2935 | if (!floor_holder->session || !floor_holder->channel || !switch_channel_test_flag(floor_holder->channel, CF_VIDEO)) { |
2936 | yield = 100000; |
2937 | goto do_continue; |
2938 | } |
2939 | |
2940 | session = floor_holder->session; |
2941 | |
2942 | if ((status = switch_core_session_read_lock(session)) == SWITCH_STATUS_SUCCESS) { |
2943 | switch_mutex_unlock(conference->mutex); |
2944 | if (!switch_channel_ready(switch_core_session_get_channel(session))switch_channel_test_ready(switch_core_session_get_channel(session ), SWITCH_TRUE, SWITCH_FALSE)) { |
2945 | status = SWITCH_STATUS_FALSE; |
2946 | } else { |
2947 | status = switch_core_session_read_video_frame(session, &vid_frame, SWITCH_IO_FLAG_NONE, 0); |
2948 | } |
2949 | switch_mutex_lock(conference->mutex); |
2950 | switch_core_session_rwunlock(session); |
2951 | } |
2952 | |
2953 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { |
2954 | yield = 100000; |
2955 | goto do_continue; |
2956 | } |
2957 | |
2958 | if (vid_frame && switch_test_flag(vid_frame, SFF_CNG)((vid_frame)->flags & SFF_CNG)) { |
2959 | yield = 10000; |
2960 | goto do_continue; |
2961 | } |
2962 | |
2963 | memcpy(buf, vid_frame->packet, vid_frame->packetlen); |
2964 | |
2965 | switch_mutex_unlock(conference->mutex); |
2966 | switch_mutex_lock(conference->mutex); |
2967 | want_refresh = 0; |
2968 | |
2969 | if (switch_test_flag(conference, CFLAG_FLOOR_CHANGE)((conference)->flags & CFLAG_FLOOR_CHANGE)) { |
2970 | switch_clear_flag(conference, CFLAG_FLOOR_CHANGE)(conference)->flags &= ~(CFLAG_FLOOR_CHANGE); |
2971 | } |
2972 | |
2973 | for (imember = conference->members; imember; imember = imember->next) { |
2974 | switch_core_session_t *isession = imember->session; |
2975 | switch_channel_t *ichannel; |
2976 | |
2977 | if (!isession || switch_core_session_read_lock(isession) != SWITCH_STATUS_SUCCESS) { |
2978 | continue; |
2979 | } |
2980 | |
2981 | ichannel = switch_core_session_get_channel(imember->session); |
2982 | |
2983 | if (switch_channel_test_flag(ichannel, CF_VIDEO_REFRESH_REQ)) { |
2984 | want_refresh++; |
2985 | switch_channel_clear_flag(ichannel, CF_VIDEO_REFRESH_REQ); |
2986 | } |
2987 | |
2988 | if (isession && switch_channel_test_flag(ichannel, CF_VIDEO)) { |
2989 | memcpy(vid_frame->packet, buf, vid_frame->packetlen); |
2990 | switch_core_session_write_video_frame(imember->session, vid_frame, SWITCH_IO_FLAG_NONE, 0); |
2991 | } |
2992 | |
2993 | switch_core_session_rwunlock(isession); |
2994 | } |
2995 | |
2996 | if (want_refresh && session) { |
2997 | switch_core_session_refresh_video(session); |
2998 | want_refresh = 0; |
2999 | } |
3000 | |
3001 | do_continue: |
3002 | switch_mutex_unlock(conference->mutex); |
3003 | } |
3004 | |
3005 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3005, ((void*)0), SWITCH_LOG_DEBUG, "Video thread ending for conference %s\n", conference->name); |
3006 | conference->video_running = 0; |
3007 | |
3008 | return NULL((void*)0); |
3009 | } |
3010 | |
3011 | static void conference_command_handler(switch_live_array_t *la, const char *cmd, const char *sessid, cJSON *jla, void *user_data) |
3012 | { |
3013 | } |
3014 | |
3015 | /* Main monitor thread (1 per distinct conference room) */ |
3016 | static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *obj) |
3017 | { |
3018 | conference_obj_t *conference = (conference_obj_t *) obj; |
3019 | conference_member_t *imember, *omember; |
3020 | uint32_t samples = switch_samples_per_packet(conference->rate, conference->interval)((uint32_t)((float)conference->rate / (1000.0f / (float)conference ->interval))); |
3021 | uint32_t bytes = samples * 2 * conference->channels; |
3022 | uint8_t ready = 0, total = 0; |
3023 | switch_timer_t timer = { 0 }; |
3024 | switch_event_t *event; |
3025 | uint8_t *file_frame; |
3026 | uint8_t *async_file_frame; |
3027 | int16_t *bptr; |
3028 | uint32_t x = 0; |
3029 | int32_t z = 0; |
3030 | int member_score_sum = 0; |
3031 | int divisor = 0; |
3032 | conference_cdr_node_t *np; |
3033 | |
3034 | if (!(divisor = conference->rate / 8000)) { |
3035 | divisor = 1; |
3036 | } |
3037 | |
3038 | file_frame = switch_core_alloc(conference->pool, SWITCH_RECOMMENDED_BUFFER_SIZE)switch_core_perform_alloc(conference->pool, 8192, "mod_conference.c" , (const char *)__func__, 3038); |
3039 | async_file_frame = switch_core_alloc(conference->pool, SWITCH_RECOMMENDED_BUFFER_SIZE)switch_core_perform_alloc(conference->pool, 8192, "mod_conference.c" , (const char *)__func__, 3039); |
3040 | |
3041 | if (switch_core_timer_init(&timer, conference->timer_name, conference->interval, samples, conference->pool) == SWITCH_STATUS_SUCCESS) { |
3042 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3042, ((void*)0), SWITCH_LOG_DEBUG, "Setup timer success interval: %u samples: %u\n", conference->interval, samples); |
3043 | } else { |
3044 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3044, ((void*)0), SWITCH_LOG_ERROR, "Timer Setup Failed. Conference Cannot Start\n"); |
3045 | return NULL((void*)0); |
3046 | } |
3047 | |
3048 | switch_mutex_lock(globals.hash_mutex); |
3049 | globals.threads++; |
3050 | switch_mutex_unlock(globals.hash_mutex); |
3051 | |
3052 | conference->auto_recording = 0; |
3053 | conference->record_count = 0; |
3054 | |
3055 | |
3056 | |
3057 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3057, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance"); |
3058 | conference_add_event_data(conference, event); |
3059 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-create"); |
3060 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3060, &event, ((void*)0)); |
3061 | |
3062 | if (switch_test_flag(conference, CFLAG_LIVEARRAY_SYNC)((conference)->flags & CFLAG_LIVEARRAY_SYNC)) { |
3063 | char *p; |
3064 | |
3065 | if (strchr(conference->name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conference->name) && ('@') == '\0' ? (char *) __rawmemchr (conference->name, '@') : __builtin_strchr (conference-> name, '@')))) { |
3066 | conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s", conference->name); |
3067 | conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s", conference->name); |
3068 | } else { |
3069 | conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s@%s", conference->name, conference->domain); |
3070 | conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s@%s", conference->name, conference->domain); |
3071 | } |
3072 | |
3073 | conference->la_name = switch_core_strdup(conference->pool, conference->name)switch_core_perform_strdup(conference->pool, conference-> name, "mod_conference.c", (const char *)__func__, 3073); |
3074 | if ((p = strchr(conference->la_name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conference->la_name) && ('@') == '\0' ? (char *) __rawmemchr (conference->la_name, '@') : __builtin_strchr (conference->la_name, '@'))))) { |
3075 | *p = '\0'; |
3076 | } |
3077 | |
3078 | switch_live_array_create(conference->la_event_channel, conference->la_name, globals.event_channel_id, &conference->la); |
3079 | switch_live_array_set_user_data(conference->la, conference); |
3080 | switch_live_array_set_command_handler(conference->la, conference_command_handler); |
3081 | } |
3082 | |
3083 | |
3084 | while (globals.running && !switch_test_flag(conference, CFLAG_DESTRUCT)((conference)->flags & CFLAG_DESTRUCT)) { |
3085 | switch_size_t file_sample_len = samples; |
3086 | switch_size_t file_data_len = samples * 2 * conference->channels; |
3087 | int has_file_data = 0, members_with_video = 0; |
3088 | uint32_t conf_energy = 0; |
3089 | int nomoh = 0; |
3090 | conference_member_t *floor_holder, *video_bridge_members[2] = { 0 }; |
3091 | |
3092 | /* Sync the conference to a single timing source */ |
3093 | if (switch_core_timer_next(&timer) != SWITCH_STATUS_SUCCESS) { |
3094 | switch_set_flag(conference, CFLAG_DESTRUCT)(conference)->flags |= (CFLAG_DESTRUCT); |
3095 | break; |
3096 | } |
3097 | |
3098 | switch_mutex_lock(conference->mutex); |
3099 | has_file_data = ready = total = 0; |
3100 | |
3101 | floor_holder = conference->floor_holder; |
3102 | |
3103 | /* Read one frame of audio from each member channel and save it for redistribution */ |
3104 | for (imember = conference->members; imember; imember = imember->next) { |
3105 | uint32_t buf_read = 0; |
3106 | total++; |
3107 | imember->read = 0; |
3108 | |
3109 | if (switch_test_flag(imember, MFLAG_RUNNING)((imember)->flags & MFLAG_RUNNING) && imember->session) { |
3110 | switch_channel_t *channel = switch_core_session_get_channel(imember->session); |
3111 | |
3112 | if ((!floor_holder || (imember->score_iir > SCORE_IIR_SPEAKING_MAX300 && (floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN100)))) {// && |
3113 | //(!switch_test_flag(conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) { |
3114 | floor_holder = imember; |
3115 | } |
3116 | |
3117 | if (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_test_flag(channel, CF_VIDEO)) { |
3118 | members_with_video++; |
3119 | |
3120 | if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE) && switch_test_flag(imember, MFLAG_VIDEO_BRIDGE)((imember)->flags & MFLAG_VIDEO_BRIDGE)) { |
3121 | if (!video_bridge_members[0]) { |
3122 | video_bridge_members[0] = imember; |
3123 | } else { |
3124 | video_bridge_members[1] = imember; |
3125 | } |
3126 | } |
3127 | } |
3128 | |
3129 | if (switch_test_flag(imember, MFLAG_NOMOH)((imember)->flags & MFLAG_NOMOH)) { |
3130 | nomoh++; |
3131 | } |
3132 | } |
3133 | |
3134 | switch_clear_flag_locked(imember, MFLAG_HAS_AUDIO)switch_mutex_lock(imember->flag_mutex); (imember)->flags &= ~(MFLAG_HAS_AUDIO); switch_mutex_unlock(imember->flag_mutex );; |
3135 | switch_mutex_lock(imember->audio_in_mutex); |
3136 | |
3137 | if (switch_buffer_inuse(imember->audio_buffer) >= bytes |
3138 | && (buf_read = (uint32_t) switch_buffer_read(imember->audio_buffer, imember->frame, bytes))) { |
3139 | imember->read = buf_read; |
3140 | switch_set_flag_locked(imember, MFLAG_HAS_AUDIO)((imember->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("imember->flag_mutex != ((void*)0)", "mod_conference.c", 3140, __PRETTY_FUNCTION__));switch_mutex_lock(imember->flag_mutex );(imember)->flags |= (MFLAG_HAS_AUDIO);switch_mutex_unlock (imember->flag_mutex);; |
3141 | ready++; |
3142 | } |
3143 | switch_mutex_unlock(imember->audio_in_mutex); |
3144 | } |
3145 | |
3146 | if (floor_holder != conference->floor_holder) { |
3147 | conference_set_floor_holder(conference, floor_holder); |
3148 | } |
3149 | |
3150 | if (conference->perpetual_sound && !conference->async_fnode) { |
3151 | conference_play_file(conference, conference->perpetual_sound, CONF_DEFAULT_LEADIN20, NULL((void*)0), 1); |
3152 | } else if (conference->moh_sound && ((nomoh == 0 && conference->count == 1) |
3153 | || switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) && !conference->async_fnode && !conference->fnode) { |
3154 | conference_play_file(conference, conference->moh_sound, CONF_DEFAULT_LEADIN20, NULL((void*)0), 1); |
3155 | } |
3156 | |
3157 | |
3158 | /* Find if no one talked for more than x number of second */ |
3159 | if (conference->terminate_on_silence && conference->count > 1) { |
3160 | int is_talking = 0; |
3161 | |
3162 | for (imember = conference->members; imember; imember = imember->next) { |
3163 | if (switch_epoch_time_now(NULL((void*)0)) - imember->join_time <= conference->terminate_on_silence) { |
3164 | is_talking++; |
3165 | } else if (imember->last_talking != 0 && switch_epoch_time_now(NULL((void*)0)) - imember->last_talking <= conference->terminate_on_silence) { |
3166 | is_talking++; |
3167 | } |
3168 | } |
3169 | if (is_talking == 0) { |
3170 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3170, ((void*)0), SWITCH_LOG_DEBUG, "Conference has been idle for over %d seconds, terminating\n", conference->terminate_on_silence); |
3171 | switch_set_flag(conference, CFLAG_DESTRUCT)(conference)->flags |= (CFLAG_DESTRUCT); |
3172 | } |
3173 | } |
3174 | |
3175 | /* Start auto recording if there's the minimum number of required participants. */ |
3176 | if (conference->auto_record && !conference->auto_recording && (conference->count >= conference->min_recording_participants)) { |
3177 | conference->auto_recording++; |
3178 | conference->record_count++; |
3179 | imember = conference->members; |
3180 | if (imember) { |
3181 | switch_channel_t *channel = switch_core_session_get_channel(imember->session); |
3182 | char *rfile = switch_channel_expand_variables(channel, conference->auto_record)switch_channel_expand_variables_check(channel, conference-> auto_record, ((void*)0), ((void*)0), 0); |
3183 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3183, ((void*)0), SWITCH_LOG_DEBUG, "Auto recording file: %s\n", rfile); |
3184 | launch_conference_record_thread(conference, rfile, SWITCH_TRUE); |
3185 | |
3186 | if (rfile != conference->auto_record) { |
3187 | conference->record_filename = switch_core_strdup(conference->pool, rfile)switch_core_perform_strdup(conference->pool, rfile, "mod_conference.c" , (const char *)__func__, 3187); |
3188 | switch_safe_free(rfile)if (rfile) {free(rfile);rfile=((void*)0);}; |
3189 | } else { |
3190 | conference->record_filename = switch_core_strdup(conference->pool, conference->auto_record)switch_core_perform_strdup(conference->pool, conference-> auto_record, "mod_conference.c", (const char *)__func__, 3190 ); |
3191 | } |
3192 | /* Set the conference recording variable for each member */ |
3193 | for (omember = conference->members; omember; omember = omember->next) { |
3194 | if (!omember->session) continue; |
3195 | channel = switch_core_session_get_channel(omember->session); |
3196 | switch_channel_set_variable(channel, "conference_recording", conference->record_filename)switch_channel_set_variable_var_check(channel, "conference_recording" , conference->record_filename, SWITCH_TRUE); |
3197 | } |
3198 | } else { |
3199 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3199, ((void*)0), SWITCH_LOG_ERROR, "Auto Record Failed. No members in conference.\n"); |
3200 | } |
3201 | } |
3202 | |
3203 | |
3204 | if (members_with_video) { |
3205 | if (conference->video_running != 1) { |
3206 | if (!switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE)) { |
3207 | launch_conference_video_thread(conference); |
3208 | } |
3209 | } |
3210 | |
3211 | if (conference->vh[0].up == 0 && |
3212 | conference->vh[1].up == 0 && |
3213 | video_bridge_members[0] && |
3214 | video_bridge_members[1] && |
3215 | switch_test_flag(video_bridge_members[0], MFLAG_RUNNING)((video_bridge_members[0])->flags & MFLAG_RUNNING) && |
3216 | switch_test_flag(video_bridge_members[1], MFLAG_RUNNING)((video_bridge_members[1])->flags & MFLAG_RUNNING) && |
3217 | switch_channel_ready(switch_core_session_get_channel(video_bridge_members[0]->session))switch_channel_test_ready(switch_core_session_get_channel(video_bridge_members [0]->session), SWITCH_TRUE, SWITCH_FALSE) && |
3218 | switch_channel_ready(switch_core_session_get_channel(video_bridge_members[1]->session))switch_channel_test_ready(switch_core_session_get_channel(video_bridge_members [1]->session), SWITCH_TRUE, SWITCH_FALSE) |
3219 | ) { |
3220 | conference->mh.up = 2; |
3221 | if (launch_conference_video_bridge_thread(video_bridge_members[0], video_bridge_members[1])) { |
3222 | conference->mh.up = 1; |
3223 | } else { |
3224 | conference->mh.up = -1; |
3225 | } |
3226 | } |
3227 | } |
3228 | |
3229 | /* If a file or speech event is being played */ |
3230 | if (conference->fnode && !switch_test_flag(conference->fnode, NFLAG_PAUSE)((conference->fnode)->flags & NFLAG_PAUSE)) { |
3231 | /* Lead in time */ |
3232 | if (conference->fnode->leadin) { |
3233 | conference->fnode->leadin--; |
3234 | } else if (!conference->fnode->done) { |
3235 | file_sample_len = samples; |
3236 | |
3237 | if (conference->fnode->type == NODE_TYPE_SPEECH) { |
3238 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_BLOCKING; |
3239 | switch_size_t speech_len = file_data_len; |
3240 | |
3241 | if (conference->fnode->al) { |
3242 | speech_len /= 2; |
3243 | } |
3244 | |
3245 | if (switch_core_speech_read_tts(conference->fnode->sh, file_frame, &speech_len, &flags) == SWITCH_STATUS_SUCCESS) { |
3246 | |
3247 | if (conference->fnode->al) { |
3248 | process_al(conference->fnode->al, file_frame, speech_len, conference->rate); |
3249 | } |
3250 | |
3251 | file_sample_len = file_data_len / 2 / conference->fnode->sh->channels; |
3252 | |
3253 | |
3254 | } else { |
3255 | file_sample_len = file_data_len = 0; |
3256 | } |
3257 | } else if (conference->fnode->type == NODE_TYPE_FILE) { |
3258 | switch_core_file_read(&conference->fnode->fh, file_frame, &file_sample_len); |
3259 | if (conference->fnode->fh.vol) { |
3260 | switch_change_sln_volume_granular((void *)file_frame, (uint32_t)file_sample_len * conference->fnode->fh.channels, |
3261 | conference->fnode->fh.vol); |
3262 | } |
3263 | if (conference->fnode->al) { |
3264 | process_al(conference->fnode->al, file_frame, file_sample_len * 2, conference->fnode->fh.samplerate); |
3265 | } |
3266 | } |
3267 | |
3268 | if (file_sample_len <= 0) { |
3269 | conference->fnode->done++; |
3270 | } else { |
3271 | has_file_data = 1; |
3272 | } |
3273 | } |
3274 | } |
3275 | |
3276 | if (conference->async_fnode) { |
3277 | /* Lead in time */ |
3278 | if (conference->async_fnode->leadin) { |
3279 | conference->async_fnode->leadin--; |
3280 | } else if (!conference->async_fnode->done) { |
3281 | file_sample_len = samples; |
3282 | switch_core_file_read(&conference->async_fnode->fh, async_file_frame, &file_sample_len); |
3283 | if (conference->async_fnode->al) { |
3284 | process_al(conference->async_fnode->al, file_frame, file_sample_len * 2, conference->async_fnode->fh.samplerate); |
3285 | } |
3286 | if (file_sample_len <= 0) { |
3287 | conference->async_fnode->done++; |
3288 | } else { |
3289 | if (has_file_data) { |
3290 | switch_size_t x; |
3291 | for (x = 0; x < file_sample_len * conference->channels; x++) { |
3292 | int32_t z; |
3293 | int16_t *muxed; |
3294 | |
3295 | muxed = (int16_t *) file_frame; |
3296 | bptr = (int16_t *) async_file_frame; |
3297 | z = muxed[x] + bptr[x]; |
3298 | switch_normalize_to_16bit(z)if (z > 32767) z = 32767; else if (z < -32768) z = -32768 ;; |
3299 | muxed[x] = (int16_t) z; |
3300 | } |
3301 | } else { |
3302 | memcpy(file_frame, async_file_frame, file_sample_len * 2 * conference->channels); |
3303 | has_file_data = 1; |
3304 | } |
3305 | } |
3306 | } |
3307 | } |
3308 | |
3309 | if (ready || has_file_data) { |
3310 | /* Use more bits in the main_frame to preserve the exact sum of the audio samples. */ |
3311 | int main_frame[SWITCH_RECOMMENDED_BUFFER_SIZE8192] = { 0 }; |
3312 | int16_t write_frame[SWITCH_RECOMMENDED_BUFFER_SIZE8192] = { 0 }; |
3313 | |
3314 | |
3315 | /* Init the main frame with file data if there is any. */ |
3316 | bptr = (int16_t *) file_frame; |
3317 | if (has_file_data && file_sample_len) { |
3318 | |
3319 | for (x = 0; x < bytes / 2; x++) { |
3320 | if (x <= file_sample_len * conference->channels) { |
3321 | main_frame[x] = (int32_t) bptr[x]; |
3322 | } else { |
3323 | memset(&main_frame[x], 255, sizeof(main_frame[x])); |
3324 | } |
3325 | } |
3326 | } |
3327 | |
3328 | member_score_sum = 0; |
3329 | conference->mux_loop_count = 0; |
3330 | conference->member_loop_count = 0; |
3331 | |
3332 | |
3333 | /* Copy audio from every member known to be producing audio into the main frame. */ |
3334 | for (omember = conference->members; omember; omember = omember->next) { |
3335 | conference->member_loop_count++; |
3336 | |
3337 | if (!(switch_test_flag(omember, MFLAG_RUNNING)((omember)->flags & MFLAG_RUNNING) && switch_test_flag(omember, MFLAG_HAS_AUDIO)((omember)->flags & MFLAG_HAS_AUDIO))) { |
3338 | continue; |
3339 | } |
3340 | |
3341 | if (conference->agc_level) { |
3342 | if (switch_test_flag(omember, MFLAG_TALKING)((omember)->flags & MFLAG_TALKING) && switch_test_flag(omember, MFLAG_CAN_SPEAK)((omember)->flags & MFLAG_CAN_SPEAK)) { |
3343 | member_score_sum += omember->score; |
3344 | conference->mux_loop_count++; |
3345 | } |
3346 | } |
3347 | |
3348 | bptr = (int16_t *) omember->frame; |
3349 | for (x = 0; x < omember->read / 2; x++) { |
3350 | main_frame[x] += (int32_t) bptr[x]; |
3351 | } |
3352 | } |
3353 | |
3354 | if (conference->agc_level && conference->member_loop_count) { |
3355 | conf_energy = 0; |
3356 | |
3357 | for (x = 0; x < bytes / 2; x++) { |
3358 | z = abs(main_frame[x]); |
3359 | switch_normalize_to_16bit(z)if (z > 32767) z = 32767; else if (z < -32768) z = -32768 ;; |
3360 | conf_energy += (int16_t) z; |
3361 | } |
3362 | |
3363 | conference->score = conf_energy / ((bytes / 2) / divisor) / conference->member_loop_count; |
3364 | |
3365 | conference->avg_tally += conference->score; |
3366 | conference->avg_score = conference->avg_tally / ++conference->avg_itt; |
3367 | if (!conference->avg_itt) conference->avg_tally = conference->score; |
3368 | } |
3369 | |
3370 | /* Create write frame once per member who is not deaf for each sample in the main frame |
3371 | check if our audio is involved and if so, subtract it from the sample so we don't hear ourselves. |
3372 | Since main frame was 32 bit int, we did not lose any detail, now that we have to convert to 16 bit we can |
3373 | cut it off at the min and max range if need be and write the frame to the output buffer. |
3374 | */ |
3375 | for (omember = conference->members; omember; omember = omember->next) { |
3376 | switch_size_t ok = 1; |
3377 | |
3378 | if (!switch_test_flag(omember, MFLAG_RUNNING)((omember)->flags & MFLAG_RUNNING)) { |
3379 | continue; |
3380 | } |
3381 | |
3382 | if (!switch_test_flag(omember, MFLAG_CAN_HEAR)((omember)->flags & MFLAG_CAN_HEAR)) { |
3383 | switch_mutex_lock(omember->audio_out_mutex); |
3384 | memset(write_frame, 255, bytes); |
3385 | ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes); |
3386 | switch_mutex_unlock(omember->audio_out_mutex); |
3387 | continue; |
3388 | } |
3389 | |
3390 | bptr = (int16_t *) omember->frame; |
3391 | |
3392 | for (x = 0; x < bytes / 2 ; x++) { |
3393 | z = main_frame[x]; |
3394 | |
3395 | /* bptr[x] represents my own contribution to this audio sample */ |
3396 | if (switch_test_flag(omember, MFLAG_HAS_AUDIO)((omember)->flags & MFLAG_HAS_AUDIO) && x <= omember->read / 2) { |
3397 | z -= (int32_t) bptr[x]; |
3398 | } |
3399 | |
3400 | /* when there are relationships, we have to do more work by scouring all the members to see if there are any |
3401 | reasons why we should not be hearing a paticular member, and if not, delete their samples as well. |
3402 | */ |
3403 | if (conference->relationship_total) { |
3404 | for (imember = conference->members; imember; imember = imember->next) { |
3405 | if (imember != omember && switch_test_flag(imember, MFLAG_HAS_AUDIO)((imember)->flags & MFLAG_HAS_AUDIO)) { |
3406 | conference_relationship_t *rel; |
3407 | switch_size_t found = 0; |
3408 | int16_t *rptr = (int16_t *) imember->frame; |
3409 | for (rel = imember->relationships; rel; rel = rel->next) { |
3410 | if ((rel->id == omember->id || rel->id == 0) && !switch_test_flag(rel, RFLAG_CAN_SPEAK)((rel)->flags & RFLAG_CAN_SPEAK)) { |
3411 | z -= (int32_t) rptr[x]; |
3412 | found = 1; |
3413 | break; |
3414 | } |
3415 | } |
3416 | if (!found) { |
3417 | for (rel = omember->relationships; rel; rel = rel->next) { |
3418 | if ((rel->id == imember->id || rel->id == 0) && !switch_test_flag(rel, RFLAG_CAN_HEAR)((rel)->flags & RFLAG_CAN_HEAR)) { |
3419 | z -= (int32_t) rptr[x]; |
3420 | break; |
3421 | } |
3422 | } |
3423 | } |
3424 | |
3425 | } |
3426 | } |
3427 | } |
3428 | |
3429 | /* Now we can convert to 16 bit. */ |
3430 | switch_normalize_to_16bit(z)if (z > 32767) z = 32767; else if (z < -32768) z = -32768 ;; |
3431 | write_frame[x] = (int16_t) z; |
3432 | } |
3433 | |
3434 | switch_mutex_lock(omember->audio_out_mutex); |
3435 | ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes); |
3436 | switch_mutex_unlock(omember->audio_out_mutex); |
3437 | |
3438 | if (!ok) { |
3439 | switch_mutex_unlock(conference->mutex); |
3440 | goto end; |
3441 | } |
3442 | } |
3443 | } else { /* There is no source audio. Push silence into all of the buffers */ |
3444 | int16_t write_frame[SWITCH_RECOMMENDED_BUFFER_SIZE8192] = { 0 }; |
3445 | |
3446 | if (conference->comfort_noise_level) { |
3447 | switch_generate_sln_silence(write_frame, samples, conference->channels, conference->comfort_noise_level); |
3448 | } else { |
3449 | memset(write_frame, 255, bytes); |
3450 | } |
3451 | |
3452 | for (omember = conference->members; omember; omember = omember->next) { |
3453 | switch_size_t ok = 1; |
3454 | |
3455 | if (!switch_test_flag(omember, MFLAG_RUNNING)((omember)->flags & MFLAG_RUNNING)) { |
3456 | continue; |
3457 | } |
3458 | |
3459 | switch_mutex_lock(omember->audio_out_mutex); |
3460 | ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes); |
3461 | switch_mutex_unlock(omember->audio_out_mutex); |
3462 | |
3463 | if (!ok) { |
3464 | switch_mutex_unlock(conference->mutex); |
3465 | goto end; |
3466 | } |
3467 | } |
3468 | } |
3469 | |
3470 | if (conference->async_fnode && conference->async_fnode->done) { |
3471 | switch_memory_pool_t *pool; |
3472 | conference_file_close(conference, conference->async_fnode); |
3473 | pool = conference->async_fnode->pool; |
3474 | conference->async_fnode = NULL((void*)0); |
3475 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 3475); |
3476 | } |
3477 | |
3478 | if (conference->fnode && conference->fnode->done) { |
3479 | conference_file_node_t *fnode; |
3480 | switch_memory_pool_t *pool; |
3481 | |
3482 | if (conference->fnode->type != NODE_TYPE_SPEECH) { |
3483 | conference_file_close(conference, conference->fnode); |
3484 | } |
3485 | |
3486 | fnode = conference->fnode; |
3487 | conference->fnode = conference->fnode->next; |
3488 | |
3489 | pool = fnode->pool; |
3490 | fnode = NULL((void*)0); |
3491 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 3491); |
3492 | } |
3493 | |
3494 | if (!conference->end_count && conference->endconf_time && |
3495 | switch_epoch_time_now(NULL((void*)0)) - conference->endconf_time > conference->endconf_grace_time) { |
3496 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3496, ((void*)0), SWITCH_LOG_DEBUG, "Conference %s: endconf grace time exceeded (%u)\n", |
3497 | conference->name, conference->endconf_grace_time); |
3498 | switch_set_flag(conference, CFLAG_DESTRUCT | CFLAG_ENDCONF_FORCED)(conference)->flags |= (CFLAG_DESTRUCT | CFLAG_ENDCONF_FORCED ); |
3499 | } |
3500 | |
3501 | switch_mutex_unlock(conference->mutex); |
3502 | } |
3503 | /* Rinse ... Repeat */ |
3504 | end: |
3505 | |
3506 | if (switch_test_flag(conference, CFLAG_OUTCALL)((conference)->flags & CFLAG_OUTCALL)) { |
3507 | conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; |
3508 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3508, ((void*)0), SWITCH_LOG_NOTICE, "Ending pending outcall channels for Conference: '%s'\n", conference->name); |
3509 | while(conference->originating) { |
3510 | switch_yield(200000)switch_sleep(200000);; |
3511 | } |
3512 | } |
3513 | |
3514 | conference_send_presence(conference); |
3515 | |
3516 | switch_mutex_lock(conference->mutex); |
3517 | conference_stop_file(conference, FILE_STOP_ASYNC); |
3518 | conference_stop_file(conference, FILE_STOP_ALL); |
3519 | |
3520 | for (np = conference->cdr_nodes; np; np = np->next) { |
3521 | if (np->var_event) { |
3522 | switch_event_destroy(&np->var_event); |
3523 | } |
3524 | } |
3525 | |
3526 | |
3527 | /* Close Unused Handles */ |
3528 | if (conference->fnode) { |
3529 | conference_file_node_t *fnode, *cur; |
3530 | switch_memory_pool_t *pool; |
3531 | |
3532 | fnode = conference->fnode; |
3533 | while (fnode) { |
3534 | cur = fnode; |
3535 | fnode = fnode->next; |
3536 | |
3537 | if (cur->type != NODE_TYPE_SPEECH) { |
3538 | conference_file_close(conference, cur); |
3539 | } |
3540 | |
3541 | pool = cur->pool; |
3542 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 3542); |
3543 | } |
3544 | conference->fnode = NULL((void*)0); |
3545 | } |
3546 | |
3547 | if (conference->async_fnode) { |
3548 | switch_memory_pool_t *pool; |
3549 | conference_file_close(conference, conference->async_fnode); |
3550 | pool = conference->async_fnode->pool; |
3551 | conference->async_fnode = NULL((void*)0); |
3552 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 3552); |
3553 | } |
3554 | |
3555 | switch_mutex_lock(conference->member_mutex); |
3556 | for (imember = conference->members; imember; imember = imember->next) { |
3557 | switch_channel_t *channel; |
3558 | |
3559 | if (!switch_test_flag(imember, MFLAG_NOCHANNEL)((imember)->flags & MFLAG_NOCHANNEL)) { |
3560 | channel = switch_core_session_get_channel(imember->session); |
3561 | |
3562 | if (!switch_false(switch_channel_get_variable(channel, "hangup_after_conference")switch_channel_get_variable_dup(channel, "hangup_after_conference" , SWITCH_TRUE, -1))) { |
3563 | /* add this little bit to preserve the bridge cause code in case of an early media call that */ |
3564 | /* never answers */ |
3565 | if (switch_test_flag(conference, CFLAG_ANSWERED)((conference)->flags & CFLAG_ANSWERED)) { |
3566 | switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(channel, "mod_conference.c", (const char *)__func__, 3566, SWITCH_CAUSE_NORMAL_CLEARING); |
3567 | } else { |
3568 | /* put actual cause code from outbound channel hangup here */ |
3569 | switch_channel_hangup(channel, conference->bridge_hangup_cause)switch_channel_perform_hangup(channel, "mod_conference.c", (const char *)__func__, 3569, conference->bridge_hangup_cause); |
3570 | } |
3571 | } |
3572 | } |
3573 | |
3574 | switch_clear_flag_locked(imember, MFLAG_RUNNING)switch_mutex_lock(imember->flag_mutex); (imember)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(imember->flag_mutex );; |
3575 | } |
3576 | switch_mutex_unlock(conference->member_mutex); |
3577 | switch_mutex_unlock(conference->mutex); |
3578 | |
3579 | if (conference->vh[0].up == 1) { |
3580 | conference->vh[0].up = -1; |
3581 | } |
3582 | |
3583 | if (conference->vh[1].up == 1) { |
3584 | conference->vh[1].up = -1; |
3585 | } |
3586 | |
3587 | while (conference->vh[0].up || conference->vh[1].up) { |
3588 | switch_cond_next(); |
3589 | } |
3590 | |
3591 | if (conference->video_running == 1) { |
3592 | conference->video_running = -1; |
3593 | while (conference->video_running) { |
3594 | switch_cond_next(); |
3595 | } |
3596 | } |
3597 | |
3598 | |
3599 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3599, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance"); |
3600 | conference_add_event_data(conference, event); |
3601 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-destroy"); |
3602 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3602, &event, ((void*)0)); |
3603 | |
3604 | switch_core_timer_destroy(&timer); |
3605 | switch_mutex_lock(globals.hash_mutex); |
3606 | if (switch_test_flag(conference, CFLAG_INHASH)((conference)->flags & CFLAG_INHASH)) { |
3607 | switch_core_hash_delete(globals.conference_hash, conference->name); |
3608 | } |
3609 | switch_mutex_unlock(globals.hash_mutex); |
3610 | |
3611 | /* Wait till everybody is out */ |
3612 | switch_clear_flag_locked(conference, CFLAG_RUNNING)switch_mutex_lock(conference->flag_mutex); (conference)-> flags &= ~(CFLAG_RUNNING); switch_mutex_unlock(conference ->flag_mutex);; |
3613 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3613, ((void*)0), SWITCH_LOG_DEBUG, "Write Lock ON\n"); |
3614 | switch_thread_rwlock_wrlock(conference->rwlock); |
3615 | switch_thread_rwlock_unlock(conference->rwlock); |
3616 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3616, ((void*)0), SWITCH_LOG_DEBUG, "Write Lock OFF\n"); |
3617 | |
3618 | if (conference->la) { |
3619 | switch_live_array_destroy(&conference->la); |
3620 | } |
3621 | |
3622 | if (conference->sh) { |
3623 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; |
3624 | switch_core_speech_close(&conference->lsh, &flags); |
3625 | conference->sh = NULL((void*)0); |
3626 | } |
3627 | |
3628 | conference->end_time = switch_epoch_time_now(NULL((void*)0)); |
3629 | conference_cdr_render(conference); |
3630 | |
3631 | if (conference->pool) { |
3632 | switch_memory_pool_t *pool = conference->pool; |
3633 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 3633); |
3634 | } |
3635 | |
3636 | switch_mutex_lock(globals.hash_mutex); |
3637 | globals.threads--; |
3638 | switch_mutex_unlock(globals.hash_mutex); |
3639 | |
3640 | return NULL((void*)0); |
3641 | } |
3642 | |
3643 | static void conference_loop_fn_floor_toggle(conference_member_t *member, caller_control_action_t *action) |
3644 | { |
3645 | if (member == NULL((void*)0)) return; |
3646 | |
3647 | conf_api_sub_floor(member, NULL((void*)0), NULL((void*)0)); |
3648 | } |
3649 | |
3650 | static void conference_loop_fn_vid_floor_toggle(conference_member_t *member, caller_control_action_t *action) |
3651 | { |
3652 | if (member == NULL((void*)0)) return; |
3653 | |
3654 | conf_api_sub_vid_floor(member, NULL((void*)0), NULL((void*)0)); |
3655 | } |
3656 | |
3657 | static void conference_loop_fn_vid_floor_force(conference_member_t *member, caller_control_action_t *action) |
3658 | { |
3659 | if (member == NULL((void*)0)) return; |
3660 | |
3661 | conf_api_sub_vid_floor(member, NULL((void*)0), "force"); |
3662 | } |
3663 | |
3664 | static void conference_loop_fn_mute_toggle(conference_member_t *member, caller_control_action_t *action) |
3665 | { |
3666 | if (member == NULL((void*)0)) |
3667 | return; |
3668 | |
3669 | if (switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
3670 | conf_api_sub_mute(member, NULL((void*)0), NULL((void*)0)); |
3671 | } else { |
3672 | conf_api_sub_unmute(member, NULL((void*)0), NULL((void*)0)); |
3673 | if (!switch_test_flag(member, MFLAG_CAN_HEAR)((member)->flags & MFLAG_CAN_HEAR)) { |
3674 | conf_api_sub_undeaf(member, NULL((void*)0), NULL((void*)0)); |
3675 | } |
3676 | } |
3677 | } |
3678 | |
3679 | static void conference_loop_fn_mute_on(conference_member_t *member, caller_control_action_t *action) |
3680 | { |
3681 | if (switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
3682 | conf_api_sub_mute(member, NULL((void*)0), NULL((void*)0)); |
3683 | } |
3684 | } |
3685 | |
3686 | static void conference_loop_fn_mute_off(conference_member_t *member, caller_control_action_t *action) |
3687 | { |
3688 | if (!switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
3689 | conf_api_sub_unmute(member, NULL((void*)0), NULL((void*)0)); |
3690 | if (!switch_test_flag(member, MFLAG_CAN_HEAR)((member)->flags & MFLAG_CAN_HEAR)) { |
3691 | conf_api_sub_undeaf(member, NULL((void*)0), NULL((void*)0)); |
3692 | } |
3693 | } |
3694 | } |
3695 | |
3696 | static void conference_loop_fn_lock_toggle(conference_member_t *member, caller_control_action_t *action) |
3697 | { |
3698 | switch_event_t *event; |
3699 | |
3700 | if (member == NULL((void*)0)) |
3701 | return; |
3702 | |
3703 | if (switch_test_flag(member->conference, CFLAG_WAIT_MOD)((member->conference)->flags & CFLAG_WAIT_MOD) && !switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD) ) |
3704 | return; |
3705 | |
3706 | if (!switch_test_flag(member->conference, CFLAG_LOCKED)((member->conference)->flags & CFLAG_LOCKED)) { |
3707 | if (member->conference->is_locked_sound) { |
3708 | conference_play_file(member->conference, member->conference->is_locked_sound, CONF_DEFAULT_LEADIN20, NULL((void*)0), 0); |
3709 | } |
3710 | |
3711 | switch_set_flag_locked(member->conference, CFLAG_LOCKED)((member->conference->flag_mutex != ((void*)0)) ? (void ) (0) : __assert_fail ("member->conference->flag_mutex != ((void*)0)" , "mod_conference.c", 3711, __PRETTY_FUNCTION__));switch_mutex_lock (member->conference->flag_mutex);(member->conference )->flags |= (CFLAG_LOCKED);switch_mutex_unlock(member-> conference->flag_mutex);; |
3712 | if (test_eflag(member->conference, EFLAG_LOCK)((member->conference)->eflags & EFLAG_LOCK) && |
3713 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3713, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3714 | conference_add_event_data(member->conference, event); |
3715 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "lock"); |
3716 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3716, &event, ((void*)0)); |
3717 | } |
3718 | } else { |
3719 | if (member->conference->is_unlocked_sound) { |
3720 | conference_play_file(member->conference, member->conference->is_unlocked_sound, CONF_DEFAULT_LEADIN20, NULL((void*)0), 0); |
3721 | } |
3722 | |
3723 | switch_clear_flag_locked(member->conference, CFLAG_LOCKED)switch_mutex_lock(member->conference->flag_mutex); (member ->conference)->flags &= ~(CFLAG_LOCKED); switch_mutex_unlock (member->conference->flag_mutex);; |
3724 | if (test_eflag(member->conference, EFLAG_UNLOCK)((member->conference)->eflags & EFLAG_UNLOCK) && |
3725 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3725, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3726 | conference_add_event_data(member->conference, event); |
3727 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "unlock"); |
3728 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3728, &event, ((void*)0)); |
3729 | } |
3730 | } |
3731 | |
3732 | } |
3733 | |
3734 | static void conference_loop_fn_deafmute_toggle(conference_member_t *member, caller_control_action_t *action) |
3735 | { |
3736 | if (member == NULL((void*)0)) |
3737 | return; |
3738 | |
3739 | if (switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
3740 | conf_api_sub_mute(member, NULL((void*)0), NULL((void*)0)); |
3741 | if (switch_test_flag(member, MFLAG_CAN_HEAR)((member)->flags & MFLAG_CAN_HEAR)) { |
3742 | conf_api_sub_deaf(member, NULL((void*)0), NULL((void*)0)); |
3743 | } |
3744 | } else { |
3745 | conf_api_sub_unmute(member, NULL((void*)0), NULL((void*)0)); |
3746 | if (!switch_test_flag(member, MFLAG_CAN_HEAR)((member)->flags & MFLAG_CAN_HEAR)) { |
3747 | conf_api_sub_undeaf(member, NULL((void*)0), NULL((void*)0)); |
3748 | } |
3749 | } |
3750 | } |
3751 | |
3752 | static void conference_loop_fn_energy_up(conference_member_t *member, caller_control_action_t *action) |
3753 | { |
3754 | char msg[512], str[30] = ""; |
3755 | switch_event_t *event; |
3756 | char *p; |
3757 | |
3758 | if (member == NULL((void*)0)) |
3759 | return; |
3760 | |
3761 | |
3762 | member->energy_level += 200; |
3763 | if (member->energy_level > 1800) { |
3764 | member->energy_level = 1800; |
3765 | } |
3766 | |
3767 | if (test_eflag(member->conference, EFLAG_ENERGY_LEVEL)((member->conference)->eflags & EFLAG_ENERGY_LEVEL) && |
3768 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3768, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3769 | conference_add_event_member_data(member, event); |
3770 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "energy-level"); |
3771 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level); |
3772 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3772, &event, ((void*)0)); |
3773 | } |
3774 | |
3775 | //switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); |
3776 | //conference_member_say(member, msg, 0); |
3777 | |
3778 | switch_snprintf(str, sizeof(str), "%d", abs(member->energy_level) / 200); |
3779 | for (p = str; p && *p; p++) { |
3780 | switch_snprintf(msg, sizeof(msg), "digits/%c.wav", *p); |
3781 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3782 | } |
3783 | |
3784 | |
3785 | |
3786 | |
3787 | } |
3788 | |
3789 | static void conference_loop_fn_energy_equ_conf(conference_member_t *member, caller_control_action_t *action) |
3790 | { |
3791 | char msg[512], str[30] = "", *p; |
3792 | switch_event_t *event; |
3793 | |
3794 | if (member == NULL((void*)0)) |
3795 | return; |
3796 | |
3797 | member->energy_level = member->conference->energy_level; |
3798 | |
3799 | if (test_eflag(member->conference, EFLAG_ENERGY_LEVEL)((member->conference)->eflags & EFLAG_ENERGY_LEVEL) && |
3800 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3800, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3801 | conference_add_event_member_data(member, event); |
3802 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "energy-level"); |
3803 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level); |
3804 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3804, &event, ((void*)0)); |
3805 | } |
3806 | |
3807 | //switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); |
3808 | //conference_member_say(member, msg, 0); |
3809 | |
3810 | switch_snprintf(str, sizeof(str), "%d", abs(member->energy_level) / 200); |
3811 | for (p = str; p && *p; p++) { |
3812 | switch_snprintf(msg, sizeof(msg), "digits/%c.wav", *p); |
3813 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3814 | } |
3815 | |
3816 | } |
3817 | |
3818 | static void conference_loop_fn_energy_dn(conference_member_t *member, caller_control_action_t *action) |
3819 | { |
3820 | char msg[512], str[30] = "", *p; |
3821 | switch_event_t *event; |
3822 | |
3823 | if (member == NULL((void*)0)) |
3824 | return; |
3825 | |
3826 | member->energy_level -= 200; |
3827 | if (member->energy_level < 0) { |
3828 | member->energy_level = 0; |
3829 | } |
3830 | |
3831 | if (test_eflag(member->conference, EFLAG_ENERGY_LEVEL)((member->conference)->eflags & EFLAG_ENERGY_LEVEL) && |
3832 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3832, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3833 | conference_add_event_member_data(member, event); |
3834 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "energy-level"); |
3835 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level); |
3836 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3836, &event, ((void*)0)); |
3837 | } |
3838 | |
3839 | //switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); |
3840 | //conference_member_say(member, msg, 0); |
3841 | |
3842 | switch_snprintf(str, sizeof(str), "%d", abs(member->energy_level) / 200); |
3843 | for (p = str; p && *p; p++) { |
3844 | switch_snprintf(msg, sizeof(msg), "digits/%c.wav", *p); |
3845 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3846 | } |
3847 | |
3848 | } |
3849 | |
3850 | static void conference_loop_fn_volume_talk_up(conference_member_t *member, caller_control_action_t *action) |
3851 | { |
3852 | char msg[512]; |
3853 | switch_event_t *event; |
3854 | |
3855 | if (member == NULL((void*)0)) |
3856 | return; |
3857 | |
3858 | member->volume_out_level++; |
3859 | switch_normalize_volume(member->volume_out_level)if (member->volume_out_level > 4) member->volume_out_level = 4; if (member->volume_out_level < -4) member->volume_out_level = -4;; |
3860 | |
3861 | if (test_eflag(member->conference, EFLAG_VOLUME_LEVEL)((member->conference)->eflags & EFLAG_VOLUME_LEVEL) && |
3862 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3862, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3863 | conference_add_event_member_data(member, event); |
3864 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-level"); |
3865 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level); |
3866 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3866, &event, ((void*)0)); |
3867 | } |
3868 | |
3869 | //switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); |
3870 | //conference_member_say(member, msg, 0); |
3871 | |
3872 | if (member->volume_out_level < 0) { |
3873 | switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_out_level); |
3874 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3875 | } |
3876 | |
3877 | switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_out_level)); |
3878 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3879 | |
3880 | } |
3881 | |
3882 | static void conference_loop_fn_volume_talk_zero(conference_member_t *member, caller_control_action_t *action) |
3883 | { |
3884 | char msg[512]; |
3885 | switch_event_t *event; |
3886 | |
3887 | if (member == NULL((void*)0)) |
3888 | return; |
3889 | |
3890 | member->volume_out_level = 0; |
3891 | |
3892 | if (test_eflag(member->conference, EFLAG_VOLUME_LEVEL)((member->conference)->eflags & EFLAG_VOLUME_LEVEL) && |
3893 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3893, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3894 | conference_add_event_member_data(member, event); |
3895 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-level"); |
3896 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level); |
3897 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3897, &event, ((void*)0)); |
3898 | } |
3899 | |
3900 | //switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); |
3901 | //conference_member_say(member, msg, 0); |
3902 | |
3903 | |
3904 | if (member->volume_out_level < 0) { |
3905 | switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_out_level); |
3906 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3907 | } |
3908 | |
3909 | switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_out_level)); |
3910 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3911 | } |
3912 | |
3913 | static void conference_loop_fn_volume_talk_dn(conference_member_t *member, caller_control_action_t *action) |
3914 | { |
3915 | char msg[512]; |
3916 | switch_event_t *event; |
3917 | |
3918 | if (member == NULL((void*)0)) |
3919 | return; |
3920 | |
3921 | member->volume_out_level--; |
3922 | switch_normalize_volume(member->volume_out_level)if (member->volume_out_level > 4) member->volume_out_level = 4; if (member->volume_out_level < -4) member->volume_out_level = -4;; |
3923 | |
3924 | if (test_eflag(member->conference, EFLAG_VOLUME_LEVEL)((member->conference)->eflags & EFLAG_VOLUME_LEVEL) && |
3925 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3925, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3926 | conference_add_event_member_data(member, event); |
3927 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-level"); |
3928 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level); |
3929 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3929, &event, ((void*)0)); |
3930 | } |
3931 | |
3932 | //switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); |
3933 | //conference_member_say(member, msg, 0); |
3934 | |
3935 | if (member->volume_out_level < 0) { |
3936 | switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_out_level); |
3937 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3938 | } |
3939 | |
3940 | switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_out_level)); |
3941 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3942 | } |
3943 | |
3944 | static void conference_loop_fn_volume_listen_up(conference_member_t *member, caller_control_action_t *action) |
3945 | { |
3946 | char msg[512]; |
3947 | switch_event_t *event; |
3948 | |
3949 | if (member == NULL((void*)0)) |
3950 | return; |
3951 | |
3952 | member->volume_in_level++; |
3953 | switch_normalize_volume(member->volume_in_level)if (member->volume_in_level > 4) member->volume_in_level = 4; if (member->volume_in_level < -4) member->volume_in_level = -4;; |
3954 | |
3955 | if (test_eflag(member->conference, EFLAG_GAIN_LEVEL)((member->conference)->eflags & EFLAG_GAIN_LEVEL) && |
3956 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3956, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3957 | conference_add_event_member_data(member, event); |
3958 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "gain-level"); |
3959 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level); |
3960 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3960, &event, ((void*)0)); |
3961 | } |
3962 | |
3963 | //switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); |
3964 | //conference_member_say(member, msg, 0); |
3965 | |
3966 | if (member->volume_in_level < 0) { |
3967 | switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_in_level); |
3968 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3969 | } |
3970 | |
3971 | switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_in_level)); |
3972 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
3973 | |
3974 | } |
3975 | |
3976 | static void conference_loop_fn_volume_listen_zero(conference_member_t *member, caller_control_action_t *action) |
3977 | { |
3978 | char msg[512]; |
3979 | switch_event_t *event; |
3980 | |
3981 | if (member == NULL((void*)0)) |
3982 | return; |
3983 | |
3984 | member->volume_in_level = 0; |
3985 | |
3986 | if (test_eflag(member->conference, EFLAG_GAIN_LEVEL)((member->conference)->eflags & EFLAG_GAIN_LEVEL) && |
3987 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3987, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
3988 | conference_add_event_member_data(member, event); |
3989 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "gain-level"); |
3990 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level); |
3991 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3991, &event, ((void*)0)); |
3992 | } |
3993 | |
3994 | //switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); |
3995 | //conference_member_say(member, msg, 0); |
3996 | |
3997 | if (member->volume_in_level < 0) { |
3998 | switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_in_level); |
3999 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
4000 | } |
4001 | |
4002 | switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_in_level)); |
4003 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
4004 | |
4005 | } |
4006 | |
4007 | static void conference_loop_fn_volume_listen_dn(conference_member_t *member, caller_control_action_t *action) |
4008 | { |
4009 | char msg[512]; |
4010 | switch_event_t *event; |
4011 | |
4012 | if (member == NULL((void*)0)) |
4013 | return; |
4014 | |
4015 | member->volume_in_level--; |
4016 | switch_normalize_volume(member->volume_in_level)if (member->volume_in_level > 4) member->volume_in_level = 4; if (member->volume_in_level < -4) member->volume_in_level = -4;; |
4017 | |
4018 | if (test_eflag(member->conference, EFLAG_GAIN_LEVEL)((member->conference)->eflags & EFLAG_GAIN_LEVEL) && |
4019 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 4019, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
4020 | conference_add_event_member_data(member, event); |
4021 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "gain-level"); |
4022 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level); |
4023 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 4023, &event, ((void*)0)); |
4024 | } |
4025 | |
4026 | //switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); |
4027 | //conference_member_say(member, msg, 0); |
4028 | |
4029 | if (member->volume_in_level < 0) { |
4030 | switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_in_level); |
4031 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
4032 | } |
4033 | |
4034 | switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_in_level)); |
4035 | conference_member_play_file(member, msg, 0, SWITCH_TRUE); |
4036 | } |
4037 | |
4038 | static void conference_loop_fn_event(conference_member_t *member, caller_control_action_t *action) |
4039 | { |
4040 | switch_event_t *event; |
4041 | if (test_eflag(member->conference, EFLAG_DTMF)((member->conference)->eflags & EFLAG_DTMF) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 4041, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
4042 | conference_add_event_member_data(member, event); |
4043 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "dtmf"); |
4044 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DTMF-Key", action->binded_dtmf); |
4045 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Data", action->expanded_data); |
4046 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 4046, &event, ((void*)0)); |
4047 | } |
4048 | } |
4049 | |
4050 | static void conference_loop_fn_transfer(conference_member_t *member, caller_control_action_t *action) |
4051 | { |
4052 | char *exten = NULL((void*)0); |
4053 | char *dialplan = "XML"; |
4054 | char *context = "default"; |
4055 | |
4056 | char *argv[3] = { 0 }; |
4057 | int argc; |
4058 | char *mydata = NULL((void*)0); |
4059 | switch_event_t *event; |
4060 | |
4061 | if (test_eflag(member->conference, EFLAG_DTMF)((member->conference)->eflags & EFLAG_DTMF) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 4061, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
4062 | conference_add_event_member_data(member, event); |
4063 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "transfer"); |
4064 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Dialplan", action->expanded_data); |
4065 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 4065, &event, ((void*)0)); |
4066 | } |
4067 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
4068 | |
4069 | if ((mydata = switch_core_session_strdup(member->session, action->expanded_data)switch_core_perform_session_strdup(member->session, action ->expanded_data, "mod_conference.c", (const char *)__func__ , 4069))) { |
4070 | if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { |
4071 | if (argc > 0) { |
4072 | exten = argv[0]; |
4073 | } |
4074 | if (argc > 1) { |
4075 | dialplan = argv[1]; |
4076 | } |
4077 | if (argc > 2) { |
4078 | context = argv[2]; |
4079 | } |
4080 | |
4081 | } else { |
4082 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4082, (const char*)(member->session), SWITCH_LOG_ERROR, "Empty transfer string [%s]\n", (char *) action->expanded_data); |
4083 | goto done; |
4084 | } |
4085 | } else { |
4086 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4086, (const char*)(member->session), SWITCH_LOG_ERROR, "Unable to allocate memory to duplicate transfer data.\n"); |
4087 | goto done; |
4088 | } |
4089 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4089, (const char*)(member->session), SWITCH_LOG_DEBUG, "Transfering to: %s, %s, %s\n", exten, dialplan, context); |
4090 | |
4091 | switch_ivr_session_transfer(member->session, exten, dialplan, context); |
4092 | |
4093 | done: |
4094 | return; |
4095 | } |
4096 | |
4097 | static void conference_loop_fn_exec_app(conference_member_t *member, caller_control_action_t *action) |
4098 | { |
4099 | char *app = NULL((void*)0); |
4100 | char *arg = ""; |
4101 | |
4102 | char *argv[2] = { 0 }; |
4103 | int argc; |
4104 | char *mydata = NULL((void*)0); |
4105 | switch_event_t *event = NULL((void*)0); |
4106 | switch_channel_t *channel = NULL((void*)0); |
4107 | |
4108 | if (!action->expanded_data) return; |
4109 | |
4110 | if (test_eflag(member->conference, EFLAG_DTMF)((member->conference)->eflags & EFLAG_DTMF) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 4110, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
4111 | conference_add_event_member_data(member, event); |
4112 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "execute_app"); |
4113 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", action->expanded_data); |
4114 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 4114, &event, ((void*)0)); |
4115 | } |
4116 | |
4117 | mydata = strdup(action->expanded_data)(__extension__ (__builtin_constant_p (action->expanded_data ) && ((size_t)(const void *)((action->expanded_data ) + 1) - (size_t)(const void *)(action->expanded_data) == 1 ) ? (((const char *) (action->expanded_data))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (action->expanded_data) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, action->expanded_data, __len); __retval ; })) : __strdup (action->expanded_data))); |
4118 | switch_assert(mydata)((mydata) ? (void) (0) : __assert_fail ("mydata", "mod_conference.c" , 4118, __PRETTY_FUNCTION__)); |
4119 | |
4120 | if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { |
4121 | if (argc > 0) { |
4122 | app = argv[0]; |
4123 | } |
4124 | if (argc > 1) { |
4125 | arg = argv[1]; |
4126 | } |
4127 | |
4128 | } else { |
4129 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4129, (const char*)(member->session), SWITCH_LOG_ERROR, "Empty execute app string [%s]\n", |
4130 | (char *) action->expanded_data); |
4131 | goto done; |
4132 | } |
4133 | |
4134 | if (!app) { |
4135 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4135, (const char*)(member->session), SWITCH_LOG_ERROR, "Unable to find application.\n"); |
4136 | goto done; |
4137 | } |
4138 | |
4139 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4139, (const char*)(member->session), SWITCH_LOG_DEBUG, "Execute app: %s, %s\n", app, arg); |
4140 | |
4141 | channel = switch_core_session_get_channel(member->session); |
4142 | |
4143 | switch_channel_set_app_flag(channel, CF_APP_TAGGED)switch_channel_set_app_flag_key("mod_conference.c", channel, CF_APP_TAGGED ); |
4144 | switch_core_session_set_read_codec(member->session, NULL((void*)0)); |
4145 | switch_core_session_execute_application(member->session, app, arg)switch_core_session_execute_application_get_flags(member-> session, app, arg, ((void*)0)); |
4146 | switch_core_session_set_read_codec(member->session, &member->read_codec); |
4147 | switch_channel_clear_app_flag(channel, CF_APP_TAGGED)switch_channel_clear_app_flag_key("mod_conference.c", channel , CF_APP_TAGGED); |
4148 | |
4149 | done: |
4150 | |
4151 | switch_safe_free(mydata)if (mydata) {free(mydata);mydata=((void*)0);}; |
4152 | |
4153 | return; |
4154 | } |
4155 | |
4156 | static void conference_loop_fn_hangup(conference_member_t *member, caller_control_action_t *action) |
4157 | { |
4158 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
4159 | } |
4160 | |
4161 | |
4162 | static int noise_gate_check(conference_member_t *member) |
4163 | { |
4164 | int r = 0; |
4165 | |
4166 | |
4167 | if (member->conference->agc_level && member->agc_volume_in_level != 0) { |
4168 | int target_score = 0; |
4169 | |
4170 | target_score = (member->energy_level + (25 * member->agc_volume_in_level)); |
4171 | |
4172 | if (target_score < 0) target_score = 0; |
4173 | |
4174 | r = (int)member->score > target_score; |
4175 | |
4176 | } else { |
4177 | r = (int32_t)member->score > member->energy_level; |
4178 | } |
4179 | |
4180 | return r; |
4181 | } |
4182 | |
4183 | static void clear_avg(conference_member_t *member) |
4184 | { |
4185 | |
4186 | member->avg_score = 0; |
4187 | member->avg_itt = 0; |
4188 | member->avg_tally = 0; |
4189 | member->agc_concur = 0; |
4190 | } |
4191 | |
4192 | static void check_agc_levels(conference_member_t *member) |
4193 | { |
4194 | int x = 0; |
4195 | |
4196 | if (!member->avg_score) return; |
4197 | |
4198 | if ((int)member->avg_score < member->conference->agc_level - 100) { |
4199 | member->agc_volume_in_level++; |
4200 | switch_normalize_volume_granular(member->agc_volume_in_level)if (member->agc_volume_in_level > 13) member->agc_volume_in_level = 13; if (member->agc_volume_in_level < -13) member-> agc_volume_in_level = -13;; |
4201 | x = 1; |
4202 | } else if ((int)member->avg_score > member->conference->agc_level + 100) { |
4203 | member->agc_volume_in_level--; |
4204 | switch_normalize_volume_granular(member->agc_volume_in_level)if (member->agc_volume_in_level > 13) member->agc_volume_in_level = 13; if (member->agc_volume_in_level < -13) member-> agc_volume_in_level = -13;; |
4205 | x = -1; |
4206 | } |
4207 | |
4208 | if (x) { |
4209 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 4209, ((void*)0), SWITCH_LOG_DEBUG7, |
4210 | "AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d %s\n", |
4211 | member->conference->name, |
4212 | member->id, member->conference->agc_level - member->avg_score, member->conference->agc_level, |
4213 | member->score, member->avg_score, member->agc_volume_in_level, x > 0 ? "+++" : "---"); |
4214 | |
4215 | clear_avg(member); |
4216 | } |
4217 | } |
4218 | |
4219 | static void member_check_channels(switch_frame_t *frame, conference_member_t *member, switch_bool_t in) |
4220 | { |
4221 | if (member->conference->channels != member->read_impl.number_of_channels || switch_test_flag(member, MFLAG_POSITIONAL)((member)->flags & MFLAG_POSITIONAL)) { |
4222 | uint32_t rlen; |
4223 | int from, to; |
4224 | |
4225 | if (in) { |
4226 | to = member->conference->channels; |
4227 | from = member->read_impl.number_of_channels; |
4228 | } else { |
4229 | from = member->conference->channels; |
4230 | to = member->read_impl.number_of_channels; |
4231 | } |
4232 | |
4233 | rlen = frame->datalen / 2 / from; |
4234 | |
4235 | if (in && frame->rate == 48000 && ((from == 1 && to == 2) || (from == 2 && to == 2)) && switch_test_flag(member, MFLAG_POSITIONAL)((member)->flags & MFLAG_POSITIONAL)) { |
4236 | if (from == 2 && to == 2) { |
4237 | switch_mux_channels((int16_t *) frame->data, rlen, 2, 1); |
4238 | frame->datalen /= 2; |
4239 | rlen = frame->datalen / 2; |
4240 | } |
4241 | |
4242 | process_al(member->al, frame->data, frame->datalen, frame->rate); |
4243 | } else { |
4244 | switch_mux_channels((int16_t *) frame->data, rlen, from, to); |
4245 | } |
4246 | |
4247 | frame->datalen = rlen * 2 * to; |
4248 | |
4249 | } |
4250 | } |
4251 | |
4252 | |
4253 | /* marshall frames from the call leg to the conference thread for muxing to other call legs */ |
4254 | static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *obj) |
4255 | { |
4256 | switch_event_t *event; |
4257 | conference_member_t *member = obj; |
4258 | switch_channel_t *channel; |
4259 | switch_status_t status; |
4260 | switch_frame_t *read_frame = NULL((void*)0); |
4261 | uint32_t hangover = 40, hangunder = 5, hangover_hits = 0, hangunder_hits = 0, diff_level = 400; |
4262 | switch_core_session_t *session = member->session; |
4263 | uint32_t flush_len, loops = 0; |
4264 | switch_frame_t tmp_frame = { 0 }; |
4265 | |
4266 | if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { |
4267 | goto end; |
4268 | } |
4269 | |
4270 | switch_assert(member != NULL)((member != ((void*)0)) ? (void) (0) : __assert_fail ("member != ((void*)0)" , "mod_conference.c", 4270, __PRETTY_FUNCTION__)); |
4271 | |
4272 | switch_clear_flag_locked(member, MFLAG_TALKING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_TALKING); switch_mutex_unlock(member->flag_mutex) ;; |
4273 | |
4274 | channel = switch_core_session_get_channel(session); |
4275 | |
4276 | switch_core_session_get_read_impl(session, &member->read_impl); |
4277 | |
4278 | switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "mod_conference.c" , (const char *)__func__, 4278); |
4279 | |
4280 | flush_len = switch_samples_per_packet(member->conference->rate, member->conference->interval)((uint32_t)((float)member->conference->rate / (1000.0f / (float)member->conference->interval))) * member->conference->channels * 10; |
4281 | |
4282 | /* As long as we have a valid read, feed that data into an input buffer where the conference thread will take it |
4283 | and mux it with any audio from other channels. */ |
4284 | |
4285 | while (switch_test_flag(member, MFLAG_RUNNING)((member)->flags & MFLAG_RUNNING) && switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) { |
4286 | |
4287 | if (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_test_app_flag(channel, CF_APP_TAGGED)switch_channel_test_app_flag_key("mod_conference.c", channel, CF_APP_TAGGED)) { |
4288 | switch_yield(100000)switch_sleep(100000);; |
4289 | continue; |
4290 | } |
4291 | |
4292 | /* Read a frame. */ |
4293 | status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); |
4294 | |
4295 | switch_mutex_lock(member->read_mutex); |
4296 | |
4297 | /* end the loop, if appropriate */ |
4298 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE) || !switch_test_flag(member, MFLAG_RUNNING)((member)->flags & MFLAG_RUNNING)) { |
4299 | switch_mutex_unlock(member->read_mutex); |
4300 | break; |
4301 | } |
4302 | |
4303 | if (switch_channel_test_flag(channel, CF_VIDEO) && !switch_test_flag(member, MFLAG_ACK_VIDEO)((member)->flags & MFLAG_ACK_VIDEO)) { |
4304 | switch_set_flag_locked(member, MFLAG_ACK_VIDEO)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 4304 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_ACK_VIDEO);switch_mutex_unlock (member->flag_mutex);; |
4305 | switch_channel_clear_flag(channel, CF_VIDEO_ECHO); |
4306 | switch_core_session_refresh_video(member->session); |
4307 | conference_set_video_floor_holder(member->conference, member, SWITCH_FALSE); |
4308 | } |
4309 | |
4310 | /* if we have caller digits, feed them to the parser to find an action */ |
4311 | if (switch_channel_has_dtmf(channel)) { |
4312 | char dtmf[128] = ""; |
4313 | |
4314 | switch_channel_dequeue_dtmf_string(channel, dtmf, sizeof(dtmf)); |
4315 | |
4316 | if (switch_test_flag(member, MFLAG_DIST_DTMF)((member)->flags & MFLAG_DIST_DTMF)) { |
4317 | conference_send_all_dtmf(member, member->conference, dtmf); |
4318 | } else if (member->dmachine) { |
4319 | char *p; |
4320 | char str[2] = ""; |
4321 | for (p = dtmf; p && *p; p++) { |
4322 | str[0] = *p; |
4323 | switch_ivr_dmachine_feed(member->dmachine, str, NULL((void*)0)); |
4324 | } |
4325 | } |
4326 | } else if (member->dmachine) { |
4327 | switch_ivr_dmachine_ping(member->dmachine, NULL((void*)0)); |
4328 | } |
4329 | |
4330 | if (switch_queue_size(member->dtmf_queue)) { |
4331 | switch_dtmf_t *dt; |
4332 | void *pop; |
4333 | |
4334 | if (switch_queue_trypop(member->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) { |
4335 | dt = (switch_dtmf_t *) pop; |
4336 | switch_core_session_send_dtmf(member->session, dt); |
4337 | free(dt); |
4338 | } |
4339 | } |
4340 | |
4341 | if (switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) { |
4342 | if (member->conference->agc_level) { |
4343 | member->nt_tally++; |
4344 | } |
4345 | |
4346 | if (hangunder_hits) { |
4347 | hangunder_hits--; |
4348 | } |
4349 | if (switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING)) { |
4350 | if (++hangover_hits >= hangover) { |
4351 | hangover_hits = hangunder_hits = 0; |
4352 | switch_clear_flag_locked(member, MFLAG_TALKING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_TALKING); switch_mutex_unlock(member->flag_mutex) ;; |
4353 | member_update_status_field(member); |
4354 | check_agc_levels(member); |
4355 | clear_avg(member); |
4356 | member->score_iir = 0; |
4357 | |
4358 | if (test_eflag(member->conference, EFLAG_STOP_TALKING)((member->conference)->eflags & EFLAG_STOP_TALKING) && |
4359 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 4359, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
4360 | conference_add_event_member_data(member, event); |
4361 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-talking"); |
4362 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 4362, &event, ((void*)0)); |
4363 | } |
4364 | } |
4365 | } |
4366 | |
4367 | goto do_continue; |
4368 | } |
4369 | |
4370 | if (member->nt_tally > (int32_t)(member->read_impl.actual_samples_per_second / member->read_impl.samples_per_packet) * 3) { |
4371 | member->agc_volume_in_level = 0; |
4372 | clear_avg(member); |
4373 | } |
4374 | |
4375 | /* Check for input volume adjustments */ |
4376 | if (!member->conference->agc_level) { |
4377 | member->conference->agc_level = 0; |
4378 | clear_avg(member); |
4379 | } |
4380 | |
4381 | |
4382 | /* if the member can speak, compute the audio energy level and */ |
4383 | /* generate events when the level crosses the threshold */ |
4384 | if ((switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) || switch_test_flag(member, MFLAG_MUTE_DETECT)((member)->flags & MFLAG_MUTE_DETECT))) { |
4385 | uint32_t energy = 0, i = 0, samples = 0, j = 0; |
4386 | int16_t *data; |
4387 | int agc_period = (member->read_impl.actual_samples_per_second / member->read_impl.samples_per_packet) / 4; |
4388 | |
4389 | |
4390 | data = read_frame->data; |
4391 | member->score = 0; |
4392 | |
4393 | if (member->volume_in_level) { |
4394 | switch_change_sln_volume(read_frame->data, (read_frame->datalen / 2) * member->conference->channels, member->volume_in_level); |
4395 | } |
4396 | |
4397 | if (member->agc_volume_in_level) { |
4398 | switch_change_sln_volume_granular(read_frame->data, (read_frame->datalen / 2) * member->conference->channels, member->agc_volume_in_level); |
4399 | } |
4400 | |
4401 | if ((samples = read_frame->datalen / sizeof(*data) / member->read_impl.number_of_channels)) { |
4402 | for (i = 0; i < samples; i++) { |
4403 | energy += abs(data[j]); |
4404 | j += member->read_impl.number_of_channels; |
4405 | } |
4406 | |
4407 | member->score = energy / samples; |
4408 | } |
4409 | |
4410 | if (member->vol_period) { |
4411 | member->vol_period--; |
4412 | } |
4413 | |
4414 | if (member->conference->agc_level && member->score && |
4415 | switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) && |
4416 | noise_gate_check(member) |
4417 | ) { |
4418 | int last_shift = abs((int)(member->last_score - member->score)); |
4419 | |
4420 | if (member->score && member->last_score && last_shift > 900) { |
4421 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 4421, ((void*)0), SWITCH_LOG_DEBUG7, |
4422 | "AGC %s:%d drop anomalous shift of %d\n", |
4423 | member->conference->name, |
4424 | member->id, last_shift); |
4425 | |
4426 | } else { |
4427 | member->avg_tally += member->score; |
4428 | member->avg_itt++; |
4429 | if (!member->avg_itt) member->avg_itt++; |
4430 | member->avg_score = member->avg_tally / member->avg_itt; |
4431 | } |
4432 | |
4433 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 4433, ((void*)0), SWITCH_LOG_DEBUG7, |
4434 | "AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d\n", |
4435 | member->conference->name, |
4436 | member->id, member->conference->agc_level - member->avg_score, member->conference->agc_level, |
4437 | member->score, member->avg_score, member->agc_volume_in_level); |
4438 | |
4439 | if (++member->agc_concur >= agc_period) { |
4440 | if (!member->vol_period) { |
4441 | check_agc_levels(member); |
4442 | } |
4443 | member->agc_concur = 0; |
4444 | } |
4445 | } else { |
4446 | member->nt_tally++; |
4447 | } |
4448 | |
4449 | member->score_iir = (int) (((1.0 - SCORE_DECAY0.8) * (float) member->score) + (SCORE_DECAY0.8 * (float) member->score_iir)); |
4450 | |
4451 | if (member->score_iir > SCORE_MAX_IIR25000) { |
4452 | member->score_iir = SCORE_MAX_IIR25000; |
4453 | } |
4454 | |
4455 | if (noise_gate_check(member)) { |
4456 | uint32_t diff = member->score - member->energy_level; |
4457 | if (hangover_hits) { |
4458 | hangover_hits--; |
4459 | } |
4460 | |
4461 | if (member->conference->agc_level) { |
4462 | member->nt_tally = 0; |
4463 | } |
4464 | |
4465 | if (diff >= diff_level || ++hangunder_hits >= hangunder) { |
4466 | |
4467 | hangover_hits = hangunder_hits = 0; |
4468 | member->last_talking = switch_epoch_time_now(NULL((void*)0)); |
4469 | |
4470 | if (!switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING)) { |
4471 | switch_set_flag_locked(member, MFLAG_TALKING)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 4471 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_TALKING);switch_mutex_unlock(member ->flag_mutex);; |
4472 | member_update_status_field(member); |
4473 | if (test_eflag(member->conference, EFLAG_START_TALKING)((member->conference)->eflags & EFLAG_START_TALKING ) && switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) && |
4474 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 4474, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
4475 | conference_add_event_member_data(member, event); |
4476 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "start-talking"); |
4477 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 4477, &event, ((void*)0)); |
4478 | } |
4479 | |
4480 | if (switch_test_flag(member, MFLAG_MUTE_DETECT)((member)->flags & MFLAG_MUTE_DETECT) && !switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
4481 | |
4482 | if (!zstr(member->conference->mute_detect_sound)_zstr(member->conference->mute_detect_sound)) { |
4483 | switch_set_flag(member, MFLAG_INDICATE_MUTE_DETECT)(member)->flags |= (MFLAG_INDICATE_MUTE_DETECT); |
4484 | } |
4485 | |
4486 | if (test_eflag(member->conference, EFLAG_MUTE_DETECT)((member->conference)->eflags & EFLAG_MUTE_DETECT) && |
4487 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 4487, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
4488 | conference_add_event_member_data(member, event); |
4489 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "mute-detect"); |
4490 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 4490, &event, ((void*)0)); |
4491 | } |
4492 | } |
4493 | } |
4494 | } |
4495 | } else { |
4496 | if (hangunder_hits) { |
4497 | hangunder_hits--; |
4498 | } |
4499 | |
4500 | if (member->conference->agc_level) { |
4501 | member->nt_tally++; |
4502 | } |
4503 | |
4504 | if (switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING) && switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
4505 | switch_event_t *event; |
4506 | if (++hangover_hits >= hangover) { |
4507 | hangover_hits = hangunder_hits = 0; |
4508 | switch_clear_flag_locked(member, MFLAG_TALKING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_TALKING); switch_mutex_unlock(member->flag_mutex) ;; |
4509 | member_update_status_field(member); |
4510 | check_agc_levels(member); |
4511 | clear_avg(member); |
4512 | |
4513 | if (test_eflag(member->conference, EFLAG_STOP_TALKING)((member->conference)->eflags & EFLAG_STOP_TALKING) && |
4514 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 4514, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
4515 | conference_add_event_member_data(member, event); |
4516 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-talking"); |
4517 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 4517, &event, ((void*)0)); |
4518 | } |
4519 | } |
4520 | } |
4521 | } |
4522 | |
4523 | |
4524 | member->last_score = member->score; |
4525 | } |
4526 | |
4527 | loops++; |
4528 | |
4529 | if (switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) { |
4530 | switch_channel_clear_flag(member->channel, CF_CONFERENCE_RESET_MEDIA); |
4531 | |
4532 | if (loops > 500) { |
4533 | member->loop_loop = 1; |
4534 | |
4535 | if (setup_media(member, member->conference)) { |
4536 | break; |
4537 | } |
4538 | } |
4539 | |
4540 | } |
4541 | |
4542 | /* skip frames that are not actual media or when we are muted or silent */ |
4543 | if ((switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING) || member->energy_level == 0 || switch_test_flag(member->conference, CFLAG_AUDIO_ALWAYS)((member->conference)->flags & CFLAG_AUDIO_ALWAYS)) |
4544 | && switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) && !switch_test_flag(member->conference, CFLAG_WAIT_MOD)((member->conference)->flags & CFLAG_WAIT_MOD) |
4545 | && (member->conference->count > 1 || (member->conference->record_count && member->conference->count >= member->conference->min_recording_participants))) { |
4546 | switch_audio_resampler_t *read_resampler = member->read_resampler; |
4547 | void *data; |
4548 | uint32_t datalen; |
4549 | |
4550 | if (read_resampler) { |
4551 | int16_t *bptr = (int16_t *) read_frame->data; |
4552 | int len = (int) read_frame->datalen; |
4553 | |
4554 | switch_resample_process(read_resampler, bptr, len / 2 / member->read_impl.number_of_channels); |
4555 | memcpy(member->resample_out, read_resampler->to, read_resampler->to_len * 2 * member->read_impl.number_of_channels); |
4556 | len = read_resampler->to_len * 2 * member->read_impl.number_of_channels; |
4557 | datalen = len; |
4558 | data = member->resample_out; |
4559 | } else { |
4560 | data = read_frame->data; |
4561 | datalen = read_frame->datalen; |
4562 | } |
4563 | |
4564 | tmp_frame.data = data; |
4565 | tmp_frame.datalen = datalen; |
4566 | tmp_frame.rate = member->conference->rate; |
4567 | member_check_channels(&tmp_frame, member, SWITCH_TRUE); |
4568 | |
4569 | |
4570 | if (datalen) { |
4571 | switch_size_t ok = 1; |
4572 | |
4573 | /* Write the audio into the input buffer */ |
4574 | switch_mutex_lock(member->audio_in_mutex); |
4575 | if (switch_buffer_inuse(member->audio_buffer) > flush_len) { |
4576 | switch_buffer_zero(member->audio_buffer); |
4577 | switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "mod_conference.c" , (const char *)__func__, 4577); |
4578 | } |
4579 | ok = switch_buffer_write(member->audio_buffer, tmp_frame.data, tmp_frame.datalen); |
4580 | switch_mutex_unlock(member->audio_in_mutex); |
4581 | if (!ok) { |
4582 | switch_mutex_unlock(member->read_mutex); |
4583 | break; |
4584 | } |
4585 | } |
4586 | } |
4587 | |
4588 | do_continue: |
4589 | |
4590 | switch_mutex_unlock(member->read_mutex); |
4591 | |
4592 | } |
4593 | |
4594 | if (switch_queue_size(member->dtmf_queue)) { |
4595 | switch_dtmf_t *dt; |
4596 | void *pop; |
4597 | |
4598 | while (switch_queue_trypop(member->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) { |
4599 | dt = (switch_dtmf_t *) pop; |
4600 | free(dt); |
4601 | } |
4602 | } |
4603 | |
4604 | |
4605 | switch_resample_destroy(&member->read_resampler); |
4606 | switch_core_session_rwunlock(session); |
4607 | |
4608 | end: |
4609 | |
4610 | switch_clear_flag_locked(member, MFLAG_ITHREAD)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_ITHREAD); switch_mutex_unlock(member->flag_mutex) ;; |
4611 | |
4612 | return NULL((void*)0); |
4613 | } |
4614 | |
4615 | |
4616 | static void member_add_file_data(conference_member_t *member, int16_t *data, switch_size_t file_data_len) |
4617 | { |
4618 | switch_size_t file_sample_len; |
4619 | int16_t file_frame[SWITCH_RECOMMENDED_BUFFER_SIZE8192] = { 0 }; |
4620 | |
4621 | |
4622 | switch_mutex_lock(member->fnode_mutex); |
4623 | |
4624 | if (!member->fnode) { |
4625 | goto done; |
4626 | } |
4627 | |
4628 | file_sample_len = file_data_len / 2 / member->conference->channels; |
4629 | |
4630 | /* if we are done, clean it up */ |
4631 | if (member->fnode->done) { |
4632 | conference_file_node_t *fnode; |
4633 | switch_memory_pool_t *pool; |
4634 | |
4635 | if (member->fnode->type != NODE_TYPE_SPEECH) { |
4636 | conference_file_close(member->conference, member->fnode); |
4637 | } |
4638 | |
4639 | fnode = member->fnode; |
4640 | member->fnode = member->fnode->next; |
4641 | |
4642 | pool = fnode->pool; |
4643 | fnode = NULL((void*)0); |
4644 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 4644); |
4645 | } else if(!switch_test_flag(member->fnode, NFLAG_PAUSE)((member->fnode)->flags & NFLAG_PAUSE)) { |
4646 | /* skip this frame until leadin time has expired */ |
4647 | if (member->fnode->leadin) { |
4648 | member->fnode->leadin--; |
4649 | } else { |
4650 | if (member->fnode->type == NODE_TYPE_SPEECH) { |
4651 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_BLOCKING; |
4652 | switch_size_t speech_len = file_data_len; |
4653 | |
4654 | if (member->fnode->al) { |
4655 | speech_len /= 2; |
4656 | } |
4657 | |
4658 | if (switch_core_speech_read_tts(member->fnode->sh, file_frame, &speech_len, &flags) == SWITCH_STATUS_SUCCESS) { |
4659 | file_sample_len = file_data_len / 2 / member->conference->channels; |
4660 | } else { |
4661 | file_sample_len = file_data_len = 0; |
4662 | } |
4663 | } else if (member->fnode->type == NODE_TYPE_FILE) { |
4664 | switch_core_file_read(&member->fnode->fh, file_frame, &file_sample_len); |
4665 | file_data_len = file_sample_len * 2 * member->fnode->fh.channels; |
Value stored to 'file_data_len' is never read | |
4666 | } |
4667 | |
4668 | if (file_sample_len <= 0) { |
4669 | member->fnode->done++; |
4670 | } else { /* there is file node data to mix into the frame */ |
4671 | uint32_t i; |
4672 | int32_t sample; |
4673 | |
4674 | /* Check for output volume adjustments */ |
4675 | if (member->volume_out_level) { |
4676 | switch_change_sln_volume(file_frame, (uint32_t)file_sample_len * member->conference->channels, member->volume_out_level); |
4677 | } |
4678 | |
4679 | if (member->fnode->al) { |
4680 | process_al(member->fnode->al, file_frame, file_sample_len * 2, member->conference->rate); |
4681 | } |
4682 | |
4683 | for (i = 0; i < (int)file_sample_len * member->conference->channels; i++) { |
4684 | if (member->fnode->mux) { |
4685 | sample = data[i] + file_frame[i]; |
4686 | switch_normalize_to_16bit(sample)if (sample > 32767) sample = 32767; else if (sample < - 32768) sample = -32768;; |
4687 | data[i] = (int16_t)sample; |
4688 | } else { |
4689 | data[i] = file_frame[i]; |
4690 | } |
4691 | } |
4692 | |
4693 | } |
4694 | } |
4695 | } |
4696 | |
4697 | done: |
4698 | |
4699 | switch_mutex_unlock(member->fnode_mutex); |
4700 | } |
4701 | |
4702 | |
4703 | |
4704 | /* launch an input thread for the call leg */ |
4705 | static void launch_conference_loop_input(conference_member_t *member, switch_memory_pool_t *pool) |
4706 | { |
4707 | switch_threadattr_t *thd_attr = NULL((void*)0); |
4708 | |
4709 | if (member == NULL((void*)0) || member->input_thread) |
4710 | return; |
4711 | |
4712 | switch_threadattr_create(&thd_attr, pool); |
4713 | switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024); |
4714 | switch_set_flag_locked(member, MFLAG_ITHREAD)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 4714 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_ITHREAD);switch_mutex_unlock(member ->flag_mutex);; |
4715 | if (switch_thread_create(&member->input_thread, thd_attr, conference_loop_input, member, pool) != SWITCH_STATUS_SUCCESS) { |
4716 | switch_clear_flag_locked(member, MFLAG_ITHREAD)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_ITHREAD); switch_mutex_unlock(member->flag_mutex) ;; |
4717 | } |
4718 | } |
4719 | |
4720 | /* marshall frames from the conference (or file or tts output) to the call leg */ |
4721 | /* NB. this starts the input thread after some initial setup for the call leg */ |
4722 | static void conference_loop_output(conference_member_t *member) |
4723 | { |
4724 | switch_channel_t *channel; |
4725 | switch_frame_t write_frame = { 0 }; |
4726 | uint8_t *data = NULL((void*)0); |
4727 | switch_timer_t timer = { 0 }; |
4728 | uint32_t interval; |
4729 | uint32_t samples; |
4730 | //uint32_t csamples; |
4731 | uint32_t tsamples; |
4732 | uint32_t flush_len; |
4733 | uint32_t low_count, bytes; |
4734 | call_list_t *call_list, *cp; |
4735 | switch_codec_implementation_t read_impl = { 0 }; |
4736 | int sanity; |
4737 | switch_status_t st; |
4738 | |
4739 | switch_core_session_get_read_impl(member->session, &read_impl); |
4740 | |
4741 | |
4742 | channel = switch_core_session_get_channel(member->session); |
4743 | interval = read_impl.microseconds_per_packet / 1000; |
4744 | samples = switch_samples_per_packet(member->conference->rate, interval)((uint32_t)((float)member->conference->rate / (1000.0f / (float)interval))); |
4745 | //csamples = samples; |
4746 | tsamples = member->orig_read_impl.samples_per_packet; |
4747 | low_count = 0; |
4748 | bytes = samples * 2 * member->conference->channels; |
4749 | call_list = NULL((void*)0); |
4750 | cp = NULL((void*)0); |
4751 | |
4752 | member->loop_loop = 0; |
4753 | |
4754 | switch_assert(member->conference != NULL)((member->conference != ((void*)0)) ? (void) (0) : __assert_fail ("member->conference != ((void*)0)", "mod_conference.c", 4754 , __PRETTY_FUNCTION__)); |
4755 | |
4756 | flush_len = switch_samples_per_packet(member->conference->rate, member->conference->interval)((uint32_t)((float)member->conference->rate / (1000.0f / (float)member->conference->interval))) * 10 * member->conference->channels; |
4757 | |
4758 | if (switch_core_timer_init(&timer, member->conference->timer_name, interval, tsamples, NULL((void*)0)) != SWITCH_STATUS_SUCCESS) { |
4759 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4759, (const char*)(member->session), SWITCH_LOG_ERROR, "Timer Setup Failed. Conference Cannot Start\n"); |
4760 | return; |
4761 | } |
4762 | |
4763 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4763, (const char*)(member->session), SWITCH_LOG_DEBUG, "Setup timer %s success interval: %u samples: %u\n", |
4764 | member->conference->timer_name, interval, tsamples); |
4765 | |
4766 | |
4767 | write_frame.data = data = switch_core_session_alloc(member->session, SWITCH_RECOMMENDED_BUFFER_SIZE)switch_core_perform_session_alloc(member->session, 8192, "mod_conference.c" , (const char *)__func__, 4767); |
4768 | write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE8192; |
4769 | |
4770 | |
4771 | write_frame.codec = &member->write_codec; |
4772 | |
4773 | /* Start the input thread */ |
4774 | launch_conference_loop_input(member, switch_core_session_get_pool(member->session)); |
4775 | |
4776 | if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) { |
4777 | const char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name")switch_channel_get_variable_dup(channel, "conference_auto_outcall_caller_id_name" , SWITCH_TRUE, -1); |
4778 | const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number")switch_channel_get_variable_dup(channel, "conference_auto_outcall_caller_id_number" , SWITCH_TRUE, -1); |
4779 | const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout")switch_channel_get_variable_dup(channel, "conference_auto_outcall_timeout" , SWITCH_TRUE, -1); |
4780 | const char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags")switch_channel_get_variable_dup(channel, "conference_auto_outcall_flags" , SWITCH_TRUE, -1); |
4781 | const char *profile = switch_channel_get_variable(channel, "conference_auto_outcall_profile")switch_channel_get_variable_dup(channel, "conference_auto_outcall_profile" , SWITCH_TRUE, -1); |
4782 | const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce")switch_channel_get_variable_dup(channel, "conference_auto_outcall_announce" , SWITCH_TRUE, -1); |
4783 | const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix")switch_channel_get_variable_dup(channel, "conference_auto_outcall_prefix" , SWITCH_TRUE, -1); |
4784 | const char *maxwait = switch_channel_get_variable(channel, "conference_auto_outcall_maxwait")switch_channel_get_variable_dup(channel, "conference_auto_outcall_maxwait" , SWITCH_TRUE, -1); |
4785 | const char *delimiter_val = switch_channel_get_variable(channel, "conference_auto_outcall_delimiter")switch_channel_get_variable_dup(channel, "conference_auto_outcall_delimiter" , SWITCH_TRUE, -1); |
4786 | int to = 60; |
4787 | int wait_sec = 2; |
4788 | int loops = 0; |
4789 | |
4790 | if (ann && !switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ)) { |
4791 | member->conference->special_announce = switch_core_strdup(member->conference->pool, ann)switch_core_perform_strdup(member->conference->pool, ann , "mod_conference.c", (const char *)__func__, 4791); |
4792 | } |
4793 | |
4794 | switch_channel_set_private(channel, "_conference_autocall_list_", NULL((void*)0)); |
4795 | |
4796 | switch_set_flag(member->conference, CFLAG_OUTCALL)(member->conference)->flags |= (CFLAG_OUTCALL); |
4797 | |
4798 | if (toval) { |
4799 | to = atoi(toval); |
4800 | if (to < 10 || to > 500) { |
4801 | to = 60; |
4802 | } |
4803 | } |
4804 | |
4805 | for (cp = call_list; cp; cp = cp->next) { |
4806 | int argc; |
4807 | char *argv[512] = { 0 }; |
4808 | char *cpstr = strdup(cp->string)(__extension__ (__builtin_constant_p (cp->string) && ((size_t)(const void *)((cp->string) + 1) - (size_t)(const void *)(cp->string) == 1) ? (((const char *) (cp->string ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (cp->string) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, cp->string, __len); __retval; } )) : __strdup (cp->string))); |
4809 | int x = 0; |
4810 | |
4811 | switch_assert(cpstr)((cpstr) ? (void) (0) : __assert_fail ("cpstr", "mod_conference.c" , 4811, __PRETTY_FUNCTION__)); |
4812 | if (!zstr(delimiter_val)_zstr(delimiter_val) && strlen(delimiter_val) == 1) { |
4813 | char delimiter = *delimiter_val; |
4814 | argc = switch_separate_string(cpstr, delimiter, argv, (sizeof(argv) / sizeof(argv[0]))); |
4815 | } else { |
4816 | argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); |
4817 | } |
4818 | for (x = 0; x < argc; x++) { |
4819 | char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix)(prefix ? prefix : ""), argv[x]); |
4820 | switch_assert(dial_str)((dial_str) ? (void) (0) : __assert_fail ("dial_str", "mod_conference.c" , 4820, __PRETTY_FUNCTION__)); |
4821 | conference_outcall_bg(member->conference, NULL((void*)0), NULL((void*)0), dial_str, to, switch_str_nil(flags)(flags ? flags : ""), cid_name, cid_num, NULL((void*)0), |
4822 | profile, &member->conference->cancel_cause, NULL((void*)0)); |
4823 | switch_safe_free(dial_str)if (dial_str) {free(dial_str);dial_str=((void*)0);}; |
4824 | } |
4825 | switch_safe_free(cpstr)if (cpstr) {free(cpstr);cpstr=((void*)0);}; |
4826 | } |
4827 | |
4828 | if (maxwait) { |
4829 | int tmp = atoi(maxwait); |
4830 | if (tmp > 0) { |
4831 | wait_sec = tmp; |
4832 | } |
4833 | } |
4834 | |
4835 | |
4836 | loops = wait_sec * 10; |
4837 | |
4838 | switch_channel_set_app_flag(channel, CF_APP_TAGGED)switch_channel_set_app_flag_key("mod_conference.c", channel, CF_APP_TAGGED ); |
4839 | do { |
4840 | switch_ivr_sleep(member->session, 100, SWITCH_TRUE, NULL((void*)0)); |
4841 | } while(switch_channel_up(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state (channel) < CS_HANGUP) && (member->conference->originating && --loops)); |
4842 | switch_channel_clear_app_flag(channel, CF_APP_TAGGED)switch_channel_clear_app_flag_key("mod_conference.c", channel , CF_APP_TAGGED); |
4843 | |
4844 | if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) { |
4845 | member->conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; |
4846 | goto end; |
4847 | } |
4848 | |
4849 | conference_member_play_file(member, "tone_stream://%(500,0,640)", 0, SWITCH_TRUE); |
4850 | } |
4851 | |
4852 | if (!switch_test_flag(member->conference, CFLAG_ANSWERED)((member->conference)->flags & CFLAG_ANSWERED)) { |
4853 | switch_channel_answer(channel)switch_channel_perform_answer(channel, "mod_conference.c", (const char *)__func__, 4853); |
4854 | } |
4855 | |
4856 | |
4857 | sanity = 2000; |
4858 | while(!switch_test_flag(member, MFLAG_ITHREAD)((member)->flags & MFLAG_ITHREAD) && sanity > 0) { |
4859 | switch_cond_next(); |
4860 | sanity--; |
4861 | } |
4862 | |
4863 | /* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed, */ |
4864 | /* you better not block this thread loop for more than the duration of member->conference->timer_name! */ |
4865 | while (!member->loop_loop && switch_test_flag(member, MFLAG_RUNNING)((member)->flags & MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD)((member)->flags & MFLAG_ITHREAD) |
4866 | && switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) { |
4867 | switch_event_t *event; |
4868 | int use_timer = 0; |
4869 | switch_buffer_t *use_buffer = NULL((void*)0); |
4870 | uint32_t mux_used = 0; |
4871 | |
4872 | switch_mutex_lock(member->write_mutex); |
4873 | |
4874 | |
4875 | if (switch_channel_test_flag(member->channel, CF_CONFERENCE_ADV)) { |
4876 | if (member->conference->la) { |
4877 | adv_la(member->conference, member, SWITCH_TRUE); |
4878 | } |
4879 | switch_channel_clear_flag(member->channel, CF_CONFERENCE_ADV); |
4880 | } |
4881 | |
4882 | |
4883 | if (switch_core_session_dequeue_event(member->session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { |
4884 | if (event->event_id == SWITCH_EVENT_MESSAGE) { |
4885 | char *from = switch_event_get_header(event, "from")switch_event_get_header_idx(event, "from", -1); |
4886 | char *to = switch_event_get_header(event, "to")switch_event_get_header_idx(event, "to", -1); |
4887 | char *body = switch_event_get_body(event); |
4888 | |
4889 | if (to && from && body) { |
4890 | if (strchr(to, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p (to) && ('+') == '\0' ? (char *) __rawmemchr (to, '+' ) : __builtin_strchr (to, '+'))) && strncmp(to, CONF_CHAT_PROTO, strlen(CONF_CHAT_PROTO))(__extension__ (__builtin_constant_p (strlen("conf")) && ((__builtin_constant_p (to) && strlen (to) < ((size_t ) (strlen("conf")))) || (__builtin_constant_p ("conf") && strlen ("conf") < ((size_t) (strlen("conf"))))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (to) && __builtin_constant_p ("conf") && (__s1_len = __builtin_strlen (to), __s2_len = __builtin_strlen ("conf"), (!((size_t)(const void *)((to) + 1) - (size_t)(const void *)(to) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("conf") + 1) - (size_t)(const void *)("conf") == 1) || __s2_len >= 4)) ? __builtin_strcmp (to, "conf") : (__builtin_constant_p (to) && ((size_t)(const void *)((to) + 1) - (size_t)(const void *)(to ) == 1) && (__s1_len = __builtin_strlen (to), __s1_len < 4) ? (__builtin_constant_p ("conf") && ((size_t )(const void *)(("conf") + 1) - (size_t)(const void *)("conf" ) == 1) ? __builtin_strcmp (to, "conf") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("conf"); int __result = (((const unsigned char *) (const char *) (to))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( to))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (to ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (to))[3 ] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("conf" ) && ((size_t)(const void *)(("conf") + 1) - (size_t) (const void *)("conf") == 1) && (__s2_len = __builtin_strlen ("conf"), __s2_len < 4) ? (__builtin_constant_p (to) && ((size_t)(const void *)((to) + 1) - (size_t)(const void *)(to ) == 1) ? __builtin_strcmp (to, "conf") : (- (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (to); int __result = (((const unsigned char *) (const char *) ("conf"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "conf"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "conf"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("conf" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (to, "conf")))); }) : strncmp (to, "conf", strlen("conf"))))) { |
4891 | switch_event_del_header(event, "to")switch_event_del_header_val(event, "to", ((void*)0)); |
4892 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, |
4893 | "to", "%s+%s@%s", CONF_CHAT_PROTO"conf", member->conference->name, member->conference->domain); |
4894 | } else { |
4895 | switch_event_del_header(event, "to")switch_event_del_header_val(event, "to", ((void*)0)); |
4896 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", member->conference->name); |
4897 | } |
4898 | chat_send(event); |
4899 | } |
4900 | } |
4901 | switch_event_destroy(&event); |
4902 | } |
4903 | |
4904 | if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { |
4905 | /* test to see if outbound channel has answered */ |
4906 | if (switch_channel_test_flag(channel, CF_ANSWERED) && !switch_test_flag(member->conference, CFLAG_ANSWERED)((member->conference)->flags & CFLAG_ANSWERED)) { |
4907 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4907, (const char*)(member->session), SWITCH_LOG_DEBUG, |
4908 | "Outbound conference channel answered, setting CFLAG_ANSWERED\n"); |
4909 | switch_set_flag(member->conference, CFLAG_ANSWERED)(member->conference)->flags |= (CFLAG_ANSWERED); |
4910 | } |
4911 | } else { |
4912 | if (switch_test_flag(member->conference, CFLAG_ANSWERED)((member->conference)->flags & CFLAG_ANSWERED) && !switch_channel_test_flag(channel, CF_ANSWERED)) { |
4913 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 4913, (const char*)(member->session), SWITCH_LOG_DEBUG, "CLFAG_ANSWERED set, answering inbound channel\n"); |
4914 | switch_channel_answer(channel)switch_channel_perform_answer(channel, "mod_conference.c", (const char *)__func__, 4914); |
4915 | } |
4916 | } |
4917 | |
4918 | use_buffer = NULL((void*)0); |
4919 | mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer); |
4920 | |
4921 | use_timer = 1; |
4922 | |
4923 | if (mux_used) { |
4924 | if (mux_used < bytes) { |
4925 | if (++low_count >= 5) { |
4926 | /* partial frame sitting around this long is useless and builds delay */ |
4927 | switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 4927 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_FLUSH_BUFFER);switch_mutex_unlock (member->flag_mutex);; |
4928 | } |
4929 | } else if (mux_used > flush_len) { |
4930 | /* getting behind, clear the buffer */ |
4931 | switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 4931 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_FLUSH_BUFFER);switch_mutex_unlock (member->flag_mutex);; |
4932 | } |
4933 | } |
4934 | |
4935 | if (switch_channel_test_app_flag(channel, CF_APP_TAGGED)switch_channel_test_app_flag_key("mod_conference.c", channel, CF_APP_TAGGED)) { |
4936 | switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 4936 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_FLUSH_BUFFER);switch_mutex_unlock (member->flag_mutex);; |
4937 | } else if (mux_used >= bytes) { |
4938 | /* Flush the output buffer and write all the data (presumably muxed) back to the channel */ |
4939 | switch_mutex_lock(member->audio_out_mutex); |
4940 | write_frame.data = data; |
4941 | use_buffer = member->mux_buffer; |
4942 | low_count = 0; |
4943 | |
4944 | if ((write_frame.datalen = (uint32_t) switch_buffer_read(use_buffer, write_frame.data, bytes))) { |
4945 | if (write_frame.datalen) { |
4946 | write_frame.samples = write_frame.datalen / 2 / member->conference->channels; |
4947 | |
4948 | if( !switch_test_flag(member, MFLAG_CAN_HEAR)((member)->flags & MFLAG_CAN_HEAR)) { |
4949 | memset(write_frame.data, 255, write_frame.datalen); |
4950 | } else if (member->volume_out_level) { /* Check for output volume adjustments */ |
4951 | switch_change_sln_volume(write_frame.data, write_frame.samples * member->conference->channels, member->volume_out_level); |
4952 | } |
4953 | |
4954 | write_frame.timestamp = timer.samplecount; |
4955 | |
4956 | if (member->fnode) { |
4957 | member_add_file_data(member, write_frame.data, write_frame.datalen); |
4958 | } |
4959 | |
4960 | member_check_channels(&write_frame, member, SWITCH_FALSE); |
4961 | |
4962 | if (switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { |
4963 | switch_mutex_unlock(member->audio_out_mutex); |
4964 | break; |
4965 | } |
4966 | } |
4967 | } |
4968 | |
4969 | switch_mutex_unlock(member->audio_out_mutex); |
4970 | } |
4971 | |
4972 | if (switch_test_flag(member, MFLAG_FLUSH_BUFFER)((member)->flags & MFLAG_FLUSH_BUFFER)) { |
4973 | if (switch_buffer_inuse(member->mux_buffer)) { |
4974 | switch_mutex_lock(member->audio_out_mutex); |
4975 | switch_buffer_zero(member->mux_buffer); |
4976 | switch_mutex_unlock(member->audio_out_mutex); |
4977 | } |
4978 | switch_clear_flag_locked(member, MFLAG_FLUSH_BUFFER)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_FLUSH_BUFFER); switch_mutex_unlock(member->flag_mutex );; |
4979 | } |
4980 | |
4981 | switch_mutex_unlock(member->write_mutex); |
4982 | |
4983 | |
4984 | if (switch_test_flag(member, MFLAG_INDICATE_MUTE)((member)->flags & MFLAG_INDICATE_MUTE)) { |
4985 | if (!zstr(member->conference->muted_sound)_zstr(member->conference->muted_sound)) { |
4986 | conference_member_play_file(member, member->conference->muted_sound, 0, SWITCH_TRUE); |
4987 | } else { |
4988 | char msg[512]; |
4989 | |
4990 | switch_snprintf(msg, sizeof(msg), "Muted"); |
4991 | conference_member_say(member, msg, 0); |
4992 | } |
4993 | switch_clear_flag(member, MFLAG_INDICATE_MUTE)(member)->flags &= ~(MFLAG_INDICATE_MUTE); |
4994 | } |
4995 | |
4996 | if (switch_test_flag(member, MFLAG_INDICATE_MUTE_DETECT)((member)->flags & MFLAG_INDICATE_MUTE_DETECT)) { |
4997 | if (!zstr(member->conference->mute_detect_sound)_zstr(member->conference->mute_detect_sound)) { |
4998 | conference_member_play_file(member, member->conference->mute_detect_sound, 0, SWITCH_TRUE); |
4999 | } else { |
5000 | char msg[512]; |
5001 | |
5002 | switch_snprintf(msg, sizeof(msg), "Currently Muted"); |
5003 | conference_member_say(member, msg, 0); |
5004 | } |
5005 | switch_clear_flag(member, MFLAG_INDICATE_MUTE_DETECT)(member)->flags &= ~(MFLAG_INDICATE_MUTE_DETECT); |
5006 | } |
5007 | |
5008 | if (switch_test_flag(member, MFLAG_INDICATE_UNMUTE)((member)->flags & MFLAG_INDICATE_UNMUTE)) { |
5009 | if (!zstr(member->conference->unmuted_sound)_zstr(member->conference->unmuted_sound)) { |
5010 | conference_member_play_file(member, member->conference->unmuted_sound, 0, SWITCH_TRUE); |
5011 | } else { |
5012 | char msg[512]; |
5013 | |
5014 | switch_snprintf(msg, sizeof(msg), "Un-Muted"); |
5015 | conference_member_say(member, msg, 0); |
5016 | } |
5017 | switch_clear_flag(member, MFLAG_INDICATE_UNMUTE)(member)->flags &= ~(MFLAG_INDICATE_UNMUTE); |
5018 | } |
5019 | |
5020 | if (switch_core_session_private_event_count(member->session)) { |
5021 | switch_channel_set_app_flag(channel, CF_APP_TAGGED)switch_channel_set_app_flag_key("mod_conference.c", channel, CF_APP_TAGGED ); |
5022 | switch_ivr_parse_all_events(member->session); |
5023 | switch_channel_clear_app_flag(channel, CF_APP_TAGGED)switch_channel_clear_app_flag_key("mod_conference.c", channel , CF_APP_TAGGED); |
5024 | switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 5024 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_FLUSH_BUFFER);switch_mutex_unlock (member->flag_mutex);; |
5025 | switch_core_session_set_read_codec(member->session, &member->read_codec); |
5026 | } else { |
5027 | switch_ivr_parse_all_messages(member->session); |
5028 | } |
5029 | |
5030 | if (use_timer) { |
5031 | switch_core_timer_next(&timer); |
5032 | } else { |
5033 | switch_cond_next(); |
5034 | } |
5035 | |
5036 | } /* Rinse ... Repeat */ |
5037 | |
5038 | end: |
5039 | |
5040 | if (!member->loop_loop) { |
5041 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
5042 | |
5043 | /* Wait for the input thread to end */ |
5044 | if (member->input_thread) { |
5045 | switch_thread_join(&st, member->input_thread); |
5046 | } |
5047 | } |
5048 | |
5049 | switch_core_timer_destroy(&timer); |
5050 | |
5051 | if (member->loop_loop) { |
5052 | return; |
5053 | } |
5054 | |
5055 | switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 5055, (const char*)switch_channel_get_session(channel ), SWITCH_LOG_DEBUG, "Channel leaving conference, cause: %s\n", |
5056 | switch_channel_cause2str(switch_channel_get_cause(channel))); |
5057 | |
5058 | /* if it's an outbound channel, store the release cause in the conference struct, we might need it */ |
5059 | if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { |
5060 | member->conference->bridge_hangup_cause = switch_channel_get_cause(channel); |
5061 | } |
5062 | } |
5063 | |
5064 | /* Sub-Routine called by a record entity inside a conference */ |
5065 | static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *thread, void *obj) |
5066 | { |
5067 | int16_t *data_buf; |
5068 | switch_file_handle_t fh = { 0 }; |
5069 | conference_member_t smember = { 0 }, *member; |
5070 | conference_record_t *rp, *last = NULL((void*)0), *rec = (conference_record_t *) obj; |
5071 | conference_obj_t *conference = rec->conference; |
5072 | uint32_t samples = switch_samples_per_packet(conference->rate, conference->interval)((uint32_t)((float)conference->rate / (1000.0f / (float)conference ->interval))); |
5073 | uint32_t mux_used; |
5074 | char *vval; |
5075 | switch_timer_t timer = { 0 }; |
5076 | uint32_t rlen; |
5077 | switch_size_t data_buf_len; |
5078 | switch_event_t *event; |
5079 | switch_size_t len = 0; |
5080 | |
5081 | if (switch_thread_rwlock_tryrdlock(conference->rwlock) != SWITCH_STATUS_SUCCESS) { |
5082 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5082, ((void*)0), SWITCH_LOG_CRIT, "Read Lock Fail\n"); |
5083 | return NULL((void*)0); |
5084 | } |
5085 | |
5086 | data_buf_len = samples * sizeof(int16_t) * conference->channels; |
5087 | switch_zmalloc(data_buf, data_buf_len)(void)((((data_buf = calloc(1, (data_buf_len)))) ? (void) (0) : __assert_fail ("(data_buf = calloc(1, (data_buf_len)))", "mod_conference.c" , 5087, __PRETTY_FUNCTION__)),data_buf); |
5088 | |
5089 | switch_mutex_lock(globals.hash_mutex); |
5090 | globals.threads++; |
5091 | switch_mutex_unlock(globals.hash_mutex); |
5092 | |
5093 | member = &smember; |
5094 | |
5095 | member->flags = MFLAG_CAN_HEAR | MFLAG_NOCHANNEL | MFLAG_RUNNING; |
5096 | |
5097 | member->conference = conference; |
5098 | member->native_rate = conference->rate; |
5099 | member->rec_path = rec->path; |
5100 | member->rec_time = switch_epoch_time_now(NULL((void*)0)); |
5101 | fh.channels = 1; |
5102 | fh.samplerate = conference->rate; |
5103 | member->id = next_member_id(); |
5104 | member->pool = rec->pool; |
5105 | member->rec = rec; |
5106 | member->frame_size = SWITCH_RECOMMENDED_BUFFER_SIZE8192; |
5107 | member->frame = switch_core_alloc(member->pool, member->frame_size)switch_core_perform_alloc(member->pool, member->frame_size , "mod_conference.c", (const char *)__func__, 5107); |
5108 | member->mux_frame = switch_core_alloc(member->pool, member->frame_size)switch_core_perform_alloc(member->pool, member->frame_size , "mod_conference.c", (const char *)__func__, 5108); |
5109 | |
5110 | |
5111 | switch_mutex_init(&member->write_mutex, SWITCH_MUTEX_NESTED0x1, rec->pool); |
5112 | switch_mutex_init(&member->flag_mutex, SWITCH_MUTEX_NESTED0x1, rec->pool); |
5113 | switch_mutex_init(&member->fnode_mutex, SWITCH_MUTEX_NESTED0x1, rec->pool); |
5114 | switch_mutex_init(&member->audio_in_mutex, SWITCH_MUTEX_NESTED0x1, rec->pool); |
5115 | switch_mutex_init(&member->audio_out_mutex, SWITCH_MUTEX_NESTED0x1, rec->pool); |
5116 | switch_mutex_init(&member->read_mutex, SWITCH_MUTEX_NESTED0x1, rec->pool); |
5117 | switch_thread_rwlock_create(&member->rwlock, rec->pool); |
5118 | |
5119 | /* Setup an audio buffer for the incoming audio */ |
5120 | if (switch_buffer_create_dynamic(&member->audio_buffer, CONF_DBLOCK_SIZE1024 * 128, CONF_DBUFFER_SIZE1024 * 128, 0) != SWITCH_STATUS_SUCCESS) { |
5121 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5121, ((void*)0), SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); |
5122 | goto end; |
5123 | } |
5124 | |
5125 | /* Setup an audio buffer for the outgoing audio */ |
5126 | if (switch_buffer_create_dynamic(&member->mux_buffer, CONF_DBLOCK_SIZE1024 * 128, CONF_DBUFFER_SIZE1024 * 128, 0) != SWITCH_STATUS_SUCCESS) { |
5127 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5127, ((void*)0), SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); |
5128 | goto end; |
5129 | } |
5130 | |
5131 | if (conference_add_member(conference, member) != SWITCH_STATUS_SUCCESS) { |
5132 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5132, ((void*)0), SWITCH_LOG_ERROR, "Error Joining Conference\n"); |
5133 | goto end; |
5134 | } |
5135 | |
5136 | fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN65536; |
5137 | |
5138 | if (switch_core_file_open(&fh,switch_core_perform_file_open("mod_conference.c", (const char *)__func__, 5140, &fh, rec->path, (uint8_t) conference ->channels, conference->rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT , rec->pool) |
5139 | rec->path, (uint8_t) conference->channels, conference->rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT,switch_core_perform_file_open("mod_conference.c", (const char *)__func__, 5140, &fh, rec->path, (uint8_t) conference ->channels, conference->rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT , rec->pool) |
5140 | rec->pool)switch_core_perform_file_open("mod_conference.c", (const char *)__func__, 5140, &fh, rec->path, (uint8_t) conference ->channels, conference->rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT , rec->pool) != SWITCH_STATUS_SUCCESS) { |
5141 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5141, ((void*)0), SWITCH_LOG_ERROR, "Error Opening File [%s]\n", rec->path); |
5142 | |
5143 | |
5144 | if (test_eflag(conference, EFLAG_RECORD)((conference)->eflags & EFLAG_RECORD) && |
5145 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 5145, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
5146 | conference_add_event_data(conference, event); |
5147 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "start-recording"); |
5148 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", rec->path); |
5149 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Error", "File could not be opened for recording"); |
5150 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 5150, &event, ((void*)0)); |
5151 | } |
5152 | |
5153 | goto end; |
5154 | } |
5155 | |
5156 | |
5157 | if (switch_core_timer_init(&timer, conference->timer_name, conference->interval, samples, rec->pool) == SWITCH_STATUS_SUCCESS) { |
5158 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5158, ((void*)0), SWITCH_LOG_DEBUG, "Setup timer success interval: %u samples: %u\n", conference->interval, samples); |
5159 | } else { |
5160 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5160, ((void*)0), SWITCH_LOG_ERROR, "Timer Setup Failed. Conference Cannot Start\n"); |
5161 | goto end; |
5162 | } |
5163 | |
5164 | if ((vval = switch_mprintf("Conference %s", conference->name))) { |
5165 | switch_core_file_set_string(&fh, SWITCH_AUDIO_COL_STR_TITLE, vval); |
5166 | switch_safe_free(vval)if (vval) {free(vval);vval=((void*)0);}; |
5167 | } |
5168 | |
5169 | switch_core_file_set_string(&fh, SWITCH_AUDIO_COL_STR_ARTIST, "FreeSWITCH mod_conference Software Conference Module"); |
5170 | |
5171 | if (test_eflag(conference, EFLAG_RECORD)((conference)->eflags & EFLAG_RECORD) && |
5172 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 5172, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
5173 | conference_add_event_data(conference, event); |
5174 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "start-recording"); |
5175 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", rec->path); |
5176 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 5176, &event, ((void*)0)); |
5177 | } |
5178 | |
5179 | while (switch_test_flag(member, MFLAG_RUNNING)((member)->flags & MFLAG_RUNNING) && switch_test_flag(conference, CFLAG_RUNNING)((conference)->flags & CFLAG_RUNNING) && (conference->count + conference->count_ghosts)) { |
5180 | |
5181 | len = 0; |
5182 | |
5183 | mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer); |
5184 | |
5185 | if (switch_test_flag(member, MFLAG_FLUSH_BUFFER)((member)->flags & MFLAG_FLUSH_BUFFER)) { |
5186 | if (mux_used) { |
5187 | switch_mutex_lock(member->audio_out_mutex); |
5188 | switch_buffer_zero(member->mux_buffer); |
5189 | switch_mutex_unlock(member->audio_out_mutex); |
5190 | mux_used = 0; |
5191 | } |
5192 | switch_clear_flag_locked(member, MFLAG_FLUSH_BUFFER)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_FLUSH_BUFFER); switch_mutex_unlock(member->flag_mutex );; |
5193 | } |
5194 | |
5195 | again: |
5196 | |
5197 | if (switch_test_flag((&fh), SWITCH_FILE_PAUSE)(((&fh))->flags & SWITCH_FILE_PAUSE)) { |
5198 | switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 5198 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_FLUSH_BUFFER);switch_mutex_unlock (member->flag_mutex);; |
5199 | goto loop; |
5200 | } |
5201 | |
5202 | if (mux_used >= data_buf_len) { |
5203 | /* Flush the output buffer and write all the data (presumably muxed) to the file */ |
5204 | switch_mutex_lock(member->audio_out_mutex); |
5205 | //low_count = 0; |
5206 | |
5207 | if ((rlen = (uint32_t) switch_buffer_read(member->mux_buffer, data_buf, data_buf_len))) { |
5208 | len = (switch_size_t) rlen / sizeof(int16_t) / conference->channels; |
5209 | } |
5210 | switch_mutex_unlock(member->audio_out_mutex); |
5211 | } |
5212 | |
5213 | if (len == 0) { |
5214 | mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer); |
5215 | |
5216 | if (mux_used >= data_buf_len) { |
5217 | goto again; |
5218 | } |
5219 | |
5220 | memset(data_buf, 255, (switch_size_t) data_buf_len); |
5221 | len = (switch_size_t) samples; |
5222 | } |
5223 | |
5224 | if (!switch_test_flag(member, MFLAG_PAUSE_RECORDING)((member)->flags & MFLAG_PAUSE_RECORDING)) { |
5225 | if (!len || switch_core_file_write(&fh, data_buf, &len) != SWITCH_STATUS_SUCCESS) { |
5226 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5226, ((void*)0), SWITCH_LOG_DEBUG, "Write Failed\n"); |
5227 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
5228 | } |
5229 | } |
5230 | |
5231 | loop: |
5232 | |
5233 | switch_core_timer_next(&timer); |
5234 | } /* Rinse ... Repeat */ |
5235 | |
5236 | end: |
5237 | |
5238 | for(;;) { |
5239 | switch_mutex_lock(member->audio_out_mutex); |
5240 | rlen = (uint32_t) switch_buffer_read(member->mux_buffer, data_buf, data_buf_len); |
5241 | switch_mutex_unlock(member->audio_out_mutex); |
5242 | |
5243 | if (rlen > 0) { |
5244 | len = (switch_size_t) rlen / sizeof(int16_t)/ conference->channels; |
5245 | switch_core_file_write(&fh, data_buf, &len); |
5246 | } else { |
5247 | break; |
5248 | } |
5249 | } |
5250 | |
5251 | switch_safe_free(data_buf)if (data_buf) {free(data_buf);data_buf=((void*)0);}; |
5252 | switch_core_timer_destroy(&timer); |
5253 | conference_del_member(conference, member); |
5254 | |
5255 | switch_buffer_destroy(&member->audio_buffer); |
5256 | switch_buffer_destroy(&member->mux_buffer); |
5257 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
5258 | if (switch_test_flag((&fh), SWITCH_FILE_OPEN)(((&fh))->flags & SWITCH_FILE_OPEN)) { |
5259 | switch_core_file_close(&fh); |
5260 | } |
5261 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5261, ((void*)0), SWITCH_LOG_DEBUG, "Recording of %s Stopped\n", rec->path); |
5262 | if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 5262, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
5263 | conference_add_event_data(conference, event); |
5264 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-recording"); |
5265 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", rec->path); |
5266 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Samples-Out", "%ld", (long) fh.samples_out); |
5267 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Samplerate", "%ld", (long) fh.samplerate); |
5268 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Milliseconds-Elapsed", "%ld", (long) fh.samples_out / (fh.samplerate / 1000)); |
5269 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 5269, &event, ((void*)0)); |
5270 | } |
5271 | |
5272 | if (rec->autorec && conference->auto_recording) { |
5273 | conference->auto_recording--; |
5274 | } |
5275 | |
5276 | switch_mutex_lock(conference->flag_mutex); |
5277 | for (rp = conference->rec_node_head; rp; rp = rp->next) { |
5278 | if (rec == rp) { |
5279 | if (last) { |
5280 | last->next = rp->next; |
5281 | } else { |
5282 | conference->rec_node_head = rp->next; |
5283 | } |
5284 | } |
5285 | } |
5286 | switch_mutex_unlock(conference->flag_mutex); |
5287 | |
5288 | |
5289 | if (rec->pool) { |
5290 | switch_memory_pool_t *pool = rec->pool; |
5291 | rec = NULL((void*)0); |
5292 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5292); |
5293 | } |
5294 | |
5295 | switch_mutex_lock(globals.hash_mutex); |
5296 | globals.threads--; |
5297 | switch_mutex_unlock(globals.hash_mutex); |
5298 | |
5299 | switch_thread_rwlock_unlock(conference->rwlock); |
5300 | return NULL((void*)0); |
5301 | } |
5302 | |
5303 | /* Make files stop playing in a conference either the current one or all of them */ |
5304 | static uint32_t conference_stop_file(conference_obj_t *conference, file_stop_t stop) |
5305 | { |
5306 | uint32_t count = 0; |
5307 | conference_file_node_t *nptr; |
5308 | |
5309 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 5309, __PRETTY_FUNCTION__)); |
5310 | |
5311 | switch_mutex_lock(conference->mutex); |
5312 | |
5313 | if (stop == FILE_STOP_ALL) { |
5314 | for (nptr = conference->fnode; nptr; nptr = nptr->next) { |
5315 | nptr->done++; |
5316 | count++; |
5317 | } |
5318 | if (conference->async_fnode) { |
5319 | conference->async_fnode->done++; |
5320 | count++; |
5321 | } |
5322 | } else if (stop == FILE_STOP_ASYNC) { |
5323 | if (conference->async_fnode) { |
5324 | conference->async_fnode->done++; |
5325 | count++; |
5326 | } |
5327 | } else { |
5328 | if (conference->fnode) { |
5329 | conference->fnode->done++; |
5330 | count++; |
5331 | } |
5332 | } |
5333 | |
5334 | switch_mutex_unlock(conference->mutex); |
5335 | |
5336 | return count; |
5337 | } |
5338 | |
5339 | /* stop playing a file for the member of the conference */ |
5340 | static uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop) |
5341 | { |
5342 | conference_file_node_t *nptr; |
5343 | uint32_t count = 0; |
5344 | |
5345 | if (member == NULL((void*)0)) |
5346 | return count; |
5347 | |
5348 | |
5349 | switch_mutex_lock(member->fnode_mutex); |
5350 | |
5351 | if (stop == FILE_STOP_ALL) { |
5352 | for (nptr = member->fnode; nptr; nptr = nptr->next) { |
5353 | nptr->done++; |
5354 | count++; |
5355 | } |
5356 | } else { |
5357 | if (member->fnode) { |
5358 | member->fnode->done++; |
5359 | count++; |
5360 | } |
5361 | } |
5362 | |
5363 | switch_mutex_unlock(member->fnode_mutex); |
5364 | |
5365 | return count; |
5366 | } |
5367 | |
5368 | static void conference_send_all_dtmf(conference_member_t *member, conference_obj_t *conference, const char *dtmf) |
5369 | { |
5370 | conference_member_t *imember; |
5371 | |
5372 | switch_mutex_lock(conference->mutex); |
5373 | switch_mutex_lock(conference->member_mutex); |
5374 | |
5375 | for (imember = conference->members; imember; imember = imember->next) { |
5376 | /* don't send to self */ |
5377 | if (imember->id == member->id) { |
5378 | continue; |
5379 | } |
5380 | if (imember->session) { |
5381 | const char *p; |
5382 | for (p = dtmf; p && *p; p++) { |
5383 | switch_dtmf_t *dt, digit = { *p, SWITCH_DEFAULT_DTMF_DURATION2000 }; |
5384 | |
5385 | switch_zmalloc(dt, sizeof(*dt))(void)((((dt = calloc(1, (sizeof(*dt))))) ? (void) (0) : __assert_fail ("(dt = calloc(1, (sizeof(*dt))))", "mod_conference.c", 5385 , __PRETTY_FUNCTION__)),dt); |
5386 | *dt = digit; |
5387 | switch_queue_push(imember->dtmf_queue, dt); |
5388 | switch_core_session_kill_channel(imember->session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(imember->session, "mod_conference.c", (const char *)__func__, 5388, SWITCH_SIG_BREAK ); |
5389 | } |
5390 | } |
5391 | } |
5392 | |
5393 | switch_mutex_unlock(conference->member_mutex); |
5394 | switch_mutex_unlock(conference->mutex); |
5395 | } |
5396 | |
5397 | /* Play a file in the conference room */ |
5398 | static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel, uint8_t async) |
5399 | { |
5400 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
5401 | conference_file_node_t *fnode, *nptr = NULL((void*)0); |
5402 | switch_memory_pool_t *pool; |
5403 | uint32_t count; |
5404 | char *dfile = NULL((void*)0), *expanded = NULL((void*)0); |
5405 | int say = 0; |
5406 | uint8_t channels = (uint8_t) conference->channels; |
5407 | int bad_params = 0; |
5408 | |
5409 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 5409, __PRETTY_FUNCTION__)); |
5410 | |
5411 | if (zstr(file)_zstr(file)) { |
5412 | return SWITCH_STATUS_NOTFOUND; |
5413 | } |
5414 | |
5415 | switch_mutex_lock(conference->mutex); |
5416 | switch_mutex_lock(conference->member_mutex); |
5417 | count = conference->count; |
5418 | switch_mutex_unlock(conference->member_mutex); |
5419 | switch_mutex_unlock(conference->mutex); |
5420 | |
5421 | if (!count) { |
5422 | return SWITCH_STATUS_FALSE; |
5423 | } |
5424 | |
5425 | if (channel) { |
5426 | if ((expanded = switch_channel_expand_variables(channel, file)switch_channel_expand_variables_check(channel, file, ((void*) 0), ((void*)0), 0)) != file) { |
5427 | file = expanded; |
5428 | } else { |
5429 | expanded = NULL((void*)0); |
5430 | } |
5431 | } |
5432 | |
5433 | if (!strncasecmp(file, "say:", 4)) { |
5434 | say = 1; |
5435 | } |
5436 | |
5437 | if (!async && say) { |
5438 | status = conference_say(conference, file + 4, leadin); |
5439 | goto done; |
5440 | } |
5441 | |
5442 | if (!switch_is_file_path(file)) { |
5443 | if (!say && conference->sound_prefix) { |
5444 | char *params_portion = NULL((void*)0); |
5445 | char *file_portion = NULL((void*)0); |
5446 | switch_separate_file_params(file, &file_portion, ¶ms_portion); |
5447 | |
5448 | if (params_portion) { |
5449 | dfile = switch_mprintf("%s%s%s%s", params_portion, conference->sound_prefix, SWITCH_PATH_SEPARATOR"/", file_portion); |
5450 | } else { |
5451 | dfile = switch_mprintf("%s%s%s", conference->sound_prefix, SWITCH_PATH_SEPARATOR"/", file_portion); |
5452 | } |
5453 | |
5454 | file = dfile; |
5455 | switch_safe_free(file_portion)if (file_portion) {free(file_portion);file_portion=((void*)0) ;}; |
5456 | switch_safe_free(params_portion)if (params_portion) {free(params_portion);params_portion=((void *)0);}; |
5457 | |
5458 | } else if (!async) { |
5459 | status = conference_say(conference, file, leadin); |
5460 | goto done; |
5461 | } else { |
5462 | goto done; |
5463 | } |
5464 | } |
5465 | |
5466 | /* Setup a memory pool to use. */ |
5467 | if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5467) != SWITCH_STATUS_SUCCESS) { |
5468 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5468, ((void*)0), SWITCH_LOG_CRIT, "Pool Failure\n"); |
5469 | status = SWITCH_STATUS_MEMERR; |
5470 | goto done; |
5471 | } |
5472 | |
5473 | /* Create a node object */ |
5474 | if (!(fnode = switch_core_alloc(pool, sizeof(*fnode))switch_core_perform_alloc(pool, sizeof(*fnode), "mod_conference.c" , (const char *)__func__, 5474))) { |
5475 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5475, ((void*)0), SWITCH_LOG_CRIT, "Alloc Failure\n"); |
5476 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5476); |
5477 | status = SWITCH_STATUS_MEMERR; |
5478 | goto done; |
5479 | } |
5480 | |
5481 | fnode->type = NODE_TYPE_FILE; |
5482 | fnode->leadin = leadin; |
5483 | |
5484 | if (switch_stristr("position=", file)) { |
5485 | /* positional requires mono input */ |
5486 | fnode->fh.channels = channels = 1; |
5487 | } |
5488 | |
5489 | retry: |
5490 | |
5491 | /* Open the file */ |
5492 | fnode->fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN65536; |
5493 | if (switch_core_file_open(&fnode->fh, file, channels, conference->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, pool)switch_core_perform_file_open("mod_conference.c", (const char *)__func__, 5493, &fnode->fh, file, channels, conference ->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, pool ) != |
5494 | SWITCH_STATUS_SUCCESS) { |
5495 | switch_event_t *event; |
5496 | |
5497 | if (test_eflag(conference, EFLAG_PLAY_FILE)((conference)->eflags & EFLAG_PLAY_FILE) && |
5498 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 5498, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
5499 | conference_add_event_data(conference, event); |
5500 | |
5501 | if (fnode->fh.params) { |
5502 | switch_event_merge(event, conference->fnode->fh.params); |
5503 | } |
5504 | |
5505 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file"); |
5506 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", file); |
5507 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", async ? "true" : "false"); |
5508 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Error", "File could not be played"); |
5509 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 5509, &event, ((void*)0)); |
5510 | } |
5511 | |
5512 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5512); |
5513 | status = SWITCH_STATUS_NOTFOUND; |
5514 | goto done; |
5515 | } |
5516 | |
5517 | if (fnode->fh.params) { |
5518 | const char *vol = switch_event_get_header(fnode->fh.params, "vol")switch_event_get_header_idx(fnode->fh.params, "vol", -1); |
5519 | const char *position = switch_event_get_header(fnode->fh.params, "position")switch_event_get_header_idx(fnode->fh.params, "position", - 1); |
5520 | |
5521 | if (!zstr(vol)_zstr(vol)) { |
5522 | fnode->fh.vol = atoi(vol); |
5523 | } |
5524 | |
5525 | if (!bad_params && !zstr(position)_zstr(position) && conference->channels == 2) { |
5526 | fnode->al = create_al(pool); |
5527 | if (parse_position(fnode->al, position) != SWITCH_STATUS_SUCCESS) { |
5528 | switch_core_file_close(&fnode->fh); |
5529 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5529, ((void*)0), SWITCH_LOG_ERROR, "Invalid Position Data.\n"); |
5530 | fnode->al = NULL((void*)0); |
5531 | channels = (uint8_t)conference->channels; |
5532 | bad_params = 1; |
5533 | goto retry; |
5534 | } |
5535 | } |
5536 | } |
5537 | |
5538 | fnode->pool = pool; |
5539 | fnode->async = async; |
5540 | fnode->file = switch_core_strdup(fnode->pool, file)switch_core_perform_strdup(fnode->pool, file, "mod_conference.c" , (const char *)__func__, 5540); |
5541 | |
5542 | /* Queue the node */ |
5543 | switch_mutex_lock(conference->mutex); |
5544 | |
5545 | if (async) { |
5546 | if (conference->async_fnode) { |
5547 | nptr = conference->async_fnode; |
5548 | } |
5549 | conference->async_fnode = fnode; |
5550 | |
5551 | if (nptr) { |
5552 | switch_memory_pool_t *tmppool; |
5553 | conference_file_close(conference, nptr); |
5554 | tmppool = nptr->pool; |
5555 | switch_core_destroy_memory_pool(&tmppool)switch_core_perform_destroy_memory_pool(&tmppool, "mod_conference.c" , (const char *)__func__, 5555); |
5556 | } |
5557 | |
5558 | } else { |
5559 | for (nptr = conference->fnode; nptr && nptr->next; nptr = nptr->next); |
5560 | |
5561 | if (nptr) { |
5562 | nptr->next = fnode; |
5563 | } else { |
5564 | conference->fnode = fnode; |
5565 | } |
5566 | } |
5567 | |
5568 | switch_mutex_unlock(conference->mutex); |
5569 | |
5570 | done: |
5571 | |
5572 | switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);}; |
5573 | switch_safe_free(dfile)if (dfile) {free(dfile);dfile=((void*)0);}; |
5574 | |
5575 | return status; |
5576 | } |
5577 | |
5578 | /* Play a file in the conference room to a member */ |
5579 | static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin, switch_bool_t mux) |
5580 | { |
5581 | switch_status_t status = SWITCH_STATUS_FALSE; |
5582 | char *dfile = NULL((void*)0), *expanded = NULL((void*)0); |
5583 | conference_file_node_t *fnode, *nptr = NULL((void*)0); |
5584 | switch_memory_pool_t *pool; |
5585 | int channels = member->conference->channels; |
5586 | int bad_params = 0; |
5587 | |
5588 | if (member == NULL((void*)0) || file == NULL((void*)0) || switch_test_flag(member, MFLAG_KICKED)((member)->flags & MFLAG_KICKED)) |
5589 | return status; |
5590 | |
5591 | if ((expanded = switch_channel_expand_variables(switch_core_session_get_channel(member->session), file)switch_channel_expand_variables_check(switch_core_session_get_channel (member->session), file, ((void*)0), ((void*)0), 0)) != file) { |
5592 | file = expanded; |
5593 | } else { |
5594 | expanded = NULL((void*)0); |
5595 | } |
5596 | if (!strncasecmp(file, "say:", 4)) { |
5597 | if (!zstr(file + 4)_zstr(file + 4)) { |
5598 | status = conference_member_say(member, file + 4, leadin); |
5599 | } |
5600 | goto done; |
5601 | } |
5602 | if (!switch_is_file_path(file)) { |
5603 | if (member->conference->sound_prefix) { |
5604 | if (!(dfile = switch_mprintf("%s%s%s", member->conference->sound_prefix, SWITCH_PATH_SEPARATOR"/", file))) { |
5605 | goto done; |
5606 | } |
5607 | file = dfile; |
5608 | } else if (!zstr(file)_zstr(file)) { |
5609 | status = conference_member_say(member, file, leadin); |
5610 | goto done; |
5611 | } |
5612 | } |
5613 | /* Setup a memory pool to use. */ |
5614 | if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5614) != SWITCH_STATUS_SUCCESS) { |
5615 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 5615, (const char*)(member->session), SWITCH_LOG_CRIT, "Pool Failure\n"); |
5616 | status = SWITCH_STATUS_MEMERR; |
5617 | goto done; |
5618 | } |
5619 | /* Create a node object */ |
5620 | if (!(fnode = switch_core_alloc(pool, sizeof(*fnode))switch_core_perform_alloc(pool, sizeof(*fnode), "mod_conference.c" , (const char *)__func__, 5620))) { |
5621 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 5621, (const char*)(member->session), SWITCH_LOG_CRIT, "Alloc Failure\n"); |
5622 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5622); |
5623 | status = SWITCH_STATUS_MEMERR; |
5624 | goto done; |
5625 | } |
5626 | fnode->type = NODE_TYPE_FILE; |
5627 | fnode->leadin = leadin; |
5628 | fnode->mux = mux; |
5629 | fnode->member_id = member->id; |
5630 | |
5631 | if (switch_stristr("position=", file)) { |
5632 | /* positional requires mono input */ |
5633 | fnode->fh.channels = channels = 1; |
5634 | } |
5635 | |
5636 | retry: |
5637 | |
5638 | /* Open the file */ |
5639 | fnode->fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN65536; |
5640 | if (switch_core_file_open(&fnode->fh,switch_core_perform_file_open("mod_conference.c", (const char *)__func__, 5642, &fnode->fh, file, (uint8_t) channels , member->conference->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT , pool) |
5641 | file, (uint8_t) channels, member->conference->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,switch_core_perform_file_open("mod_conference.c", (const char *)__func__, 5642, &fnode->fh, file, (uint8_t) channels , member->conference->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT , pool) |
5642 | pool)switch_core_perform_file_open("mod_conference.c", (const char *)__func__, 5642, &fnode->fh, file, (uint8_t) channels , member->conference->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT , pool) != SWITCH_STATUS_SUCCESS) { |
5643 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5643); |
5644 | status = SWITCH_STATUS_NOTFOUND; |
5645 | goto done; |
5646 | } |
5647 | fnode->pool = pool; |
5648 | fnode->file = switch_core_strdup(fnode->pool, file)switch_core_perform_strdup(fnode->pool, file, "mod_conference.c" , (const char *)__func__, 5648); |
5649 | |
5650 | if (fnode->fh.params) { |
5651 | const char *position = switch_event_get_header(fnode->fh.params, "position")switch_event_get_header_idx(fnode->fh.params, "position", - 1); |
5652 | |
5653 | if (!bad_params && !zstr(position)_zstr(position) && member->conference->channels == 2) { |
5654 | fnode->al = create_al(pool); |
5655 | if (parse_position(fnode->al, position) != SWITCH_STATUS_SUCCESS) { |
5656 | switch_core_file_close(&fnode->fh); |
5657 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 5657, (const char*)(member->session), SWITCH_LOG_ERROR, "Invalid Position Data.\n"); |
5658 | fnode->al = NULL((void*)0); |
5659 | channels = member->conference->channels; |
5660 | bad_params = 1; |
5661 | goto retry; |
5662 | } |
5663 | } |
5664 | } |
5665 | |
5666 | /* Queue the node */ |
5667 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 5667, (const char*)(member->session), SWITCH_LOG_DEBUG, "Queueing file '%s' for play\n", file); |
5668 | switch_mutex_lock(member->fnode_mutex); |
5669 | for (nptr = member->fnode; nptr && nptr->next; nptr = nptr->next); |
5670 | if (nptr) { |
5671 | nptr->next = fnode; |
5672 | } else { |
5673 | member->fnode = fnode; |
5674 | } |
5675 | switch_mutex_unlock(member->fnode_mutex); |
5676 | status = SWITCH_STATUS_SUCCESS; |
5677 | |
5678 | done: |
5679 | |
5680 | switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);}; |
5681 | switch_safe_free(dfile)if (dfile) {free(dfile);dfile=((void*)0);}; |
5682 | |
5683 | return status; |
5684 | } |
5685 | |
5686 | /* Say some thing with TTS in the conference room */ |
5687 | static switch_status_t conference_member_say(conference_member_t *member, char *text, uint32_t leadin) |
5688 | { |
5689 | conference_obj_t *conference = member->conference; |
5690 | conference_file_node_t *fnode, *nptr; |
5691 | switch_memory_pool_t *pool; |
5692 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; |
5693 | switch_status_t status = SWITCH_STATUS_FALSE; |
5694 | char *fp = NULL((void*)0); |
5695 | int channels = member->conference->channels; |
5696 | switch_event_t *params = NULL((void*)0); |
5697 | const char *position = NULL((void*)0); |
5698 | |
5699 | if (member == NULL((void*)0) || zstr(text)_zstr(text)) |
5700 | return SWITCH_STATUS_FALSE; |
5701 | |
5702 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 5702, __PRETTY_FUNCTION__)); |
5703 | |
5704 | if (!(conference->tts_engine && conference->tts_voice)) { |
5705 | return SWITCH_STATUS_SUCCESS; |
5706 | } |
5707 | |
5708 | /* Setup a memory pool to use. */ |
5709 | if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5709) != SWITCH_STATUS_SUCCESS) { |
5710 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 5710, (const char*)(member->session), SWITCH_LOG_CRIT, "Pool Failure\n"); |
5711 | return SWITCH_STATUS_MEMERR; |
5712 | } |
5713 | |
5714 | /* Create a node object */ |
5715 | if (!(fnode = switch_core_alloc(pool, sizeof(*fnode))switch_core_perform_alloc(pool, sizeof(*fnode), "mod_conference.c" , (const char *)__func__, 5715))) { |
5716 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 5716, (const char*)(member->session), SWITCH_LOG_CRIT, "Alloc Failure\n"); |
5717 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5717); |
5718 | return SWITCH_STATUS_MEMERR; |
5719 | } |
5720 | |
5721 | if (*text == '{') { |
5722 | char *new_fp; |
5723 | |
5724 | fp = switch_core_strdup(pool, text)switch_core_perform_strdup(pool, text, "mod_conference.c", (const char *)__func__, 5724); |
5725 | switch_assert(fp)((fp) ? (void) (0) : __assert_fail ("fp", "mod_conference.c", 5725, __PRETTY_FUNCTION__)); |
5726 | |
5727 | if (!switch_event_create_brackets(fp, '{', '}', ',', ¶ms, &new_fp, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { |
5728 | new_fp = fp; |
5729 | } |
5730 | |
5731 | text = new_fp; |
5732 | } |
5733 | |
5734 | fnode->type = NODE_TYPE_SPEECH; |
5735 | fnode->leadin = leadin; |
5736 | fnode->pool = pool; |
5737 | |
5738 | |
5739 | if (params && (position = switch_event_get_header(params, "position")switch_event_get_header_idx(params, "position", -1))) { |
5740 | if (conference->channels != 2) { |
5741 | position = NULL((void*)0); |
5742 | } else { |
5743 | channels = 1; |
5744 | fnode->al = create_al(pool); |
5745 | if (parse_position(fnode->al, position) != SWITCH_STATUS_SUCCESS) { |
5746 | fnode->al = NULL((void*)0); |
5747 | channels = conference->channels; |
5748 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5748, ((void*)0), SWITCH_LOG_ERROR, "Invalid Position Data.\n"); |
5749 | } |
5750 | } |
5751 | } |
5752 | |
5753 | |
5754 | if (member->sh && member->last_speech_channels != channels) { |
5755 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; |
5756 | switch_core_speech_close(&member->lsh, &flags); |
5757 | member->sh = NULL((void*)0); |
5758 | } |
5759 | |
5760 | if (!member->sh) { |
5761 | memset(&member->lsh, 0, sizeof(member->lsh)); |
5762 | if (switch_core_speech_open(&member->lsh, conference->tts_engine, conference->tts_voice, |
5763 | conference->rate, conference->interval, channels, &flags, switch_core_session_get_pool(member->session)) != |
5764 | SWITCH_STATUS_SUCCESS) { |
5765 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 5765, (const char*)(member->session), SWITCH_LOG_ERROR, "Invalid TTS module [%s]!\n", conference->tts_engine); |
5766 | status = SWITCH_STATUS_FALSE; |
5767 | goto end; |
5768 | } |
5769 | member->last_speech_channels = channels; |
5770 | member->sh = &member->lsh; |
5771 | } |
5772 | |
5773 | /* Queue the node */ |
5774 | switch_mutex_lock(member->fnode_mutex); |
5775 | for (nptr = member->fnode; nptr && nptr->next; nptr = nptr->next); |
5776 | |
5777 | if (nptr) { |
5778 | nptr->next = fnode; |
5779 | } else { |
5780 | member->fnode = fnode; |
5781 | } |
5782 | |
5783 | fnode->sh = member->sh; |
5784 | /* Begin Generation */ |
5785 | switch_sleep(200000); |
5786 | |
5787 | if (*text == '#') { |
5788 | char *tmp = (char *) text + 1; |
5789 | char *vp = tmp, voice[128] = ""; |
5790 | if ((tmp = strchr(tmp, '#')(__extension__ (__builtin_constant_p ('#') && !__builtin_constant_p (tmp) && ('#') == '\0' ? (char *) __rawmemchr (tmp, '#' ) : __builtin_strchr (tmp, '#'))))) { |
5791 | text = tmp + 1; |
5792 | switch_copy_string(voice, vp, (tmp - vp) + 1); |
5793 | switch_core_speech_text_param_tts(fnode->sh, "voice", voice); |
5794 | } |
5795 | } else { |
5796 | switch_core_speech_text_param_tts(fnode->sh, "voice", conference->tts_voice); |
5797 | } |
5798 | |
5799 | switch_core_speech_feed_tts(fnode->sh, text, &flags); |
5800 | switch_mutex_unlock(member->fnode_mutex); |
5801 | |
5802 | status = SWITCH_STATUS_SUCCESS; |
5803 | |
5804 | end: |
5805 | |
5806 | if (params) { |
5807 | switch_event_destroy(¶ms); |
5808 | } |
5809 | |
5810 | return status; |
5811 | } |
5812 | |
5813 | /* Say some thing with TTS in the conference room */ |
5814 | static switch_status_t conference_say(conference_obj_t *conference, const char *text, uint32_t leadin) |
5815 | { |
5816 | switch_status_t status = SWITCH_STATUS_FALSE; |
5817 | conference_file_node_t *fnode, *nptr; |
5818 | switch_memory_pool_t *pool; |
5819 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; |
5820 | uint32_t count; |
5821 | switch_event_t *params = NULL((void*)0); |
5822 | char *fp = NULL((void*)0); |
5823 | int channels; |
5824 | const char *position = NULL((void*)0); |
5825 | |
5826 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 5826, __PRETTY_FUNCTION__)); |
5827 | |
5828 | channels = conference->channels; |
5829 | |
5830 | if (zstr(text)_zstr(text)) { |
5831 | return SWITCH_STATUS_GENERR; |
5832 | } |
5833 | |
5834 | |
5835 | switch_mutex_lock(conference->mutex); |
5836 | switch_mutex_lock(conference->member_mutex); |
5837 | count = conference->count; |
5838 | if (!(conference->tts_engine && conference->tts_voice)) { |
5839 | count = 0; |
5840 | } |
5841 | switch_mutex_unlock(conference->member_mutex); |
5842 | switch_mutex_unlock(conference->mutex); |
5843 | |
5844 | if (!count) { |
5845 | return SWITCH_STATUS_FALSE; |
5846 | } |
5847 | |
5848 | /* Setup a memory pool to use. */ |
5849 | if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5849) != SWITCH_STATUS_SUCCESS) { |
5850 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5850, ((void*)0), SWITCH_LOG_CRIT, "Pool Failure\n"); |
5851 | return SWITCH_STATUS_MEMERR; |
5852 | } |
5853 | |
5854 | /* Create a node object */ |
5855 | if (!(fnode = switch_core_alloc(pool, sizeof(*fnode))switch_core_perform_alloc(pool, sizeof(*fnode), "mod_conference.c" , (const char *)__func__, 5855))) { |
5856 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5856, ((void*)0), SWITCH_LOG_CRIT, "Alloc Failure\n"); |
5857 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 5857); |
5858 | return SWITCH_STATUS_MEMERR; |
5859 | } |
5860 | |
5861 | |
5862 | if (*text == '{') { |
5863 | char *new_fp; |
5864 | |
5865 | fp = switch_core_strdup(pool, text)switch_core_perform_strdup(pool, text, "mod_conference.c", (const char *)__func__, 5865); |
5866 | switch_assert(fp)((fp) ? (void) (0) : __assert_fail ("fp", "mod_conference.c", 5866, __PRETTY_FUNCTION__)); |
5867 | |
5868 | if (!switch_event_create_brackets(fp, '{', '}', ',', ¶ms, &new_fp, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { |
5869 | new_fp = fp; |
5870 | } |
5871 | |
5872 | text = new_fp; |
5873 | } |
5874 | |
5875 | |
5876 | fnode->type = NODE_TYPE_SPEECH; |
5877 | fnode->leadin = leadin; |
5878 | |
5879 | if (params && (position = switch_event_get_header(params, "position")switch_event_get_header_idx(params, "position", -1))) { |
5880 | if (conference->channels != 2) { |
5881 | position = NULL((void*)0); |
5882 | } else { |
5883 | channels = 1; |
5884 | fnode->al = create_al(pool); |
5885 | if (parse_position(fnode->al, position) != SWITCH_STATUS_SUCCESS) { |
5886 | fnode->al = NULL((void*)0); |
5887 | channels = conference->channels; |
5888 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5888, ((void*)0), SWITCH_LOG_ERROR, "Invalid Position Data.\n"); |
5889 | } |
5890 | } |
5891 | } |
5892 | |
5893 | if (conference->sh && conference->last_speech_channels != channels) { |
5894 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; |
5895 | switch_core_speech_close(&conference->lsh, &flags); |
5896 | conference->sh = NULL((void*)0); |
5897 | } |
5898 | |
5899 | if (!conference->sh) { |
5900 | memset(&conference->lsh, 0, sizeof(conference->lsh)); |
5901 | if (switch_core_speech_open(&conference->lsh, conference->tts_engine, conference->tts_voice, |
5902 | conference->rate, conference->interval, channels, &flags, NULL((void*)0)) != SWITCH_STATUS_SUCCESS) { |
5903 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 5903, ((void*)0), SWITCH_LOG_ERROR, "Invalid TTS module [%s]!\n", conference->tts_engine); |
5904 | status = SWITCH_STATUS_FALSE; |
5905 | goto end; |
5906 | } |
5907 | conference->last_speech_channels = channels; |
5908 | conference->sh = &conference->lsh; |
5909 | } |
5910 | |
5911 | fnode->pool = pool; |
5912 | |
5913 | /* Queue the node */ |
5914 | switch_mutex_lock(conference->mutex); |
5915 | for (nptr = conference->fnode; nptr && nptr->next; nptr = nptr->next); |
5916 | |
5917 | if (nptr) { |
5918 | nptr->next = fnode; |
5919 | } else { |
5920 | conference->fnode = fnode; |
5921 | } |
5922 | |
5923 | fnode->sh = conference->sh; |
5924 | if (*text == '#') { |
5925 | char *tmp = (char *) text + 1; |
5926 | char *vp = tmp, voice[128] = ""; |
5927 | if ((tmp = strchr(tmp, '#')(__extension__ (__builtin_constant_p ('#') && !__builtin_constant_p (tmp) && ('#') == '\0' ? (char *) __rawmemchr (tmp, '#' ) : __builtin_strchr (tmp, '#'))))) { |
5928 | text = tmp + 1; |
5929 | switch_copy_string(voice, vp, (tmp - vp) + 1); |
5930 | switch_core_speech_text_param_tts(fnode->sh, "voice", voice); |
5931 | } |
5932 | } else { |
5933 | switch_core_speech_text_param_tts(fnode->sh, "voice", conference->tts_voice); |
5934 | } |
5935 | |
5936 | /* Begin Generation */ |
5937 | switch_sleep(200000); |
5938 | switch_core_speech_feed_tts(fnode->sh, (char *) text, &flags); |
5939 | switch_mutex_unlock(conference->mutex); |
5940 | status = SWITCH_STATUS_SUCCESS; |
5941 | |
5942 | end: |
5943 | |
5944 | if (params) { |
5945 | switch_event_destroy(¶ms); |
5946 | } |
5947 | |
5948 | return status; |
5949 | } |
5950 | |
5951 | /* send a message to every member of the conference */ |
5952 | static void chat_message_broadcast(conference_obj_t *conference, switch_event_t *event) |
5953 | { |
5954 | conference_member_t *member = NULL((void*)0); |
5955 | switch_event_t *processed; |
5956 | |
5957 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 5957, __PRETTY_FUNCTION__)); |
5958 | switch_event_create(&processed, SWITCH_EVENT_CHANNEL_DATA)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 5958, &processed, SWITCH_EVENT_CHANNEL_DATA , ((void*)0)); |
5959 | |
5960 | switch_mutex_lock(conference->member_mutex); |
5961 | for (member = conference->members; member; member = member->next) { |
5962 | if (member->session && !switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
5963 | const char *presence_id = switch_channel_get_variable(member->channel, "presence_id")switch_channel_get_variable_dup(member->channel, "presence_id" , SWITCH_TRUE, -1); |
5964 | const char *chat_proto = switch_channel_get_variable(member->channel, "chat_proto")switch_channel_get_variable_dup(member->channel, "chat_proto" , SWITCH_TRUE, -1); |
5965 | switch_event_t *reply = NULL((void*)0); |
5966 | |
5967 | if (presence_id && chat_proto) { |
5968 | if (switch_event_get_header(processed, presence_id)switch_event_get_header_idx(processed, presence_id, -1)) { |
5969 | continue; |
5970 | } |
5971 | switch_event_dup(&reply, event); |
5972 | switch_event_add_header_string(reply, SWITCH_STACK_BOTTOM, "to", presence_id); |
5973 | switch_event_add_header_string(reply, SWITCH_STACK_BOTTOM, "conference_name", conference->name); |
5974 | switch_event_add_header_string(reply, SWITCH_STACK_BOTTOM, "conference_domain", conference->domain); |
5975 | |
5976 | switch_event_set_body(reply, switch_event_get_body(event)); |
5977 | |
5978 | switch_core_chat_deliver(chat_proto, &reply); |
5979 | switch_event_add_header_string(processed, SWITCH_STACK_BOTTOM, presence_id, "true"); |
5980 | } |
5981 | } |
5982 | } |
5983 | switch_event_destroy(&processed); |
5984 | switch_mutex_unlock(conference->member_mutex); |
5985 | } |
5986 | |
5987 | /* execute a callback for every member of the conference */ |
5988 | static void conference_member_itterator(conference_obj_t *conference, switch_stream_handle_t *stream, uint8_t non_mod, conf_api_member_cmd_t pfncallback, void *data) |
5989 | { |
5990 | conference_member_t *member = NULL((void*)0); |
5991 | |
5992 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 5992, __PRETTY_FUNCTION__)); |
5993 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 5993, __PRETTY_FUNCTION__)); |
5994 | switch_assert(pfncallback != NULL)((pfncallback != ((void*)0)) ? (void) (0) : __assert_fail ("pfncallback != ((void*)0)" , "mod_conference.c", 5994, __PRETTY_FUNCTION__)); |
5995 | |
5996 | switch_mutex_lock(conference->member_mutex); |
5997 | for (member = conference->members; member; member = member->next) { |
5998 | if (!(non_mod && switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD))) { |
5999 | if (member->session && !switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
6000 | pfncallback(member, stream, data); |
6001 | } |
6002 | } else { |
6003 | stream->write_function(stream, "Skipping moderator (member id %d).\n", member->id); |
6004 | } |
6005 | } |
6006 | switch_mutex_unlock(conference->member_mutex); |
6007 | } |
6008 | |
6009 | |
6010 | static switch_status_t list_conferences(const char *line, const char *cursor, switch_console_callback_match_t **matches) |
6011 | { |
6012 | switch_console_callback_match_t *my_matches = NULL((void*)0); |
6013 | switch_status_t status = SWITCH_STATUS_FALSE; |
6014 | switch_hash_index_t *hi; |
6015 | void *val; |
6016 | const void *vvar; |
6017 | |
6018 | switch_mutex_lock(globals.hash_mutex); |
6019 | for (hi = switch_core_hash_first(globals.conference_hash)switch_core_hash_first_iter(globals.conference_hash, ((void*) 0)); hi; hi = switch_core_hash_next(&hi)) { |
6020 | switch_core_hash_this(hi, &vvar, NULL((void*)0), &val); |
6021 | switch_console_push_match(&my_matches, (const char *) vvar); |
6022 | } |
6023 | switch_mutex_unlock(globals.hash_mutex); |
6024 | |
6025 | if (my_matches) { |
6026 | *matches = my_matches; |
6027 | status = SWITCH_STATUS_SUCCESS; |
6028 | } |
6029 | |
6030 | return status; |
6031 | } |
6032 | |
6033 | static void conference_list_pretty(conference_obj_t *conference, switch_stream_handle_t *stream) |
6034 | { |
6035 | conference_member_t *member = NULL((void*)0); |
6036 | |
6037 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 6037, __PRETTY_FUNCTION__)); |
6038 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 6038, __PRETTY_FUNCTION__)); |
6039 | |
6040 | switch_mutex_lock(conference->member_mutex); |
6041 | |
6042 | for (member = conference->members; member; member = member->next) { |
6043 | switch_channel_t *channel; |
6044 | switch_caller_profile_t *profile; |
6045 | |
6046 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
6047 | continue; |
6048 | } |
6049 | channel = switch_core_session_get_channel(member->session); |
6050 | profile = switch_channel_get_caller_profile(channel); |
6051 | |
6052 | stream->write_function(stream, "%u) %s (%s)\n", member->id, profile->caller_id_name, profile->caller_id_number); |
6053 | } |
6054 | |
6055 | switch_mutex_unlock(conference->member_mutex); |
6056 | } |
6057 | |
6058 | static void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim) |
6059 | { |
6060 | conference_member_t *member = NULL((void*)0); |
6061 | |
6062 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 6062, __PRETTY_FUNCTION__)); |
6063 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 6063, __PRETTY_FUNCTION__)); |
6064 | switch_assert(delim != NULL)((delim != ((void*)0)) ? (void) (0) : __assert_fail ("delim != ((void*)0)" , "mod_conference.c", 6064, __PRETTY_FUNCTION__)); |
6065 | |
6066 | switch_mutex_lock(conference->member_mutex); |
6067 | |
6068 | for (member = conference->members; member; member = member->next) { |
6069 | switch_channel_t *channel; |
6070 | switch_caller_profile_t *profile; |
6071 | char *uuid; |
6072 | char *name; |
6073 | uint32_t count = 0; |
6074 | |
6075 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
6076 | continue; |
6077 | } |
6078 | |
6079 | uuid = switch_core_session_get_uuid(member->session); |
6080 | channel = switch_core_session_get_channel(member->session); |
6081 | profile = switch_channel_get_caller_profile(channel); |
6082 | name = switch_channel_get_name(channel); |
6083 | |
6084 | stream->write_function(stream, "%u%s%s%s%s%s%s%s%s%s", |
6085 | member->id, delim, name, delim, uuid, delim, profile->caller_id_name, delim, profile->caller_id_number, delim); |
6086 | |
6087 | if (switch_test_flag(member, MFLAG_CAN_HEAR)((member)->flags & MFLAG_CAN_HEAR)) { |
6088 | stream->write_function(stream, "hear"); |
6089 | count++; |
6090 | } |
6091 | |
6092 | if (switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
6093 | stream->write_function(stream, "%s%s", count ? "|" : "", "speak"); |
6094 | count++; |
6095 | } |
6096 | |
6097 | if (switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING)) { |
6098 | stream->write_function(stream, "%s%s", count ? "|" : "", "talking"); |
6099 | count++; |
6100 | } |
6101 | |
6102 | if (switch_channel_test_flag(switch_core_session_get_channel(member->session), CF_VIDEO)) { |
6103 | stream->write_function(stream, "%s%s", count ? "|" : "", "video"); |
6104 | count++; |
6105 | } |
6106 | |
6107 | if (member == member->conference->floor_holder) { |
6108 | stream->write_function(stream, "%s%s", count ? "|" : "", "floor"); |
6109 | count++; |
6110 | } |
6111 | |
6112 | if (switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD)) { |
6113 | stream->write_function(stream, "%s%s", count ? "|" : "", "moderator"); |
6114 | count++; |
6115 | } |
6116 | |
6117 | if (switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST)) { |
6118 | stream->write_function(stream, "%s%s", count ? "|" : "", "ghost"); |
6119 | count++; |
6120 | } |
6121 | |
6122 | stream->write_function(stream, "%s%d%s%d%s%d%s%d\n", delim, |
6123 | member->volume_in_level, |
6124 | delim, |
6125 | member->agc_volume_in_level, |
6126 | delim, member->volume_out_level, delim, member->energy_level); |
6127 | } |
6128 | |
6129 | switch_mutex_unlock(conference->member_mutex); |
6130 | } |
6131 | |
6132 | static void conference_list_count_only(conference_obj_t *conference, switch_stream_handle_t *stream) |
6133 | { |
6134 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 6134, __PRETTY_FUNCTION__)); |
6135 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 6135, __PRETTY_FUNCTION__)); |
6136 | |
6137 | stream->write_function(stream, "%d", conference->count); |
6138 | } |
6139 | |
6140 | static switch_status_t conf_api_sub_mute(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6141 | { |
6142 | switch_event_t *event; |
6143 | |
6144 | if (member == NULL((void*)0)) |
6145 | return SWITCH_STATUS_GENERR; |
6146 | |
6147 | switch_clear_flag_locked(member, MFLAG_CAN_SPEAK)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_CAN_SPEAK); switch_mutex_unlock(member->flag_mutex );; |
6148 | switch_clear_flag_locked(member, MFLAG_TALKING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_TALKING); switch_mutex_unlock(member->flag_mutex) ;; |
6149 | |
6150 | if (member->session && !switch_test_flag(member, MFLAG_MUTE_DETECT)((member)->flags & MFLAG_MUTE_DETECT)) { |
6151 | switch_core_media_hard_mute(member->session, SWITCH_TRUE); |
6152 | } |
6153 | |
6154 | if (!(data) || !strstr((char *) data, "quiet")) { |
6155 | switch_set_flag(member, MFLAG_INDICATE_MUTE)(member)->flags |= (MFLAG_INDICATE_MUTE); |
6156 | } |
6157 | member->score_iir = 0; |
6158 | |
6159 | if (stream != NULL((void*)0)) { |
6160 | stream->write_function(stream, "OK mute %u\n", member->id); |
6161 | } |
6162 | |
6163 | if (test_eflag(member->conference, EFLAG_MUTE_MEMBER)((member->conference)->eflags & EFLAG_MUTE_MEMBER) && |
6164 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6164, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6165 | conference_add_event_member_data(member, event); |
6166 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "mute-member"); |
6167 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6167, &event, ((void*)0)); |
6168 | } |
6169 | |
6170 | if (switch_test_flag(member->conference, CFLAG_POSITIONAL)((member->conference)->flags & CFLAG_POSITIONAL)) { |
6171 | gen_arc(member->conference, NULL((void*)0)); |
6172 | } |
6173 | |
6174 | member_update_status_field(member); |
6175 | |
6176 | return SWITCH_STATUS_SUCCESS; |
6177 | } |
6178 | |
6179 | |
6180 | static switch_status_t conf_api_sub_tmute(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6181 | { |
6182 | |
6183 | if (member == NULL((void*)0)) |
6184 | return SWITCH_STATUS_GENERR; |
6185 | |
6186 | if (switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
6187 | return conf_api_sub_mute(member, stream, data); |
6188 | } |
6189 | |
6190 | return conf_api_sub_unmute(member, stream, data); |
6191 | } |
6192 | |
6193 | static switch_status_t conf_api_sub_agc(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
6194 | { |
6195 | int level; |
6196 | int on = 0; |
6197 | |
6198 | if (argc == 2) { |
6199 | stream->write_function(stream, "+OK CURRENT AGC LEVEL IS %d\n", conference->agc_level); |
6200 | return SWITCH_STATUS_SUCCESS; |
6201 | } |
6202 | |
6203 | |
6204 | if (!(on = !strcasecmp(argv[2], "on"))) { |
6205 | stream->write_function(stream, "+OK AGC DISABLED\n"); |
6206 | conference->agc_level = 0; |
6207 | return SWITCH_STATUS_SUCCESS; |
6208 | } |
6209 | |
6210 | if (argc > 3) { |
6211 | level = atoi(argv[3]); |
6212 | } else { |
6213 | level = DEFAULT_AGC_LEVEL1100; |
6214 | } |
6215 | |
6216 | if (level > conference->energy_level) { |
6217 | conference->avg_score = 0; |
6218 | conference->avg_itt = 0; |
6219 | conference->avg_tally = 0; |
6220 | conference->agc_level = level; |
6221 | |
6222 | if (stream) { |
6223 | stream->write_function(stream, "OK AGC ENABLED %d\n", conference->agc_level); |
6224 | } |
6225 | |
6226 | } else { |
6227 | if (stream) { |
6228 | stream->write_function(stream, "-ERR invalid level\n"); |
6229 | } |
6230 | } |
6231 | |
6232 | |
6233 | |
6234 | |
6235 | return SWITCH_STATUS_SUCCESS; |
6236 | |
6237 | } |
6238 | |
6239 | static switch_status_t conf_api_sub_unmute(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6240 | { |
6241 | switch_event_t *event; |
6242 | |
6243 | if (member == NULL((void*)0)) |
6244 | return SWITCH_STATUS_GENERR; |
6245 | |
6246 | switch_set_flag_locked(member, MFLAG_CAN_SPEAK)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 6246 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_CAN_SPEAK);switch_mutex_unlock (member->flag_mutex);; |
6247 | |
6248 | if (member->session && !switch_test_flag(member, MFLAG_MUTE_DETECT)((member)->flags & MFLAG_MUTE_DETECT)) { |
6249 | switch_core_media_hard_mute(member->session, SWITCH_FALSE); |
6250 | } |
6251 | |
6252 | if (!(data) || !strstr((char *) data, "quiet")) { |
6253 | switch_set_flag(member, MFLAG_INDICATE_UNMUTE)(member)->flags |= (MFLAG_INDICATE_UNMUTE); |
6254 | } |
6255 | |
6256 | if (stream != NULL((void*)0)) { |
6257 | stream->write_function(stream, "OK unmute %u\n", member->id); |
6258 | } |
6259 | |
6260 | if (test_eflag(member->conference, EFLAG_UNMUTE_MEMBER)((member->conference)->eflags & EFLAG_UNMUTE_MEMBER ) && |
6261 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6261, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6262 | conference_add_event_member_data(member, event); |
6263 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "unmute-member"); |
6264 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6264, &event, ((void*)0)); |
6265 | } |
6266 | |
6267 | if (switch_test_flag(member->conference, CFLAG_POSITIONAL)((member->conference)->flags & CFLAG_POSITIONAL)) { |
6268 | gen_arc(member->conference, NULL((void*)0)); |
6269 | } |
6270 | |
6271 | member_update_status_field(member); |
6272 | |
6273 | return SWITCH_STATUS_SUCCESS; |
6274 | } |
6275 | |
6276 | static switch_status_t conf_api_sub_deaf(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6277 | { |
6278 | switch_event_t *event; |
6279 | |
6280 | if (member == NULL((void*)0)) |
6281 | return SWITCH_STATUS_GENERR; |
6282 | |
6283 | switch_clear_flag_locked(member, MFLAG_CAN_HEAR)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_CAN_HEAR); switch_mutex_unlock(member->flag_mutex );; |
6284 | if (stream != NULL((void*)0)) { |
6285 | stream->write_function(stream, "OK deaf %u\n", member->id); |
6286 | } |
6287 | if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6287, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6288 | conference_add_event_member_data(member, event); |
6289 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "deaf-member"); |
6290 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6290, &event, ((void*)0)); |
6291 | } |
6292 | |
6293 | if (switch_test_flag(member->conference, CFLAG_POSITIONAL)((member->conference)->flags & CFLAG_POSITIONAL)) { |
6294 | gen_arc(member->conference, NULL((void*)0)); |
6295 | } |
6296 | |
6297 | return SWITCH_STATUS_SUCCESS; |
6298 | } |
6299 | |
6300 | static switch_status_t conf_api_sub_undeaf(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6301 | { |
6302 | switch_event_t *event; |
6303 | |
6304 | if (member == NULL((void*)0)) |
6305 | return SWITCH_STATUS_GENERR; |
6306 | |
6307 | switch_set_flag_locked(member, MFLAG_CAN_HEAR)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 6307 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_CAN_HEAR);switch_mutex_unlock( member->flag_mutex);; |
6308 | if (stream != NULL((void*)0)) { |
6309 | stream->write_function(stream, "OK undeaf %u\n", member->id); |
6310 | } |
6311 | if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6311, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6312 | conference_add_event_member_data(member, event); |
6313 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "undeaf-member"); |
6314 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6314, &event, ((void*)0)); |
6315 | } |
6316 | |
6317 | if (switch_test_flag(member->conference, CFLAG_POSITIONAL)((member->conference)->flags & CFLAG_POSITIONAL)) { |
6318 | gen_arc(member->conference, NULL((void*)0)); |
6319 | } |
6320 | |
6321 | return SWITCH_STATUS_SUCCESS; |
6322 | } |
6323 | |
6324 | static switch_status_t conf_api_sub_hup(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6325 | { |
6326 | switch_event_t *event; |
6327 | |
6328 | if (member == NULL((void*)0)) { |
6329 | return SWITCH_STATUS_GENERR; |
6330 | } |
6331 | |
6332 | switch_clear_flag(member, MFLAG_RUNNING)(member)->flags &= ~(MFLAG_RUNNING); |
6333 | |
6334 | if (member->conference && test_eflag(member->conference, EFLAG_HUP_MEMBER)((member->conference)->eflags & EFLAG_HUP_MEMBER)) { |
6335 | if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6335, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6336 | conference_add_event_member_data(member, event); |
6337 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "hup-member"); |
6338 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6338, &event, ((void*)0)); |
6339 | } |
6340 | } |
6341 | |
6342 | return SWITCH_STATUS_SUCCESS; |
6343 | } |
6344 | |
6345 | static switch_status_t conf_api_sub_kick(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6346 | { |
6347 | switch_event_t *event; |
6348 | |
6349 | if (member == NULL((void*)0)) { |
6350 | return SWITCH_STATUS_GENERR; |
6351 | } |
6352 | |
6353 | switch_clear_flag(member, MFLAG_RUNNING)(member)->flags &= ~(MFLAG_RUNNING); |
6354 | switch_set_flag_locked(member, MFLAG_KICKED)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 6354 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_KICKED);switch_mutex_unlock(member ->flag_mutex);; |
6355 | switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(member->session, "mod_conference.c" , (const char *)__func__, 6355, SWITCH_SIG_BREAK); |
6356 | |
6357 | if (data && member->session) { |
6358 | member->kicked_sound = switch_core_session_strdup(member->session, (char *) data)switch_core_perform_session_strdup(member->session, (char * ) data, "mod_conference.c", (const char *)__func__, 6358); |
6359 | } |
6360 | |
6361 | if (stream != NULL((void*)0)) { |
6362 | stream->write_function(stream, "OK kicked %u\n", member->id); |
6363 | } |
6364 | |
6365 | if (member->conference && test_eflag(member->conference, EFLAG_KICK_MEMBER)((member->conference)->eflags & EFLAG_KICK_MEMBER)) { |
6366 | if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6366, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6367 | conference_add_event_member_data(member, event); |
6368 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "kick-member"); |
6369 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6369, &event, ((void*)0)); |
6370 | } |
6371 | } |
6372 | |
6373 | return SWITCH_STATUS_SUCCESS; |
6374 | } |
6375 | |
6376 | |
6377 | static switch_status_t conf_api_sub_dtmf(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6378 | { |
6379 | switch_event_t *event; |
6380 | char *dtmf = (char *) data; |
6381 | |
6382 | if (member == NULL((void*)0)) { |
6383 | stream->write_function(stream, "Invalid member!\n"); |
6384 | return SWITCH_STATUS_GENERR; |
6385 | } |
6386 | |
6387 | if (zstr(dtmf)_zstr(dtmf)) { |
6388 | stream->write_function(stream, "Invalid input!\n"); |
6389 | return SWITCH_STATUS_GENERR; |
6390 | } else { |
6391 | char *p; |
6392 | |
6393 | for(p = dtmf; p && *p; p++) { |
6394 | switch_dtmf_t *dt, digit = { *p, SWITCH_DEFAULT_DTMF_DURATION2000 }; |
6395 | |
6396 | switch_zmalloc(dt, sizeof(*dt))(void)((((dt = calloc(1, (sizeof(*dt))))) ? (void) (0) : __assert_fail ("(dt = calloc(1, (sizeof(*dt))))", "mod_conference.c", 6396 , __PRETTY_FUNCTION__)),dt); |
6397 | *dt = digit; |
6398 | |
6399 | switch_queue_push(member->dtmf_queue, dt); |
6400 | switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(member->session, "mod_conference.c" , (const char *)__func__, 6400, SWITCH_SIG_BREAK); |
6401 | } |
6402 | } |
6403 | |
6404 | if (stream != NULL((void*)0)) { |
6405 | stream->write_function(stream, "OK sent %s to %u\n", (char *) data, member->id); |
6406 | } |
6407 | |
6408 | if (test_eflag(member->conference, EFLAG_DTMF_MEMBER)((member->conference)->eflags & EFLAG_DTMF_MEMBER) && |
6409 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6409, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6410 | conference_add_event_member_data(member, event); |
6411 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "dtmf-member"); |
6412 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Digits", dtmf); |
6413 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6413, &event, ((void*)0)); |
6414 | } |
6415 | |
6416 | return SWITCH_STATUS_SUCCESS; |
6417 | } |
6418 | |
6419 | static switch_status_t conf_api_sub_energy(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6420 | { |
6421 | switch_event_t *event; |
6422 | |
6423 | if (member == NULL((void*)0)) { |
6424 | return SWITCH_STATUS_GENERR; |
6425 | } |
6426 | |
6427 | if (data) { |
6428 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
6429 | if (!strcasecmp(data, "up")) { |
6430 | member->energy_level += 200; |
6431 | if (member->energy_level > 1800) { |
6432 | member->energy_level = 1800; |
6433 | } |
6434 | } else if (!strcasecmp(data, "down")) { |
6435 | member->energy_level -= 200; |
6436 | if (member->energy_level < 0) { |
6437 | member->energy_level = 0; |
6438 | } |
6439 | } else { |
6440 | member->energy_level = atoi((char *) data); |
6441 | } |
6442 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
6443 | } |
6444 | if (stream != NULL((void*)0)) { |
6445 | stream->write_function(stream, "Energy %u = %d\n", member->id, member->energy_level); |
6446 | } |
6447 | if (test_eflag(member->conference, EFLAG_ENERGY_LEVEL_MEMBER)((member->conference)->eflags & EFLAG_ENERGY_LEVEL_MEMBER ) && |
6448 | data && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6448, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6449 | conference_add_event_member_data(member, event); |
6450 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "energy-level-member"); |
6451 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Energy-Level", "%d", member->energy_level); |
6452 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6452, &event, ((void*)0)); |
6453 | } |
6454 | |
6455 | return SWITCH_STATUS_SUCCESS; |
6456 | } |
6457 | |
6458 | static switch_status_t conf_api_sub_auto_position(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
6459 | { |
6460 | #ifdef OPENAL_POSITIONING |
6461 | char *arg = NULL((void*)0); |
6462 | int set = 0; |
6463 | |
6464 | if (argc > 2) { |
6465 | arg = argv[2]; |
6466 | } |
6467 | |
6468 | |
6469 | if (!zstr(arg)_zstr(arg)) { |
6470 | if (!strcasecmp(arg, "on")) { |
6471 | switch_set_flag(conference, CFLAG_POSITIONAL)(conference)->flags |= (CFLAG_POSITIONAL); |
6472 | set = 1; |
6473 | } else if (!strcasecmp(arg, "off")) { |
6474 | switch_clear_flag(conference, CFLAG_POSITIONAL)(conference)->flags &= ~(CFLAG_POSITIONAL); |
6475 | } |
6476 | } |
6477 | |
6478 | if (set && switch_test_flag(conference, CFLAG_POSITIONAL)((conference)->flags & CFLAG_POSITIONAL)) { |
6479 | gen_arc(conference, stream); |
6480 | } |
6481 | |
6482 | stream->write_function(stream, "+OK positioning %s\n", switch_test_flag(conference, CFLAG_POSITIONAL)((conference)->flags & CFLAG_POSITIONAL) ? "on" : "off"); |
6483 | |
6484 | #else |
6485 | stream->write_function(stream, "-ERR not supported\n"); |
6486 | |
6487 | #endif |
6488 | |
6489 | return SWITCH_STATUS_SUCCESS; |
6490 | } |
6491 | |
6492 | static switch_status_t conf_api_sub_position(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6493 | { |
6494 | #ifndef OPENAL_POSITIONING |
6495 | stream->write_function(stream, "-ERR not supported\n"); |
6496 | #else |
6497 | switch_event_t *event; |
6498 | |
6499 | if (member == NULL((void*)0)) { |
6500 | return SWITCH_STATUS_GENERR; |
6501 | } |
6502 | |
6503 | if (switch_test_flag(member, MFLAG_NO_POSITIONAL)((member)->flags & MFLAG_NO_POSITIONAL)) { |
6504 | if (stream) stream->write_function(stream, |
6505 | "%s has positional audio blocked.\n", switch_channel_get_name(member->channel)); |
6506 | return SWITCH_STATUS_SUCCESS; |
6507 | } |
6508 | |
6509 | if (!member->al) { |
6510 | if (!switch_test_flag(member, MFLAG_POSITIONAL)((member)->flags & MFLAG_POSITIONAL) && member->conference->channels == 2) { |
6511 | switch_set_flag(member, MFLAG_POSITIONAL)(member)->flags |= (MFLAG_POSITIONAL); |
6512 | member->al = create_al(member->pool); |
6513 | } else { |
6514 | |
6515 | if (stream) { |
6516 | stream->write_function(stream, "Positional audio not avalilable %d\n", member->conference->channels); |
6517 | } |
6518 | return SWITCH_STATUS_FALSE; |
6519 | } |
6520 | } |
6521 | |
6522 | |
6523 | if (data) { |
6524 | if (member_parse_position(member, data) != SWITCH_STATUS_SUCCESS) { |
6525 | if (stream) { |
6526 | stream->write_function(stream, "invalid input!\n"); |
6527 | } |
6528 | return SWITCH_STATUS_FALSE; |
6529 | } |
6530 | } |
6531 | |
6532 | |
6533 | if (stream != NULL((void*)0)) { |
6534 | stream->write_function(stream, "Position %u = %0.2f:%0.2f:%0.2f\n", member->id, member->al->pos_x, member->al->pos_y, member->al->pos_z); |
6535 | } |
6536 | |
6537 | if (test_eflag(member->conference, EFLAG_SET_POSITION_MEMBER)((member->conference)->eflags & EFLAG_SET_POSITION_MEMBER ) && |
6538 | data && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6538, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6539 | conference_add_event_member_data(member, event); |
6540 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "set-position-member"); |
6541 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Position", "%0.2f:%0.2f:%0.2f", member->al->pos_x, member->al->pos_y, member->al->pos_z); |
6542 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6542, &event, ((void*)0)); |
6543 | } |
6544 | |
6545 | #endif |
6546 | |
6547 | return SWITCH_STATUS_SUCCESS; |
6548 | } |
6549 | |
6550 | static switch_status_t conf_api_sub_volume_in(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6551 | { |
6552 | switch_event_t *event; |
6553 | |
6554 | if (member == NULL((void*)0)) |
6555 | return SWITCH_STATUS_GENERR; |
6556 | |
6557 | if (data) { |
6558 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
6559 | if (!strcasecmp(data, "up")) { |
6560 | member->volume_in_level++; |
6561 | switch_normalize_volume(member->volume_in_level)if (member->volume_in_level > 4) member->volume_in_level = 4; if (member->volume_in_level < -4) member->volume_in_level = -4;; |
6562 | } else if (!strcasecmp(data, "down")) { |
6563 | member->volume_in_level--; |
6564 | switch_normalize_volume(member->volume_in_level)if (member->volume_in_level > 4) member->volume_in_level = 4; if (member->volume_in_level < -4) member->volume_in_level = -4;; |
6565 | } else { |
6566 | member->volume_in_level = atoi((char *) data); |
6567 | switch_normalize_volume(member->volume_in_level)if (member->volume_in_level > 4) member->volume_in_level = 4; if (member->volume_in_level < -4) member->volume_in_level = -4;; |
6568 | } |
6569 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
6570 | |
6571 | } |
6572 | if (stream != NULL((void*)0)) { |
6573 | stream->write_function(stream, "Volume IN %u = %d\n", member->id, member->volume_in_level); |
6574 | } |
6575 | if (test_eflag(member->conference, EFLAG_VOLUME_IN_MEMBER)((member->conference)->eflags & EFLAG_VOLUME_IN_MEMBER ) && |
6576 | data && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6576, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6577 | conference_add_event_member_data(member, event); |
6578 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-in-member"); |
6579 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%d", member->volume_in_level); |
6580 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6580, &event, ((void*)0)); |
6581 | } |
6582 | |
6583 | return SWITCH_STATUS_SUCCESS; |
6584 | } |
6585 | |
6586 | static switch_status_t conf_api_sub_volume_out(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6587 | { |
6588 | switch_event_t *event; |
6589 | |
6590 | if (member == NULL((void*)0)) |
6591 | return SWITCH_STATUS_GENERR; |
6592 | |
6593 | if (data) { |
6594 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
6595 | if (!strcasecmp(data, "up")) { |
6596 | member->volume_out_level++; |
6597 | switch_normalize_volume(member->volume_out_level)if (member->volume_out_level > 4) member->volume_out_level = 4; if (member->volume_out_level < -4) member->volume_out_level = -4;; |
6598 | } else if (!strcasecmp(data, "down")) { |
6599 | member->volume_out_level--; |
6600 | switch_normalize_volume(member->volume_out_level)if (member->volume_out_level > 4) member->volume_out_level = 4; if (member->volume_out_level < -4) member->volume_out_level = -4;; |
6601 | } else { |
6602 | member->volume_out_level = atoi((char *) data); |
6603 | switch_normalize_volume(member->volume_out_level)if (member->volume_out_level > 4) member->volume_out_level = 4; if (member->volume_out_level < -4) member->volume_out_level = -4;; |
6604 | } |
6605 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
6606 | } |
6607 | if (stream != NULL((void*)0)) { |
6608 | stream->write_function(stream, "Volume OUT %u = %d\n", member->id, member->volume_out_level); |
6609 | } |
6610 | if (test_eflag(member->conference, EFLAG_VOLUME_OUT_MEMBER)((member->conference)->eflags & EFLAG_VOLUME_OUT_MEMBER ) && data && |
6611 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 6611, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
6612 | conference_add_event_member_data(member, event); |
6613 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-out-member"); |
6614 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%d", member->volume_out_level); |
6615 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 6615, &event, ((void*)0)); |
6616 | } |
6617 | |
6618 | return SWITCH_STATUS_SUCCESS; |
6619 | } |
6620 | |
6621 | static switch_status_t conf_api_sub_list(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
6622 | { |
6623 | int ret_status = SWITCH_STATUS_GENERR; |
6624 | int count = 0; |
6625 | switch_hash_index_t *hi; |
6626 | void *val; |
6627 | char *d = ";"; |
6628 | int pretty = 0; |
6629 | int summary = 0; |
6630 | int countonly = 0; |
6631 | int argofs = (argc >= 2 && strcasecmp(argv[1], "list") == 0); /* detect being called from chat vs. api */ |
6632 | |
6633 | if (argv[1 + argofs]) { |
6634 | if (argv[2 + argofs] && !strcasecmp(argv[1 + argofs], "delim")) { |
6635 | d = argv[2 + argofs]; |
6636 | |
6637 | if (*d == '"') { |
6638 | if (++d) { |
6639 | char *p; |
6640 | if ((p = strchr(d, '"')(__extension__ (__builtin_constant_p ('"') && !__builtin_constant_p (d) && ('"') == '\0' ? (char *) __rawmemchr (d, '"') : __builtin_strchr (d, '"'))))) { |
6641 | *p = '\0'; |
6642 | } |
6643 | } else { |
6644 | d = ";"; |
6645 | } |
6646 | } |
6647 | } else if (strcasecmp(argv[1 + argofs], "pretty") == 0) { |
6648 | pretty = 1; |
6649 | } else if (strcasecmp(argv[1 + argofs], "summary") == 0) { |
6650 | summary = 1; |
6651 | } else if (strcasecmp(argv[1 + argofs], "count") == 0) { |
6652 | countonly = 1; |
6653 | } |
6654 | } |
6655 | |
6656 | if (conference == NULL((void*)0)) { |
6657 | switch_mutex_lock(globals.hash_mutex); |
6658 | for (hi = switch_core_hash_first(globals.conference_hash)switch_core_hash_first_iter(globals.conference_hash, ((void*) 0)); hi; hi = switch_core_hash_next(&hi)) { |
6659 | int fcount = 0; |
6660 | switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val); |
6661 | conference = (conference_obj_t *) val; |
6662 | |
6663 | stream->write_function(stream, "Conference %s (%u member%s rate: %u%s flags: ", |
6664 | conference->name, |
6665 | conference->count, |
6666 | conference->count == 1 ? "" : "s", conference->rate, switch_test_flag(conference, CFLAG_LOCKED)((conference)->flags & CFLAG_LOCKED) ? " locked" : ""); |
6667 | |
6668 | if (switch_test_flag(conference, CFLAG_LOCKED)((conference)->flags & CFLAG_LOCKED)) { |
6669 | stream->write_function(stream, "%slocked", fcount ? "|" : ""); |
6670 | fcount++; |
6671 | } |
6672 | |
6673 | if (switch_test_flag(conference, CFLAG_DESTRUCT)((conference)->flags & CFLAG_DESTRUCT)) { |
6674 | stream->write_function(stream, "%sdestruct", fcount ? "|" : ""); |
6675 | fcount++; |
6676 | } |
6677 | |
6678 | if (switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) { |
6679 | stream->write_function(stream, "%swait_mod", fcount ? "|" : ""); |
6680 | fcount++; |
6681 | } |
6682 | |
6683 | if (switch_test_flag(conference, CFLAG_AUDIO_ALWAYS)((conference)->flags & CFLAG_AUDIO_ALWAYS)) { |
6684 | stream->write_function(stream, "%saudio_always", fcount ? "|" : ""); |
6685 | fcount++; |
6686 | } |
6687 | |
6688 | if (switch_test_flag(conference, CFLAG_RUNNING)((conference)->flags & CFLAG_RUNNING)) { |
6689 | stream->write_function(stream, "%srunning", fcount ? "|" : ""); |
6690 | fcount++; |
6691 | } |
6692 | |
6693 | if (switch_test_flag(conference, CFLAG_ANSWERED)((conference)->flags & CFLAG_ANSWERED)) { |
6694 | stream->write_function(stream, "%sanswered", fcount ? "|" : ""); |
6695 | fcount++; |
6696 | } |
6697 | |
6698 | if (switch_test_flag(conference, CFLAG_ENFORCE_MIN)((conference)->flags & CFLAG_ENFORCE_MIN)) { |
6699 | stream->write_function(stream, "%senforce_min", fcount ? "|" : ""); |
6700 | fcount++; |
6701 | } |
6702 | |
6703 | if (switch_test_flag(conference, CFLAG_BRIDGE_TO)((conference)->flags & CFLAG_BRIDGE_TO)) { |
6704 | stream->write_function(stream, "%sbridge_to", fcount ? "|" : ""); |
6705 | fcount++; |
6706 | } |
6707 | |
6708 | if (switch_test_flag(conference, CFLAG_DYNAMIC)((conference)->flags & CFLAG_DYNAMIC)) { |
6709 | stream->write_function(stream, "%sdynamic", fcount ? "|" : ""); |
6710 | fcount++; |
6711 | } |
6712 | |
6713 | if (switch_test_flag(conference, CFLAG_EXIT_SOUND)((conference)->flags & CFLAG_EXIT_SOUND)) { |
6714 | stream->write_function(stream, "%sexit_sound", fcount ? "|" : ""); |
6715 | fcount++; |
6716 | } |
6717 | |
6718 | if (switch_test_flag(conference, CFLAG_ENTER_SOUND)((conference)->flags & CFLAG_ENTER_SOUND)) { |
6719 | stream->write_function(stream, "%senter_sound", fcount ? "|" : ""); |
6720 | fcount++; |
6721 | } |
6722 | |
6723 | if (conference->record_count > 0) { |
6724 | stream->write_function(stream, "%srecording", fcount ? "|" : ""); |
6725 | fcount++; |
6726 | } |
6727 | |
6728 | if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE)) { |
6729 | stream->write_function(stream, "%svideo_bridge", fcount ? "|" : ""); |
6730 | fcount++; |
6731 | } |
6732 | |
6733 | if (switch_test_flag(conference, CFLAG_VID_FLOOR)((conference)->flags & CFLAG_VID_FLOOR)) { |
6734 | stream->write_function(stream, "%svideo_floor_only", fcount ? "|" : ""); |
6735 | fcount++; |
6736 | } |
6737 | |
6738 | if (switch_test_flag(conference, CFLAG_RFC4579)((conference)->flags & CFLAG_RFC4579)) { |
6739 | stream->write_function(stream, "%svideo_rfc4579", fcount ? "|" : ""); |
6740 | fcount++; |
6741 | } |
6742 | |
6743 | if (!fcount) { |
6744 | stream->write_function(stream, "none"); |
6745 | } |
6746 | |
6747 | stream->write_function(stream, ")\n"); |
6748 | |
6749 | count++; |
6750 | if (!summary) { |
6751 | if (pretty) { |
6752 | conference_list_pretty(conference, stream); |
6753 | } else { |
6754 | conference_list(conference, stream, d); |
6755 | } |
6756 | } |
6757 | } |
6758 | switch_mutex_unlock(globals.hash_mutex); |
6759 | } else { |
6760 | count++; |
6761 | if (countonly) { |
6762 | conference_list_count_only(conference, stream); |
6763 | } else if (pretty) { |
6764 | conference_list_pretty(conference, stream); |
6765 | } else { |
6766 | conference_list(conference, stream, d); |
6767 | } |
6768 | } |
6769 | |
6770 | if (!count) { |
6771 | stream->write_function(stream, "No active conferences.\n"); |
6772 | } |
6773 | |
6774 | ret_status = SWITCH_STATUS_SUCCESS; |
6775 | |
6776 | return ret_status; |
6777 | } |
6778 | |
6779 | static switch_status_t conf_api_sub_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6780 | { |
6781 | |
6782 | if (member == NULL((void*)0)) |
6783 | return SWITCH_STATUS_GENERR; |
6784 | |
6785 | switch_mutex_lock(member->conference->mutex); |
6786 | |
6787 | if (member->conference->floor_holder == member) { |
6788 | conference_set_floor_holder(member->conference, NULL((void*)0)); |
6789 | if (stream != NULL((void*)0)) { |
6790 | stream->write_function(stream, "OK floor none\n"); |
6791 | } |
6792 | } else if (member->conference->floor_holder == NULL((void*)0)) { |
6793 | conference_set_floor_holder(member->conference, member); |
6794 | if (stream != NULL((void*)0)) { |
6795 | stream->write_function(stream, "OK floor %u\n", member->id); |
6796 | } |
6797 | } else { |
6798 | if (stream != NULL((void*)0)) { |
6799 | stream->write_function(stream, "ERR floor is held by %u\n", member->conference->floor_holder->id); |
6800 | } |
6801 | } |
6802 | |
6803 | switch_mutex_unlock(member->conference->mutex); |
6804 | |
6805 | return SWITCH_STATUS_SUCCESS; |
6806 | } |
6807 | |
6808 | static switch_status_t conf_api_sub_clear_vid_floor(conference_obj_t *conference, switch_stream_handle_t *stream, void *data) |
6809 | { |
6810 | |
6811 | if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE)) { |
6812 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 6812, ((void*)0), SWITCH_LOG_WARNING, |
6813 | "conference %s is in video bridge mode, this functionality is not compatible\n", conference->name); |
6814 | return SWITCH_STATUS_FALSE; |
6815 | } |
6816 | |
6817 | switch_mutex_lock(conference->mutex); |
6818 | switch_clear_flag(conference, CFLAG_VID_FLOOR_LOCK)(conference)->flags &= ~(CFLAG_VID_FLOOR_LOCK); |
6819 | //conference_set_video_floor_holder(conference, NULL); |
6820 | switch_mutex_unlock(conference->mutex); |
6821 | |
6822 | return SWITCH_STATUS_SUCCESS; |
6823 | } |
6824 | |
6825 | static switch_status_t conf_api_sub_vid_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data) |
6826 | { |
6827 | int force = 0; |
6828 | |
6829 | if (member == NULL((void*)0)) |
6830 | return SWITCH_STATUS_GENERR; |
6831 | |
6832 | if (!switch_channel_test_flag(member->channel, CF_VIDEO)) { |
6833 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 6833, ((void*)0), SWITCH_LOG_ERROR, "Channel %s does not have video capability!\n", switch_channel_get_name(member->channel)); |
6834 | return SWITCH_STATUS_FALSE; |
6835 | } |
6836 | |
6837 | if (switch_test_flag(member->conference, CFLAG_VIDEO_BRIDGE)((member->conference)->flags & CFLAG_VIDEO_BRIDGE)) { |
6838 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 6838, ((void*)0), SWITCH_LOG_ERROR, |
6839 | "conference %s is in video bridge mode, this functionality is not compatible\n", member->conference->name); |
6840 | return SWITCH_STATUS_FALSE; |
6841 | } |
6842 | |
6843 | switch_mutex_lock(member->conference->mutex); |
6844 | |
6845 | if (data && switch_stristr("force", (char *) data)) { |
6846 | force = 1; |
6847 | } |
6848 | |
6849 | if (member->conference->video_floor_holder == member && switch_test_flag(member->conference, CFLAG_VID_FLOOR_LOCK)((member->conference)->flags & CFLAG_VID_FLOOR_LOCK )) { |
6850 | switch_clear_flag(member->conference, CFLAG_VID_FLOOR_LOCK)(member->conference)->flags &= ~(CFLAG_VID_FLOOR_LOCK ); |
6851 | |
6852 | conference_set_floor_holder(member->conference, member); |
6853 | if (stream == NULL((void*)0)) { |
6854 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 6854, ((void*)0), SWITCH_LOG_INFO, "conference %s OK video floor auto\n", member->conference->name); |
6855 | } else { |
6856 | stream->write_function(stream, "OK floor none\n"); |
6857 | } |
6858 | |
6859 | } else if (force || member->conference->video_floor_holder == NULL((void*)0)) { |
6860 | switch_set_flag(member->conference, CFLAG_VID_FLOOR_LOCK)(member->conference)->flags |= (CFLAG_VID_FLOOR_LOCK); |
6861 | conference_set_video_floor_holder(member->conference, member, SWITCH_TRUE); |
6862 | if (test_eflag(member->conference, EFLAG_FLOOR_CHANGE)((member->conference)->eflags & EFLAG_FLOOR_CHANGE)) { |
6863 | if (stream == NULL((void*)0)) { |
6864 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 6864, ((void*)0), SWITCH_LOG_INFO, "conference %s OK video floor %d %s\n", |
6865 | member->conference->name, member->id, switch_channel_get_name(member->channel)); |
6866 | } else { |
6867 | stream->write_function(stream, "OK floor %u\n", member->id); |
6868 | } |
6869 | } |
6870 | } else { |
6871 | if (stream == NULL((void*)0)) { |
6872 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 6872, ((void*)0), SWITCH_LOG_INFO, "conference %s floor already held by %d %s\n", |
6873 | member->conference->name, member->id, switch_channel_get_name(member->channel)); |
6874 | } else { |
6875 | stream->write_function(stream, "ERR floor is held by %u\n", member->conference->video_floor_holder->id); |
6876 | } |
6877 | } |
6878 | |
6879 | switch_mutex_unlock(member->conference->mutex); |
6880 | |
6881 | return SWITCH_STATUS_SUCCESS; |
6882 | } |
6883 | |
6884 | static switch_xml_t add_x_tag(switch_xml_t x_member, const char *name, const char *value, int off) |
6885 | { |
6886 | switch_size_t dlen; |
6887 | char *data; |
6888 | switch_xml_t x_tag; |
6889 | |
6890 | if (!value) { |
6891 | return 0; |
6892 | } |
6893 | |
6894 | dlen = strlen(value) * 3 + 1; |
6895 | |
6896 | x_tag = switch_xml_add_child_d(x_member, name, off)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p (name) && ((size_t)(const void *)((name) + 1) - (size_t)(const void *)(name) == 1) ? (((const char *) (name))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (name) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, name, __len); __retval; })) : __strdup (name))), off), SWITCH_XML_NAMEM); |
6897 | switch_assert(x_tag)((x_tag) ? (void) (0) : __assert_fail ("x_tag", "mod_conference.c" , 6897, __PRETTY_FUNCTION__)); |
6898 | |
6899 | switch_zmalloc(data, dlen)(void)((((data = calloc(1, (dlen)))) ? (void) (0) : __assert_fail ("(data = calloc(1, (dlen)))", "mod_conference.c", 6899, __PRETTY_FUNCTION__ )),data); |
6900 | |
6901 | switch_url_encode(value, data, dlen); |
6902 | switch_xml_set_txt_d(x_tag, data)switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (data) && ((size_t)(const void * )((data) + 1) - (size_t)(const void *)(data) == 1) ? (((const char *) (data))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (data) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, data, __len); __retval; })) : __strdup (data)))), SWITCH_XML_TXTM); |
6903 | free(data); |
6904 | |
6905 | return x_tag; |
6906 | } |
6907 | |
6908 | static void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, int off) |
6909 | { |
6910 | conference_member_t *member = NULL((void*)0); |
6911 | switch_xml_t x_member = NULL((void*)0), x_members = NULL((void*)0), x_flags; |
6912 | int moff = 0; |
6913 | char i[30] = ""; |
6914 | char *ival = i; |
6915 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 6915, __PRETTY_FUNCTION__)); |
6916 | switch_assert(x_conference != NULL)((x_conference != ((void*)0)) ? (void) (0) : __assert_fail ("x_conference != ((void*)0)" , "mod_conference.c", 6916, __PRETTY_FUNCTION__)); |
6917 | |
6918 | switch_xml_set_attr_d(x_conference, "name", conference->name)switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("name") && ( (size_t)(const void *)(("name") + 1) - (size_t)(const void *) ("name") == 1) ? (((const char *) ("name"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("name") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "name", __len); __retval; })) : __strdup ("name"))), (__extension__ (__builtin_constant_p ((conference->name ? conference-> name : "")) && ((size_t)(const void *)(((conference-> name ? conference->name : "")) + 1) - (size_t)(const void * )((conference->name ? conference->name : "")) == 1) ? ( ((const char *) ((conference->name ? conference->name : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((conference->name ? conference-> name : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , (conference->name ? conference->name : ""), __len); __retval ; })) : __strdup ((conference->name ? conference->name : ""))))); |
6919 | switch_snprintf(i, sizeof(i), "%d", conference->count); |
6920 | switch_xml_set_attr_d(x_conference, "member-count", ival)switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("member-count") && ((size_t)(const void *)(("member-count") + 1) - (size_t)(const void *)("member-count") == 1) ? (((const char *) ("member-count" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("member-count") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "member-count", __len); __retval ; })) : __strdup ("member-count"))), (__extension__ (__builtin_constant_p ((ival ? ival : "")) && ((size_t)(const void *)(((ival ? ival : "")) + 1) - (size_t)(const void *)((ival ? ival : "" )) == 1) ? (((const char *) ((ival ? ival : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((ival ? ival : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (ival ? ival : ""), __len); __retval; })) : __strdup ((ival ? ival : ""))))); |
6921 | switch_snprintf(i, sizeof(i), "%d", conference->count_ghosts); |
6922 | switch_xml_set_attr_d(x_conference, "ghost-count", ival)switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("ghost-count") && ((size_t)(const void *)(("ghost-count") + 1) - (size_t)(const void *)("ghost-count") == 1) ? (((const char *) ("ghost-count" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("ghost-count") + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "ghost-count", __len); __retval; } )) : __strdup ("ghost-count"))), (__extension__ (__builtin_constant_p ((ival ? ival : "")) && ((size_t)(const void *)(((ival ? ival : "")) + 1) - (size_t)(const void *)((ival ? ival : "" )) == 1) ? (((const char *) ((ival ? ival : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((ival ? ival : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (ival ? ival : ""), __len); __retval; })) : __strdup ((ival ? ival : ""))))); |
6923 | switch_snprintf(i, sizeof(i), "%u", conference->rate); |
6924 | switch_xml_set_attr_d(x_conference, "rate", ival)switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("rate") && ( (size_t)(const void *)(("rate") + 1) - (size_t)(const void *) ("rate") == 1) ? (((const char *) ("rate"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("rate") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "rate", __len); __retval; })) : __strdup ("rate"))), (__extension__ (__builtin_constant_p ((ival ? ival : "")) && ((size_t )(const void *)(((ival ? ival : "")) + 1) - (size_t)(const void *)((ival ? ival : "")) == 1) ? (((const char *) ((ival ? ival : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1 ) : ({ size_t __len = strlen ((ival ? ival : "")) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, (ival ? ival : ""), __len ); __retval; })) : __strdup ((ival ? ival : ""))))); |
6925 | switch_xml_set_attr_d(x_conference, "uuid", conference->uuid_str)switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("uuid") && ( (size_t)(const void *)(("uuid") + 1) - (size_t)(const void *) ("uuid") == 1) ? (((const char *) ("uuid"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("uuid") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "uuid", __len); __retval; })) : __strdup ("uuid"))), (__extension__ (__builtin_constant_p ((conference->uuid_str ? conference ->uuid_str : "")) && ((size_t)(const void *)(((conference ->uuid_str ? conference->uuid_str : "")) + 1) - (size_t )(const void *)((conference->uuid_str ? conference->uuid_str : "")) == 1) ? (((const char *) ((conference->uuid_str ? conference ->uuid_str : "")))[0] == '\0' ? (char *) calloc ((size_t) 1 , (size_t) 1) : ({ size_t __len = strlen ((conference->uuid_str ? conference->uuid_str : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (conference->uuid_str ? conference-> uuid_str : ""), __len); __retval; })) : __strdup ((conference ->uuid_str ? conference->uuid_str : ""))))); |
6926 | |
6927 | if (switch_test_flag(conference, CFLAG_LOCKED)((conference)->flags & CFLAG_LOCKED)) { |
6928 | switch_xml_set_attr_d(x_conference, "locked", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("locked") && ((size_t)(const void *)(("locked") + 1) - (size_t)(const void *)("locked") == 1) ? (((const char *) ("locked"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("locked") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "locked", __len); __retval; })) : __strdup ("locked"))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && (( size_t)(const void *)((("true" ? "true" : "")) + 1) - (size_t )(const void *)(("true" ? "true" : "")) == 1) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""), __len); __retval; })) : __strdup (("true" ? "true" : ""))))); |
6929 | } |
6930 | |
6931 | if (switch_test_flag(conference, CFLAG_DESTRUCT)((conference)->flags & CFLAG_DESTRUCT)) { |
6932 | switch_xml_set_attr_d(x_conference, "destruct", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("destruct") && ((size_t)(const void *)(("destruct") + 1) - (size_t)(const void *)("destruct") == 1) ? (((const char *) ("destruct"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("destruct") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "destruct", __len); __retval; })) : __strdup ("destruct" ))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)((("true" ? "true" : "" )) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1 ) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""), __len); __retval; })) : __strdup (("true" ? "true" : ""))))); |
6933 | } |
6934 | |
6935 | if (switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) { |
6936 | switch_xml_set_attr_d(x_conference, "wait_mod", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("wait_mod") && ((size_t)(const void *)(("wait_mod") + 1) - (size_t)(const void *)("wait_mod") == 1) ? (((const char *) ("wait_mod"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("wait_mod") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "wait_mod", __len); __retval; })) : __strdup ("wait_mod" ))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)((("true" ? "true" : "" )) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1 ) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""), __len); __retval; })) : __strdup (("true" ? "true" : ""))))); |
6937 | } |
6938 | |
6939 | if (switch_test_flag(conference, CFLAG_AUDIO_ALWAYS)((conference)->flags & CFLAG_AUDIO_ALWAYS)) { |
6940 | switch_xml_set_attr_d(x_conference, "audio_always", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("audio_always") && ((size_t)(const void *)(("audio_always") + 1) - (size_t)(const void *)("audio_always") == 1) ? (((const char *) ("audio_always" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("audio_always") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "audio_always", __len); __retval ; })) : __strdup ("audio_always"))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)( (("true" ? "true" : "")) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, ("true" ? "true" : "" ), __len); __retval; })) : __strdup (("true" ? "true" : ""))) )); |
6941 | } |
6942 | |
6943 | if (switch_test_flag(conference, CFLAG_RUNNING)((conference)->flags & CFLAG_RUNNING)) { |
6944 | switch_xml_set_attr_d(x_conference, "running", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("running") && ((size_t)(const void *)(("running") + 1) - (size_t)(const void *)("running") == 1) ? (((const char *) ("running"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("running") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "running", __len); __retval; })) : __strdup ("running" ))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)((("true" ? "true" : "" )) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1 ) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""), __len); __retval; })) : __strdup (("true" ? "true" : ""))))); |
6945 | } |
6946 | |
6947 | if (switch_test_flag(conference, CFLAG_ANSWERED)((conference)->flags & CFLAG_ANSWERED)) { |
6948 | switch_xml_set_attr_d(x_conference, "answered", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("answered") && ((size_t)(const void *)(("answered") + 1) - (size_t)(const void *)("answered") == 1) ? (((const char *) ("answered"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("answered") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "answered", __len); __retval; })) : __strdup ("answered" ))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)((("true" ? "true" : "" )) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1 ) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""), __len); __retval; })) : __strdup (("true" ? "true" : ""))))); |
6949 | } |
6950 | |
6951 | if (switch_test_flag(conference, CFLAG_ENFORCE_MIN)((conference)->flags & CFLAG_ENFORCE_MIN)) { |
6952 | switch_xml_set_attr_d(x_conference, "enforce_min", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("enforce_min") && ((size_t)(const void *)(("enforce_min") + 1) - (size_t)(const void *)("enforce_min") == 1) ? (((const char *) ("enforce_min" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("enforce_min") + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "enforce_min", __len); __retval; } )) : __strdup ("enforce_min"))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)( (("true" ? "true" : "")) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, ("true" ? "true" : "" ), __len); __retval; })) : __strdup (("true" ? "true" : ""))) )); |
6953 | } |
6954 | |
6955 | if (switch_test_flag(conference, CFLAG_BRIDGE_TO)((conference)->flags & CFLAG_BRIDGE_TO)) { |
6956 | switch_xml_set_attr_d(x_conference, "bridge_to", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("bridge_to") && ((size_t)(const void *)(("bridge_to") + 1) - (size_t)(const void *)("bridge_to") == 1) ? (((const char *) ("bridge_to"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("bridge_to") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "bridge_to", __len); __retval; })) : __strdup ("bridge_to" ))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)((("true" ? "true" : "" )) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1 ) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""), __len); __retval; })) : __strdup (("true" ? "true" : ""))))); |
6957 | } |
6958 | |
6959 | if (switch_test_flag(conference, CFLAG_DYNAMIC)((conference)->flags & CFLAG_DYNAMIC)) { |
6960 | switch_xml_set_attr_d(x_conference, "dynamic", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("dynamic") && ((size_t)(const void *)(("dynamic") + 1) - (size_t)(const void *)("dynamic") == 1) ? (((const char *) ("dynamic"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("dynamic") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "dynamic", __len); __retval; })) : __strdup ("dynamic" ))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)((("true" ? "true" : "" )) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1 ) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""), __len); __retval; })) : __strdup (("true" ? "true" : ""))))); |
6961 | } |
6962 | |
6963 | if (switch_test_flag(conference, CFLAG_EXIT_SOUND)((conference)->flags & CFLAG_EXIT_SOUND)) { |
6964 | switch_xml_set_attr_d(x_conference, "exit_sound", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("exit_sound") && ((size_t)(const void *)(("exit_sound") + 1) - (size_t)(const void *)("exit_sound") == 1) ? (((const char *) ("exit_sound" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("exit_sound") + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "exit_sound", __len); __retval; } )) : __strdup ("exit_sound"))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)( (("true" ? "true" : "")) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, ("true" ? "true" : "" ), __len); __retval; })) : __strdup (("true" ? "true" : ""))) )); |
6965 | } |
6966 | |
6967 | if (switch_test_flag(conference, CFLAG_ENTER_SOUND)((conference)->flags & CFLAG_ENTER_SOUND)) { |
6968 | switch_xml_set_attr_d(x_conference, "enter_sound", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("enter_sound") && ((size_t)(const void *)(("enter_sound") + 1) - (size_t)(const void *)("enter_sound") == 1) ? (((const char *) ("enter_sound" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("enter_sound") + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "enter_sound", __len); __retval; } )) : __strdup ("enter_sound"))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)( (("true" ? "true" : "")) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, ("true" ? "true" : "" ), __len); __retval; })) : __strdup (("true" ? "true" : ""))) )); |
6969 | } |
6970 | |
6971 | if (conference->max_members > 0) { |
6972 | switch_snprintf(i, sizeof(i), "%d", conference->max_members); |
6973 | switch_xml_set_attr_d(x_conference, "max_members", ival)switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("max_members") && ((size_t)(const void *)(("max_members") + 1) - (size_t)(const void *)("max_members") == 1) ? (((const char *) ("max_members" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("max_members") + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "max_members", __len); __retval; } )) : __strdup ("max_members"))), (__extension__ (__builtin_constant_p ((ival ? ival : "")) && ((size_t)(const void *)(((ival ? ival : "")) + 1) - (size_t)(const void *)((ival ? ival : "" )) == 1) ? (((const char *) ((ival ? ival : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((ival ? ival : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (ival ? ival : ""), __len); __retval; })) : __strdup ((ival ? ival : ""))))); |
6974 | } |
6975 | |
6976 | if (conference->record_count > 0) { |
6977 | switch_xml_set_attr_d(x_conference, "recording", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("recording") && ((size_t)(const void *)(("recording") + 1) - (size_t)(const void *)("recording") == 1) ? (((const char *) ("recording"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("recording") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "recording", __len); __retval; })) : __strdup ("recording" ))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)((("true" ? "true" : "" )) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1 ) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""), __len); __retval; })) : __strdup (("true" ? "true" : ""))))); |
6978 | } |
6979 | |
6980 | if (conference->endconf_grace_time > 0) { |
6981 | switch_snprintf(i, sizeof(i), "%u", conference->endconf_grace_time); |
6982 | switch_xml_set_attr_d(x_conference, "endconf_grace_time", ival)switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("endconf_grace_time" ) && ((size_t)(const void *)(("endconf_grace_time") + 1) - (size_t)(const void *)("endconf_grace_time") == 1) ? (( (const char *) ("endconf_grace_time"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("endconf_grace_time" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "endconf_grace_time" , __len); __retval; })) : __strdup ("endconf_grace_time"))), ( __extension__ (__builtin_constant_p ((ival ? ival : "")) && ((size_t)(const void *)(((ival ? ival : "")) + 1) - (size_t) (const void *)((ival ? ival : "")) == 1) ? (((const char *) ( (ival ? ival : "")))[0] == '\0' ? (char *) calloc ((size_t) 1 , (size_t) 1) : ({ size_t __len = strlen ((ival ? ival : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (ival ? ival : ""), __len); __retval; })) : __strdup ((ival ? ival : "")) ))); |
6983 | } |
6984 | |
6985 | if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE)) { |
6986 | switch_xml_set_attr_d(x_conference, "video_bridge", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("video_bridge") && ((size_t)(const void *)(("video_bridge") + 1) - (size_t)(const void *)("video_bridge") == 1) ? (((const char *) ("video_bridge" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("video_bridge") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "video_bridge", __len); __retval ; })) : __strdup ("video_bridge"))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)( (("true" ? "true" : "")) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, ("true" ? "true" : "" ), __len); __retval; })) : __strdup (("true" ? "true" : ""))) )); |
6987 | } |
6988 | |
6989 | if (switch_test_flag(conference, CFLAG_VID_FLOOR)((conference)->flags & CFLAG_VID_FLOOR)) { |
6990 | switch_xml_set_attr_d(x_conference, "video_floor_only", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("video_floor_only") && ((size_t)(const void *)(("video_floor_only") + 1) - (size_t) (const void *)("video_floor_only") == 1) ? (((const char *) ( "video_floor_only"))[0] == '\0' ? (char *) calloc ((size_t) 1 , (size_t) 1) : ({ size_t __len = strlen ("video_floor_only") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "video_floor_only" , __len); __retval; })) : __strdup ("video_floor_only"))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && (( size_t)(const void *)((("true" ? "true" : "")) + 1) - (size_t )(const void *)(("true" ? "true" : "")) == 1) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("true" ? "true" : ""), __len); __retval; })) : __strdup (("true" ? "true" : ""))))); |
6991 | } |
6992 | |
6993 | if (switch_test_flag(conference, CFLAG_RFC4579)((conference)->flags & CFLAG_RFC4579)) { |
6994 | switch_xml_set_attr_d(x_conference, "video_rfc4579", "true")switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("video_rfc4579") && ((size_t)(const void *)(("video_rfc4579") + 1) - (size_t)(const void *)("video_rfc4579") == 1) ? (((const char *) ("video_rfc4579" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("video_rfc4579") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "video_rfc4579", __len); __retval ; })) : __strdup ("video_rfc4579"))), (__extension__ (__builtin_constant_p (("true" ? "true" : "")) && ((size_t)(const void *)( (("true" ? "true" : "")) + 1) - (size_t)(const void *)(("true" ? "true" : "")) == 1) ? (((const char *) (("true" ? "true" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("true" ? "true" : "")) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, ("true" ? "true" : "" ), __len); __retval; })) : __strdup (("true" ? "true" : ""))) )); |
6995 | } |
6996 | |
6997 | switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL((void*)0)) - conference->run_time); |
6998 | switch_xml_set_attr_d(x_conference, "run_time", ival)switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("run_time") && ((size_t)(const void *)(("run_time") + 1) - (size_t)(const void *)("run_time") == 1) ? (((const char *) ("run_time"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("run_time") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "run_time", __len); __retval; })) : __strdup ("run_time" ))), (__extension__ (__builtin_constant_p ((ival ? ival : "") ) && ((size_t)(const void *)(((ival ? ival : "")) + 1 ) - (size_t)(const void *)((ival ? ival : "")) == 1) ? (((const char *) ((ival ? ival : "")))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((ival ? ival : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (ival ? ival : ""), __len); __retval; })) : __strdup ((ival ? ival : ""))))); |
6999 | |
7000 | if (conference->agc_level) { |
7001 | char tmp[30] = ""; |
7002 | switch_snprintf(tmp, sizeof(tmp), "%d", conference->agc_level); |
7003 | switch_xml_set_attr_d_buf(x_conference, "agc", tmp)switch_xml_set_attr(switch_xml_set_flag(x_conference, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("agc") && (( size_t)(const void *)(("agc") + 1) - (size_t)(const void *)("agc" ) == 1) ? (((const char *) ("agc"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("agc") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "agc", __len ); __retval; })) : __strdup ("agc"))), (__extension__ (__builtin_constant_p (tmp) && ((size_t)(const void *)((tmp) + 1) - (size_t )(const void *)(tmp) == 1) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , tmp, __len); __retval; })) : __strdup (tmp)))); |
7004 | } |
7005 | |
7006 | x_members = switch_xml_add_child_d(x_conference, "members", 0)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("members") && ((size_t)(const void *)(("members") + 1) - (size_t)(const void *)("members") == 1) ? (((const char *) ("members"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("members" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "members" , __len); __retval; })) : __strdup ("members"))), 0), SWITCH_XML_NAMEM ); |
7007 | switch_assert(x_members)((x_members) ? (void) (0) : __assert_fail ("x_members", "mod_conference.c" , 7007, __PRETTY_FUNCTION__)); |
7008 | |
7009 | switch_mutex_lock(conference->member_mutex); |
7010 | |
7011 | for (member = conference->members; member; member = member->next) { |
7012 | switch_channel_t *channel; |
7013 | switch_caller_profile_t *profile; |
7014 | char *uuid; |
7015 | //char *name; |
7016 | uint32_t count = 0; |
7017 | switch_xml_t x_tag; |
7018 | int toff = 0; |
7019 | char tmp[50] = ""; |
7020 | |
7021 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
7022 | if (member->rec_path) { |
7023 | x_member = switch_xml_add_child_d(x_members, "member", moff++)switch_xml_set_flag(switch_xml_add_child(x_members, (__extension__ (__builtin_constant_p ("member") && ((size_t)(const void *)(("member") + 1) - (size_t)(const void *)("member") == 1) ? (((const char *) ("member"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("member") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "member", __len ); __retval; })) : __strdup ("member"))), moff++), SWITCH_XML_NAMEM ); |
7024 | switch_assert(x_member)((x_member) ? (void) (0) : __assert_fail ("x_member", "mod_conference.c" , 7024, __PRETTY_FUNCTION__)); |
7025 | switch_xml_set_attr_d(x_member, "type", "recording_node")switch_xml_set_attr(switch_xml_set_flag(x_member, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("recording_node" ? "recording_node" : "")) && ((size_t)(const void *)((("recording_node" ? "recording_node" : "")) + 1) - (size_t)(const void *)(("recording_node" ? "recording_node" : "")) == 1) ? (((const char *) (("recording_node" ? "recording_node" : "")))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (("recording_node" ? "recording_node" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("recording_node" ? "recording_node" : ""), __len ); __retval; })) : __strdup (("recording_node" ? "recording_node" : ""))))); |
7026 | /* or: |
7027 | x_member = switch_xml_add_child_d(x_members, "recording_node", moff++); |
7028 | */ |
7029 | |
7030 | x_tag = switch_xml_add_child_d(x_member, "record_path", count++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("record_path") && ((size_t)(const void *)(("record_path") + 1) - (size_t)(const void *)("record_path" ) == 1) ? (((const char *) ("record_path"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("record_path") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "record_path", __len); __retval; })) : __strdup ("record_path" ))), count++), SWITCH_XML_NAMEM); |
7031 | if (switch_test_flag(member, MFLAG_PAUSE_RECORDING)((member)->flags & MFLAG_PAUSE_RECORDING)) { |
7032 | switch_xml_set_attr_d(x_tag, "status", "paused")switch_xml_set_attr(switch_xml_set_flag(x_tag, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("status") && ((size_t)(const void *)(("status") + 1) - (size_t)(const void *)("status") == 1) ? (((const char *) ("status"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("status") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "status", __len); __retval; })) : __strdup ("status"))), (__extension__ (__builtin_constant_p (("paused" ? "paused" : "")) && ((size_t)(const void *)((("paused" ? "paused" : "")) + 1) - ( size_t)(const void *)(("paused" ? "paused" : "")) == 1) ? ((( const char *) (("paused" ? "paused" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("paused" ? "paused" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("paused" ? "paused" : ""), __len); __retval; })) : __strdup (("paused" ? "paused" : ""))))); |
7033 | } |
7034 | switch_xml_set_txt_d(x_tag, member->rec_path)switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (member->rec_path) && ((size_t )(const void *)((member->rec_path) + 1) - (size_t)(const void *)(member->rec_path) == 1) ? (((const char *) (member-> rec_path))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (member->rec_path) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, member->rec_path , __len); __retval; })) : __strdup (member->rec_path)))), SWITCH_XML_TXTM ); |
7035 | |
7036 | x_tag = switch_xml_add_child_d(x_member, "join_time", count++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("join_time") && ((size_t)(const void *)(("join_time") + 1) - (size_t)(const void *)("join_time" ) == 1) ? (((const char *) ("join_time"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "join_time") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "join_time", __len); __retval; })) : __strdup ("join_time") )), count++), SWITCH_XML_NAMEM); |
7037 | switch_xml_set_attr_d(x_tag, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_tag, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
7038 | switch_snprintf(i, sizeof(i), "%d", member->rec_time); |
7039 | switch_xml_set_txt_d(x_tag, i)switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (i) && ((size_t)(const void *)(( i) + 1) - (size_t)(const void *)(i) == 1) ? (((const char *) ( i))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ( { size_t __len = strlen (i) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, i, __len); __retval; })) : __strdup (i)))), SWITCH_XML_TXTM ); |
7040 | } |
7041 | continue; |
7042 | } |
7043 | |
7044 | uuid = switch_core_session_get_uuid(member->session); |
7045 | channel = switch_core_session_get_channel(member->session); |
7046 | profile = switch_channel_get_caller_profile(channel); |
7047 | //name = switch_channel_get_name(channel); |
7048 | |
7049 | |
7050 | x_member = switch_xml_add_child_d(x_members, "member", moff++)switch_xml_set_flag(switch_xml_add_child(x_members, (__extension__ (__builtin_constant_p ("member") && ((size_t)(const void *)(("member") + 1) - (size_t)(const void *)("member") == 1) ? (((const char *) ("member"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("member") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "member", __len ); __retval; })) : __strdup ("member"))), moff++), SWITCH_XML_NAMEM ); |
7051 | switch_assert(x_member)((x_member) ? (void) (0) : __assert_fail ("x_member", "mod_conference.c" , 7051, __PRETTY_FUNCTION__)); |
7052 | switch_xml_set_attr_d(x_member, "type", "caller")switch_xml_set_attr(switch_xml_set_flag(x_member, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("caller" ? "caller" : "")) && ((size_t)(const void *)((("caller" ? "caller" : "")) + 1) - ( size_t)(const void *)(("caller" ? "caller" : "")) == 1) ? ((( const char *) (("caller" ? "caller" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("caller" ? "caller" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("caller" ? "caller" : ""), __len); __retval; })) : __strdup (("caller" ? "caller" : ""))))); |
7053 | |
7054 | switch_snprintf(i, sizeof(i), "%d", member->id); |
7055 | |
7056 | add_x_tag(x_member, "id", i, toff++); |
7057 | add_x_tag(x_member, "uuid", uuid, toff++); |
7058 | add_x_tag(x_member, "caller_id_name", profile->caller_id_name, toff++); |
7059 | add_x_tag(x_member, "caller_id_number", profile->caller_id_number, toff++); |
7060 | |
7061 | |
7062 | switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL((void*)0)) - member->join_time); |
7063 | add_x_tag(x_member, "join_time", i, toff++); |
7064 | |
7065 | switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL((void*)0)) - member->last_talking); |
7066 | add_x_tag(x_member, "last_talking", member->last_talking ? i : "N/A", toff++); |
7067 | |
7068 | switch_snprintf(i, sizeof(i), "%d", member->energy_level); |
7069 | add_x_tag(x_member, "energy", i, toff++); |
7070 | |
7071 | switch_snprintf(i, sizeof(i), "%d", member->volume_in_level); |
7072 | add_x_tag(x_member, "volume_in", i, toff++); |
7073 | |
7074 | switch_snprintf(i, sizeof(i), "%d", member->volume_out_level); |
7075 | add_x_tag(x_member, "volume_out", i, toff++); |
7076 | |
7077 | x_flags = switch_xml_add_child_d(x_member, "flags", count++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("flags") && ((size_t)(const void *)(("flags") + 1) - (size_t)(const void *)("flags") == 1) ? ( ((const char *) ("flags"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("flags") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "flags", __len); __retval ; })) : __strdup ("flags"))), count++), SWITCH_XML_NAMEM); |
7078 | switch_assert(x_flags)((x_flags) ? (void) (0) : __assert_fail ("x_flags", "mod_conference.c" , 7078, __PRETTY_FUNCTION__)); |
7079 | |
7080 | x_tag = switch_xml_add_child_d(x_flags, "can_hear", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("can_hear") && ((size_t)(const void *)(("can_hear") + 1) - (size_t)(const void *)("can_hear" ) == 1) ? (((const char *) ("can_hear"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "can_hear") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "can_hear", __len); __retval; })) : __strdup ("can_hear"))) , count++), SWITCH_XML_NAMEM); |
7081 | switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_CAN_HEAR) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((member)->flags & MFLAG_CAN_HEAR ) ? "true" : "false") && ((size_t)(const void *)((((member )->flags & MFLAG_CAN_HEAR) ? "true" : "false") + 1) - ( size_t)(const void *)(((member)->flags & MFLAG_CAN_HEAR ) ? "true" : "false") == 1) ? (((const char *) (((member)-> flags & MFLAG_CAN_HEAR) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((member)->flags & MFLAG_CAN_HEAR) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((member)->flags & MFLAG_CAN_HEAR) ? "true" : "false" , __len); __retval; })) : __strdup (((member)->flags & MFLAG_CAN_HEAR) ? "true" : "false")))), SWITCH_XML_TXTM); |
7082 | |
7083 | x_tag = switch_xml_add_child_d(x_flags, "can_speak", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("can_speak") && ((size_t)(const void *)(("can_speak") + 1) - (size_t)(const void *)("can_speak" ) == 1) ? (((const char *) ("can_speak"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "can_speak") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "can_speak", __len); __retval; })) : __strdup ("can_speak") )), count++), SWITCH_XML_NAMEM); |
7084 | switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_CAN_SPEAK) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((member)->flags & MFLAG_CAN_SPEAK ) ? "true" : "false") && ((size_t)(const void *)((((member )->flags & MFLAG_CAN_SPEAK) ? "true" : "false") + 1) - (size_t)(const void *)(((member)->flags & MFLAG_CAN_SPEAK ) ? "true" : "false") == 1) ? (((const char *) (((member)-> flags & MFLAG_CAN_SPEAK) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((member)->flags & MFLAG_CAN_SPEAK) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((member)->flags & MFLAG_CAN_SPEAK) ? "true" : "false" , __len); __retval; })) : __strdup (((member)->flags & MFLAG_CAN_SPEAK) ? "true" : "false")))), SWITCH_XML_TXTM); |
7085 | |
7086 | x_tag = switch_xml_add_child_d(x_flags, "mute_detect", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("mute_detect") && ((size_t)(const void *)(("mute_detect") + 1) - (size_t)(const void *)("mute_detect" ) == 1) ? (((const char *) ("mute_detect"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("mute_detect") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "mute_detect", __len); __retval; })) : __strdup ("mute_detect" ))), count++), SWITCH_XML_NAMEM); |
7087 | switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((member)->flags & MFLAG_MUTE_DETECT ) ? "true" : "false") && ((size_t)(const void *)((((member )->flags & MFLAG_MUTE_DETECT) ? "true" : "false") + 1) - (size_t)(const void *)(((member)->flags & MFLAG_MUTE_DETECT ) ? "true" : "false") == 1) ? (((const char *) (((member)-> flags & MFLAG_MUTE_DETECT) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((member)->flags & MFLAG_MUTE_DETECT) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , ((member)->flags & MFLAG_MUTE_DETECT) ? "true" : "false" , __len); __retval; })) : __strdup (((member)->flags & MFLAG_MUTE_DETECT) ? "true" : "false")))), SWITCH_XML_TXTM); |
7088 | |
7089 | x_tag = switch_xml_add_child_d(x_flags, "talking", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("talking") && ((size_t)(const void *)(("talking") + 1) - (size_t)(const void *)("talking") == 1) ? (((const char *) ("talking"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("talking" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "talking" , __len); __retval; })) : __strdup ("talking"))), count++), SWITCH_XML_NAMEM ); |
7090 | switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_TALKING) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((member)->flags & MFLAG_TALKING ) ? "true" : "false") && ((size_t)(const void *)((((member )->flags & MFLAG_TALKING) ? "true" : "false") + 1) - ( size_t)(const void *)(((member)->flags & MFLAG_TALKING ) ? "true" : "false") == 1) ? (((const char *) (((member)-> flags & MFLAG_TALKING) ? "true" : "false"))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((member)->flags & MFLAG_TALKING) ? "true" : "false" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((member )->flags & MFLAG_TALKING) ? "true" : "false", __len); __retval ; })) : __strdup (((member)->flags & MFLAG_TALKING) ? "true" : "false")))), SWITCH_XML_TXTM); |
7091 | |
7092 | x_tag = switch_xml_add_child_d(x_flags, "has_video", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("has_video") && ((size_t)(const void *)(("has_video") + 1) - (size_t)(const void *)("has_video" ) == 1) ? (((const char *) ("has_video"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "has_video") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "has_video", __len); __retval; })) : __strdup ("has_video") )), count++), SWITCH_XML_NAMEM); |
7093 | switch_xml_set_txt_d(x_tag, switch_channel_test_flag(switch_core_session_get_channel(member->session), CF_VIDEO) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (switch_channel_test_flag(switch_core_session_get_channel (member->session), CF_VIDEO) ? "true" : "false") && ((size_t)(const void *)((switch_channel_test_flag(switch_core_session_get_channel (member->session), CF_VIDEO) ? "true" : "false") + 1) - (size_t )(const void *)(switch_channel_test_flag(switch_core_session_get_channel (member->session), CF_VIDEO) ? "true" : "false") == 1) ? ( ((const char *) (switch_channel_test_flag(switch_core_session_get_channel (member->session), CF_VIDEO) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (switch_channel_test_flag(switch_core_session_get_channel (member->session), CF_VIDEO) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, switch_channel_test_flag (switch_core_session_get_channel(member->session), CF_VIDEO ) ? "true" : "false", __len); __retval; })) : __strdup (switch_channel_test_flag (switch_core_session_get_channel(member->session), CF_VIDEO ) ? "true" : "false")))), SWITCH_XML_TXTM); |
7094 | |
7095 | x_tag = switch_xml_add_child_d(x_flags, "video_bridge", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("video_bridge") && ((size_t)( const void *)(("video_bridge") + 1) - (size_t)(const void *)( "video_bridge") == 1) ? (((const char *) ("video_bridge"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("video_bridge") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "video_bridge", __len); __retval; })) : __strdup ("video_bridge"))), count++), SWITCH_XML_NAMEM); |
7096 | switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_VIDEO_BRIDGE) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((member)->flags & MFLAG_VIDEO_BRIDGE ) ? "true" : "false") && ((size_t)(const void *)((((member )->flags & MFLAG_VIDEO_BRIDGE) ? "true" : "false") + 1 ) - (size_t)(const void *)(((member)->flags & MFLAG_VIDEO_BRIDGE ) ? "true" : "false") == 1) ? (((const char *) (((member)-> flags & MFLAG_VIDEO_BRIDGE) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((member)->flags & MFLAG_VIDEO_BRIDGE) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , ((member)->flags & MFLAG_VIDEO_BRIDGE) ? "true" : "false" , __len); __retval; })) : __strdup (((member)->flags & MFLAG_VIDEO_BRIDGE) ? "true" : "false")))), SWITCH_XML_TXTM); |
7097 | |
7098 | x_tag = switch_xml_add_child_d(x_flags, "has_floor", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("has_floor") && ((size_t)(const void *)(("has_floor") + 1) - (size_t)(const void *)("has_floor" ) == 1) ? (((const char *) ("has_floor"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "has_floor") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "has_floor", __len); __retval; })) : __strdup ("has_floor") )), count++), SWITCH_XML_NAMEM); |
7099 | switch_xml_set_txt_d(x_tag, (member == member->conference->floor_holder) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p ((member == member->conference->floor_holder ) ? "true" : "false") && ((size_t)(const void *)(((member == member->conference->floor_holder) ? "true" : "false" ) + 1) - (size_t)(const void *)((member == member->conference ->floor_holder) ? "true" : "false") == 1) ? (((const char * ) ((member == member->conference->floor_holder) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen ((member == member->conference ->floor_holder) ? "true" : "false") + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (member == member->conference-> floor_holder) ? "true" : "false", __len); __retval; })) : __strdup ((member == member->conference->floor_holder) ? "true" : "false")))), SWITCH_XML_TXTM); |
7100 | |
7101 | x_tag = switch_xml_add_child_d(x_flags, "is_moderator", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("is_moderator") && ((size_t)( const void *)(("is_moderator") + 1) - (size_t)(const void *)( "is_moderator") == 1) ? (((const char *) ("is_moderator"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("is_moderator") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "is_moderator", __len); __retval; })) : __strdup ("is_moderator"))), count++), SWITCH_XML_NAMEM); |
7102 | switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_MOD) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((member)->flags & MFLAG_MOD) ? "true" : "false") && ((size_t)(const void *)((((member)-> flags & MFLAG_MOD) ? "true" : "false") + 1) - (size_t)(const void *)(((member)->flags & MFLAG_MOD) ? "true" : "false" ) == 1) ? (((const char *) (((member)->flags & MFLAG_MOD ) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((member)->flags & MFLAG_MOD) ? "true" : "false") + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((member)->flags & MFLAG_MOD ) ? "true" : "false", __len); __retval; })) : __strdup (((member )->flags & MFLAG_MOD) ? "true" : "false")))), SWITCH_XML_TXTM ); |
7103 | |
7104 | x_tag = switch_xml_add_child_d(x_flags, "end_conference", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("end_conference") && ((size_t )(const void *)(("end_conference") + 1) - (size_t)(const void *)("end_conference") == 1) ? (((const char *) ("end_conference" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("end_conference") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "end_conference", __len); __retval ; })) : __strdup ("end_conference"))), count++), SWITCH_XML_NAMEM ); |
7105 | switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_ENDCONF) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((member)->flags & MFLAG_ENDCONF ) ? "true" : "false") && ((size_t)(const void *)((((member )->flags & MFLAG_ENDCONF) ? "true" : "false") + 1) - ( size_t)(const void *)(((member)->flags & MFLAG_ENDCONF ) ? "true" : "false") == 1) ? (((const char *) (((member)-> flags & MFLAG_ENDCONF) ? "true" : "false"))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((member)->flags & MFLAG_ENDCONF) ? "true" : "false" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((member )->flags & MFLAG_ENDCONF) ? "true" : "false", __len); __retval ; })) : __strdup (((member)->flags & MFLAG_ENDCONF) ? "true" : "false")))), SWITCH_XML_TXTM); |
7106 | |
7107 | x_tag = switch_xml_add_child_d(x_flags, "is_ghost", count++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("is_ghost") && ((size_t)(const void *)(("is_ghost") + 1) - (size_t)(const void *)("is_ghost" ) == 1) ? (((const char *) ("is_ghost"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "is_ghost") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "is_ghost", __len); __retval; })) : __strdup ("is_ghost"))) , count++), SWITCH_XML_NAMEM); |
7108 | switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_GHOST) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((member)->flags & MFLAG_GHOST) ? "true" : "false") && ((size_t)(const void *)((((member )->flags & MFLAG_GHOST) ? "true" : "false") + 1) - (size_t )(const void *)(((member)->flags & MFLAG_GHOST) ? "true" : "false") == 1) ? (((const char *) (((member)->flags & MFLAG_GHOST) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((member )->flags & MFLAG_GHOST) ? "true" : "false") + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, ((member)->flags & MFLAG_GHOST) ? "true" : "false", __len); __retval; })) : __strdup (((member)->flags & MFLAG_GHOST) ? "true" : "false")) )), SWITCH_XML_TXTM); |
7109 | |
7110 | switch_snprintf(tmp, sizeof(tmp), "%d", member->volume_out_level); |
7111 | add_x_tag(x_member, "output-volume", tmp, toff++); |
7112 | |
7113 | switch_snprintf(tmp, sizeof(tmp), "%d", member->agc_volume_in_level ? member->agc_volume_in_level : member->volume_in_level); |
7114 | add_x_tag(x_member, "input-volume", tmp, toff++); |
7115 | |
7116 | switch_snprintf(tmp, sizeof(tmp), "%d", member->agc_volume_in_level); |
7117 | add_x_tag(x_member, "auto-adjusted-input-volume", tmp, toff++); |
7118 | |
7119 | } |
7120 | |
7121 | switch_mutex_unlock(conference->member_mutex); |
7122 | } |
7123 | static switch_status_t conf_api_sub_xml_list(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7124 | { |
7125 | int count = 0; |
7126 | switch_hash_index_t *hi; |
7127 | void *val; |
7128 | switch_xml_t x_conference, x_conferences; |
7129 | int off = 0; |
7130 | char *ebuf; |
7131 | |
7132 | x_conferences = switch_xml_new("conferences"); |
7133 | switch_assert(x_conferences)((x_conferences) ? (void) (0) : __assert_fail ("x_conferences" , "mod_conference.c", 7133, __PRETTY_FUNCTION__)); |
7134 | |
7135 | if (conference == NULL((void*)0)) { |
7136 | switch_mutex_lock(globals.hash_mutex); |
7137 | for (hi = switch_core_hash_first(globals.conference_hash)switch_core_hash_first_iter(globals.conference_hash, ((void*) 0)); hi; hi = switch_core_hash_next(&hi)) { |
7138 | switch_core_hash_this(hi, NULL((void*)0), NULL((void*)0), &val); |
7139 | conference = (conference_obj_t *) val; |
7140 | |
7141 | x_conference = switch_xml_add_child_d(x_conferences, "conference", off++)switch_xml_set_flag(switch_xml_add_child(x_conferences, (__extension__ (__builtin_constant_p ("conference") && ((size_t)(const void *)(("conference") + 1) - (size_t)(const void *)("conference" ) == 1) ? (((const char *) ("conference"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "conference", __len); __retval; })) : __strdup ("conference" ))), off++), SWITCH_XML_NAMEM); |
7142 | switch_assert(conference)((conference) ? (void) (0) : __assert_fail ("conference", "mod_conference.c" , 7142, __PRETTY_FUNCTION__)); |
7143 | |
7144 | count++; |
7145 | conference_xlist(conference, x_conference, off); |
7146 | |
7147 | } |
7148 | switch_mutex_unlock(globals.hash_mutex); |
7149 | } else { |
7150 | x_conference = switch_xml_add_child_d(x_conferences, "conference", off++)switch_xml_set_flag(switch_xml_add_child(x_conferences, (__extension__ (__builtin_constant_p ("conference") && ((size_t)(const void *)(("conference") + 1) - (size_t)(const void *)("conference" ) == 1) ? (((const char *) ("conference"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "conference", __len); __retval; })) : __strdup ("conference" ))), off++), SWITCH_XML_NAMEM); |
7151 | switch_assert(conference)((conference) ? (void) (0) : __assert_fail ("conference", "mod_conference.c" , 7151, __PRETTY_FUNCTION__)); |
7152 | count++; |
7153 | conference_xlist(conference, x_conference, off); |
7154 | } |
7155 | |
7156 | |
7157 | ebuf = switch_xml_toxml(x_conferences, SWITCH_TRUE); |
7158 | |
7159 | stream->write_function(stream, "%s", ebuf); |
7160 | |
7161 | switch_xml_free(x_conferences); |
7162 | free(ebuf); |
7163 | |
7164 | return SWITCH_STATUS_SUCCESS; |
7165 | } |
7166 | |
7167 | static void switch_fnode_toggle_pause(conference_file_node_t *fnode, switch_stream_handle_t *stream) |
7168 | { |
7169 | if (fnode) { |
7170 | if (switch_test_flag(fnode, NFLAG_PAUSE)((fnode)->flags & NFLAG_PAUSE)) { |
7171 | stream->write_function(stream, "+OK Resume\n"); |
7172 | switch_clear_flag(fnode, NFLAG_PAUSE)(fnode)->flags &= ~(NFLAG_PAUSE); |
7173 | } else { |
7174 | stream->write_function(stream, "+OK Pause\n"); |
7175 | switch_set_flag(fnode, NFLAG_PAUSE)(fnode)->flags |= (NFLAG_PAUSE); |
7176 | } |
7177 | } |
7178 | } |
7179 | |
7180 | static switch_status_t conf_api_sub_pause_play(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7181 | { |
7182 | if (argc == 2) { |
7183 | switch_mutex_lock(conference->mutex); |
7184 | switch_fnode_toggle_pause(conference->fnode, stream); |
7185 | switch_mutex_unlock(conference->mutex); |
7186 | |
7187 | return SWITCH_STATUS_SUCCESS; |
7188 | } |
7189 | |
7190 | if (argc == 3) { |
7191 | uint32_t id = atoi(argv[2]); |
7192 | conference_member_t *member; |
7193 | |
7194 | if ((member = conference_member_get(conference, id))) { |
7195 | switch_mutex_lock(member->fnode_mutex); |
7196 | switch_fnode_toggle_pause(member->fnode, stream); |
7197 | switch_mutex_unlock(member->fnode_mutex); |
7198 | switch_thread_rwlock_unlock(member->rwlock); |
7199 | return SWITCH_STATUS_SUCCESS; |
7200 | } else { |
7201 | stream->write_function(stream, "Member: %u not found.\n", id); |
7202 | } |
7203 | } |
7204 | |
7205 | return SWITCH_STATUS_GENERR; |
7206 | } |
7207 | |
7208 | static void switch_fnode_seek(conference_file_node_t *fnode, switch_stream_handle_t *stream, char *arg) |
7209 | { |
7210 | if (fnode && fnode->type == NODE_TYPE_FILE) { |
7211 | unsigned int samps = 0; |
7212 | unsigned int pos = 0; |
7213 | |
7214 | if (*arg == '+' || *arg == '-') { |
7215 | int step; |
7216 | int32_t target; |
7217 | if (!(step = atoi(arg))) { |
7218 | step = 1000; |
7219 | } |
7220 | |
7221 | samps = step * (fnode->fh.native_rate / 1000); |
7222 | target = (int32_t)fnode->fh.pos + samps; |
7223 | |
7224 | if (target < 0) { |
7225 | target = 0; |
7226 | } |
7227 | |
7228 | stream->write_function(stream, "+OK seek to position %d\n", target); |
7229 | switch_core_file_seek(&fnode->fh, &pos, target, SEEK_SET0); |
7230 | |
7231 | } else { |
7232 | samps = switch_atoui(arg) * (fnode->fh.native_rate / 1000); |
7233 | stream->write_function(stream, "+OK seek to position %d\n", samps); |
7234 | switch_core_file_seek(&fnode->fh, &pos, samps, SEEK_SET0); |
7235 | } |
7236 | } |
7237 | } |
7238 | |
7239 | static switch_status_t conf_api_sub_file_seek(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7240 | { |
7241 | if (argc == 3) { |
7242 | switch_mutex_lock(conference->mutex); |
7243 | switch_fnode_seek(conference->fnode, stream, argv[2]); |
7244 | switch_mutex_unlock(conference->mutex); |
7245 | |
7246 | return SWITCH_STATUS_SUCCESS; |
7247 | } |
7248 | |
7249 | if (argc == 4) { |
7250 | uint32_t id = atoi(argv[3]); |
7251 | conference_member_t *member = conference_member_get(conference, id); |
7252 | if (member == NULL((void*)0)) { |
7253 | stream->write_function(stream, "Member: %u not found.\n", id); |
7254 | return SWITCH_STATUS_GENERR; |
7255 | } |
7256 | |
7257 | switch_mutex_lock(member->fnode_mutex); |
7258 | switch_fnode_seek(member->fnode, stream, argv[2]); |
7259 | switch_mutex_unlock(member->fnode_mutex); |
7260 | switch_thread_rwlock_unlock(member->rwlock); |
7261 | return SWITCH_STATUS_SUCCESS; |
7262 | } |
7263 | |
7264 | return SWITCH_STATUS_GENERR; |
7265 | } |
7266 | |
7267 | static switch_status_t conf_api_sub_play(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7268 | { |
7269 | int ret_status = SWITCH_STATUS_GENERR; |
7270 | switch_event_t *event; |
7271 | uint8_t async = 0; |
7272 | |
7273 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7273, __PRETTY_FUNCTION__)); |
7274 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7274, __PRETTY_FUNCTION__)); |
7275 | |
7276 | if ((argc == 4 && !strcasecmp(argv[3], "async")) || (argc == 5 && !strcasecmp(argv[4], "async"))) { |
7277 | argc--; |
7278 | async++; |
7279 | } |
7280 | |
7281 | if (argc == 3) { |
7282 | if (conference_play_file(conference, argv[2], 0, NULL((void*)0), async) == SWITCH_STATUS_SUCCESS) { |
7283 | stream->write_function(stream, "(play) Playing file %s\n", argv[2]); |
7284 | if (test_eflag(conference, EFLAG_PLAY_FILE)((conference)->eflags & EFLAG_PLAY_FILE) && |
7285 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7285, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7286 | conference_add_event_data(conference, event); |
7287 | |
7288 | if (conference->fnode && conference->fnode->fh.params) { |
7289 | switch_event_merge(event, conference->fnode->fh.params); |
7290 | } |
7291 | |
7292 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file"); |
7293 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", argv[2]); |
7294 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", async ? "true" : "false"); |
7295 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7295, &event, ((void*)0)); |
7296 | } |
7297 | } else { |
7298 | stream->write_function(stream, "(play) File: %s not found.\n", argv[2] ? argv[2] : "(unspecified)"); |
7299 | } |
7300 | ret_status = SWITCH_STATUS_SUCCESS; |
7301 | } else if (argc >= 4) { |
7302 | uint32_t id = atoi(argv[3]); |
7303 | conference_member_t *member; |
7304 | switch_bool_t mux = SWITCH_TRUE; |
7305 | |
7306 | if (argc > 4 && !strcasecmp(argv[4], "nomux")) { |
7307 | mux = SWITCH_FALSE; |
7308 | } |
7309 | |
7310 | if ((member = conference_member_get(conference, id))) { |
7311 | if (conference_member_play_file(member, argv[2], 0, mux) == SWITCH_STATUS_SUCCESS) { |
7312 | stream->write_function(stream, "(play) Playing file %s to member %u\n", argv[2], id); |
7313 | if (test_eflag(conference, EFLAG_PLAY_FILE_MEMBER)((conference)->eflags & EFLAG_PLAY_FILE_MEMBER) && |
7314 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7314, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7315 | conference_add_event_member_data(member, event); |
7316 | |
7317 | if (member->fnode->fh.params) { |
7318 | switch_event_merge(event, member->fnode->fh.params); |
7319 | } |
7320 | |
7321 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member"); |
7322 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", argv[2]); |
7323 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7323, &event, ((void*)0)); |
7324 | } |
7325 | } else { |
7326 | stream->write_function(stream, "(play) File: %s not found.\n", argv[2] ? argv[2] : "(unspecified)"); |
7327 | } |
7328 | switch_thread_rwlock_unlock(member->rwlock); |
7329 | ret_status = SWITCH_STATUS_SUCCESS; |
7330 | } else { |
7331 | stream->write_function(stream, "Member: %u not found.\n", id); |
7332 | } |
7333 | } |
7334 | |
7335 | return ret_status; |
7336 | } |
7337 | |
7338 | static switch_status_t conf_api_sub_say(conference_obj_t *conference, switch_stream_handle_t *stream, const char *text) |
7339 | { |
7340 | switch_event_t *event; |
7341 | |
7342 | if (zstr(text)_zstr(text)) { |
7343 | stream->write_function(stream, "(say) Error! No text.\n"); |
7344 | return SWITCH_STATUS_GENERR; |
7345 | } |
7346 | |
7347 | if (conference_say(conference, text, 0) != SWITCH_STATUS_SUCCESS) { |
7348 | stream->write_function(stream, "(say) Error!\n"); |
7349 | return SWITCH_STATUS_GENERR; |
7350 | } |
7351 | |
7352 | stream->write_function(stream, "(say) OK\n"); |
7353 | if (test_eflag(conference, EFLAG_SPEAK_TEXT)((conference)->eflags & EFLAG_SPEAK_TEXT) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7353, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7354 | conference_add_event_data(conference, event); |
7355 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "speak-text"); |
7356 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Text", text); |
7357 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7357, &event, ((void*)0)); |
7358 | } |
7359 | return SWITCH_STATUS_SUCCESS; |
7360 | } |
7361 | |
7362 | static switch_status_t conf_api_sub_saymember(conference_obj_t *conference, switch_stream_handle_t *stream, const char *text) |
7363 | { |
7364 | int ret_status = SWITCH_STATUS_GENERR; |
7365 | char *expanded = NULL((void*)0); |
7366 | char *start_text = NULL((void*)0); |
7367 | char *workspace = NULL((void*)0); |
7368 | uint32_t id = 0; |
7369 | conference_member_t *member = NULL((void*)0); |
7370 | switch_event_t *event; |
7371 | |
7372 | if (zstr(text)_zstr(text)) { |
7373 | stream->write_function(stream, "(saymember) No Text!\n"); |
7374 | goto done; |
7375 | } |
7376 | |
7377 | if (!(workspace = strdup(text)(__extension__ (__builtin_constant_p (text) && ((size_t )(const void *)((text) + 1) - (size_t)(const void *)(text) == 1) ? (((const char *) (text))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen (text) + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, text, __len) ; __retval; })) : __strdup (text))))) { |
7378 | stream->write_function(stream, "(saymember) Memory Error!\n"); |
7379 | goto done; |
7380 | } |
7381 | |
7382 | if ((start_text = strchr(workspace, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p (workspace) && (' ') == '\0' ? (char *) __rawmemchr ( workspace, ' ') : __builtin_strchr (workspace, ' '))))) { |
7383 | *start_text++ = '\0'; |
7384 | text = start_text; |
7385 | } |
7386 | |
7387 | id = atoi(workspace); |
7388 | |
7389 | if (!id || zstr(text)_zstr(text)) { |
7390 | stream->write_function(stream, "(saymember) No Text!\n"); |
7391 | goto done; |
7392 | } |
7393 | |
7394 | if (!(member = conference_member_get(conference, id))) { |
7395 | stream->write_function(stream, "(saymember) Unknown Member %u!\n", id); |
7396 | goto done; |
7397 | } |
7398 | |
7399 | if ((expanded = switch_channel_expand_variables(switch_core_session_get_channel(member->session), (char *) text)switch_channel_expand_variables_check(switch_core_session_get_channel (member->session), (char *) text, ((void*)0), ((void*)0), 0 )) != text) { |
7400 | text = expanded; |
7401 | } else { |
7402 | expanded = NULL((void*)0); |
7403 | } |
7404 | |
7405 | if (!text || conference_member_say(member, (char *) text, 0) != SWITCH_STATUS_SUCCESS) { |
7406 | stream->write_function(stream, "(saymember) Error!\n"); |
7407 | goto done; |
7408 | } |
7409 | |
7410 | stream->write_function(stream, "(saymember) OK\n"); |
7411 | if (test_eflag(member->conference, EFLAG_SPEAK_TEXT_MEMBER)((member->conference)->eflags & EFLAG_SPEAK_TEXT_MEMBER ) && |
7412 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7412, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7413 | conference_add_event_member_data(member, event); |
7414 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "speak-text-member"); |
7415 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Text", text); |
7416 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7416, &event, ((void*)0)); |
7417 | } |
7418 | ret_status = SWITCH_STATUS_SUCCESS; |
7419 | |
7420 | done: |
7421 | |
7422 | if (member) { |
7423 | switch_thread_rwlock_unlock(member->rwlock); |
7424 | } |
7425 | |
7426 | switch_safe_free(workspace)if (workspace) {free(workspace);workspace=((void*)0);}; |
7427 | switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);}; |
7428 | return ret_status; |
7429 | } |
7430 | |
7431 | static switch_status_t conf_api_sub_stop(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7432 | { |
7433 | uint8_t current = 0, all = 0, async = 0; |
7434 | |
7435 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7435, __PRETTY_FUNCTION__)); |
7436 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7436, __PRETTY_FUNCTION__)); |
7437 | |
7438 | if (argc > 2) { |
7439 | current = strcasecmp(argv[2], "current") ? 0 : 1; |
7440 | all = strcasecmp(argv[2], "all") ? 0 : 1; |
7441 | async = strcasecmp(argv[2], "async") ? 0 : 1; |
7442 | } else { |
7443 | all = 1; |
7444 | } |
7445 | |
7446 | if (!(current || all || async)) |
7447 | return SWITCH_STATUS_GENERR; |
7448 | |
7449 | if (argc == 4) { |
7450 | uint32_t id = atoi(argv[3]); |
7451 | conference_member_t *member; |
7452 | |
7453 | if ((member = conference_member_get(conference, id))) { |
7454 | uint32_t stopped = conference_member_stop_file(member, async ? FILE_STOP_ASYNC : current ? FILE_STOP_CURRENT : FILE_STOP_ALL); |
7455 | stream->write_function(stream, "Stopped %u files.\n", stopped); |
7456 | switch_thread_rwlock_unlock(member->rwlock); |
7457 | } else { |
7458 | stream->write_function(stream, "Member: %u not found.\n", id); |
7459 | } |
7460 | } else { |
7461 | uint32_t stopped = conference_stop_file(conference, async ? FILE_STOP_ASYNC : current ? FILE_STOP_CURRENT : FILE_STOP_ALL); |
7462 | stream->write_function(stream, "Stopped %u files.\n", stopped); |
7463 | } |
7464 | return SWITCH_STATUS_SUCCESS; |
7465 | } |
7466 | |
7467 | static switch_status_t conf_api_sub_relate(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7468 | { |
7469 | uint8_t nospeak = 0, nohear = 0, clear = 0; |
7470 | |
7471 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7471, __PRETTY_FUNCTION__)); |
7472 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7472, __PRETTY_FUNCTION__)); |
7473 | |
7474 | if (argc <= 4) |
7475 | return SWITCH_STATUS_GENERR; |
7476 | |
7477 | nospeak = strstr(argv[4], "nospeak") ? 1 : 0; |
7478 | nohear = strstr(argv[4], "nohear") ? 1 : 0; |
7479 | |
7480 | if (!strcasecmp(argv[4], "clear")) { |
7481 | clear = 1; |
7482 | } |
7483 | |
7484 | if (!(clear || nospeak || nohear)) { |
7485 | return SWITCH_STATUS_GENERR; |
7486 | } |
7487 | |
7488 | if (clear) { |
7489 | conference_member_t *member = NULL((void*)0); |
7490 | uint32_t id = atoi(argv[2]); |
7491 | uint32_t oid = atoi(argv[3]); |
7492 | |
7493 | if ((member = conference_member_get(conference, id))) { |
7494 | member_del_relationship(member, oid); |
7495 | stream->write_function(stream, "relationship %u->%u cleared.\n", id, oid); |
7496 | switch_thread_rwlock_unlock(member->rwlock); |
7497 | } else { |
7498 | stream->write_function(stream, "relationship %u->%u not found.\n", id, oid); |
7499 | } |
7500 | return SWITCH_STATUS_SUCCESS; |
7501 | } |
7502 | |
7503 | if (nospeak || nohear) { |
7504 | conference_member_t *member = NULL((void*)0), *other_member = NULL((void*)0); |
7505 | uint32_t id = atoi(argv[2]); |
7506 | uint32_t oid = atoi(argv[3]); |
7507 | |
7508 | if ((member = conference_member_get(conference, id))) { |
7509 | other_member = conference_member_get(conference, oid); |
7510 | } |
7511 | |
7512 | if (member && other_member) { |
7513 | conference_relationship_t *rel = NULL((void*)0); |
7514 | |
7515 | if ((rel = member_get_relationship(member, other_member))) { |
7516 | rel->flags = 0; |
7517 | } else { |
7518 | rel = member_add_relationship(member, oid); |
7519 | } |
7520 | |
7521 | if (rel) { |
7522 | switch_set_flag(rel, RFLAG_CAN_SPEAK | RFLAG_CAN_HEAR)(rel)->flags |= (RFLAG_CAN_SPEAK | RFLAG_CAN_HEAR); |
7523 | if (nospeak) { |
7524 | switch_clear_flag(rel, RFLAG_CAN_SPEAK)(rel)->flags &= ~(RFLAG_CAN_SPEAK); |
7525 | switch_clear_flag_locked(member, MFLAG_TALKING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_TALKING); switch_mutex_unlock(member->flag_mutex) ;; |
7526 | } |
7527 | if (nohear) { |
7528 | switch_clear_flag(rel, RFLAG_CAN_HEAR)(rel)->flags &= ~(RFLAG_CAN_HEAR); |
7529 | } |
7530 | stream->write_function(stream, "ok %u->%u set\n", id, oid); |
7531 | } else { |
7532 | stream->write_function(stream, "error!\n"); |
7533 | } |
7534 | } else { |
7535 | stream->write_function(stream, "relationship %u->%u not found.\n", id, oid); |
7536 | } |
7537 | |
7538 | if (member) { |
7539 | switch_thread_rwlock_unlock(member->rwlock); |
7540 | } |
7541 | |
7542 | if (other_member) { |
7543 | switch_thread_rwlock_unlock(other_member->rwlock); |
7544 | } |
7545 | } |
7546 | |
7547 | return SWITCH_STATUS_SUCCESS; |
7548 | } |
7549 | |
7550 | static switch_status_t conf_api_sub_lock(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7551 | { |
7552 | switch_event_t *event; |
7553 | |
7554 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7554, __PRETTY_FUNCTION__)); |
7555 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7555, __PRETTY_FUNCTION__)); |
7556 | |
7557 | if (conference->is_locked_sound) { |
7558 | conference_play_file(conference, conference->is_locked_sound, CONF_DEFAULT_LEADIN20, NULL((void*)0), 0); |
7559 | } |
7560 | |
7561 | switch_set_flag_locked(conference, CFLAG_LOCKED)((conference->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conference->flag_mutex != ((void*)0)", "mod_conference.c" , 7561, __PRETTY_FUNCTION__));switch_mutex_lock(conference-> flag_mutex);(conference)->flags |= (CFLAG_LOCKED);switch_mutex_unlock (conference->flag_mutex);; |
7562 | stream->write_function(stream, "OK %s locked\n", argv[0]); |
7563 | if (test_eflag(conference, EFLAG_LOCK)((conference)->eflags & EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7563, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7564 | conference_add_event_data(conference, event); |
7565 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "lock"); |
7566 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7566, &event, ((void*)0)); |
7567 | } |
7568 | |
7569 | return 0; |
7570 | } |
7571 | |
7572 | static switch_status_t conf_api_sub_unlock(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7573 | { |
7574 | switch_event_t *event; |
7575 | |
7576 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7576, __PRETTY_FUNCTION__)); |
7577 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7577, __PRETTY_FUNCTION__)); |
7578 | |
7579 | if (conference->is_unlocked_sound) { |
7580 | conference_play_file(conference, conference->is_unlocked_sound, CONF_DEFAULT_LEADIN20, NULL((void*)0), 0); |
7581 | } |
7582 | |
7583 | switch_clear_flag_locked(conference, CFLAG_LOCKED)switch_mutex_lock(conference->flag_mutex); (conference)-> flags &= ~(CFLAG_LOCKED); switch_mutex_unlock(conference-> flag_mutex);; |
7584 | stream->write_function(stream, "OK %s unlocked\n", argv[0]); |
7585 | if (test_eflag(conference, EFLAG_UNLOCK)((conference)->eflags & EFLAG_UNLOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7585, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7586 | conference_add_event_data(conference, event); |
7587 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "unlock"); |
7588 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7588, &event, ((void*)0)); |
7589 | } |
7590 | |
7591 | return 0; |
7592 | } |
7593 | |
7594 | static switch_status_t conf_api_sub_exit_sound(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7595 | { |
7596 | switch_event_t *event; |
7597 | |
7598 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7598, __PRETTY_FUNCTION__)); |
7599 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7599, __PRETTY_FUNCTION__)); |
7600 | |
7601 | if (argc <= 2) { |
7602 | stream->write_function(stream, "Not enough args\n"); |
7603 | return SWITCH_STATUS_GENERR; |
7604 | } |
7605 | |
7606 | if ( !strcasecmp(argv[2], "on") ) { |
7607 | switch_set_flag_locked(conference, CFLAG_EXIT_SOUND)((conference->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conference->flag_mutex != ((void*)0)", "mod_conference.c" , 7607, __PRETTY_FUNCTION__));switch_mutex_lock(conference-> flag_mutex);(conference)->flags |= (CFLAG_EXIT_SOUND);switch_mutex_unlock (conference->flag_mutex);; |
7608 | stream->write_function(stream, "OK %s exit sounds on (%s)\n", argv[0], conference->exit_sound); |
7609 | if (test_eflag(conference, EFLAG_LOCK)((conference)->eflags & EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7609, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7610 | conference_add_event_data(conference, event); |
7611 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "exit-sounds-on"); |
7612 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7612, &event, ((void*)0)); |
7613 | } |
7614 | } else if ( !strcasecmp(argv[2], "off") || !strcasecmp(argv[2], "none") ) { |
7615 | switch_clear_flag_locked(conference, CFLAG_EXIT_SOUND)switch_mutex_lock(conference->flag_mutex); (conference)-> flags &= ~(CFLAG_EXIT_SOUND); switch_mutex_unlock(conference ->flag_mutex);; |
7616 | stream->write_function(stream, "OK %s exit sounds off (%s)\n", argv[0], conference->exit_sound); |
7617 | if (test_eflag(conference, EFLAG_LOCK)((conference)->eflags & EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7617, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7618 | conference_add_event_data(conference, event); |
7619 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "exit-sounds-off"); |
7620 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7620, &event, ((void*)0)); |
7621 | } |
7622 | } else if ( !strcasecmp(argv[2], "file") ) { |
7623 | if (! argv[3]) { |
7624 | stream->write_function(stream, "No filename specified\n"); |
7625 | } else { |
7626 | /* TODO: if possible, verify file exists before setting it */ |
7627 | stream->write_function(stream,"Old exit sound: [%s]\n", conference->exit_sound); |
7628 | conference->exit_sound = switch_core_strdup(conference->pool, argv[3])switch_core_perform_strdup(conference->pool, argv[3], "mod_conference.c" , (const char *)__func__, 7628); |
7629 | stream->write_function(stream, "OK %s exit sound file set to %s\n", argv[0], conference->exit_sound); |
7630 | if (test_eflag(conference, EFLAG_LOCK)((conference)->eflags & EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7630, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7631 | conference_add_event_data(conference, event); |
7632 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "exit-sound-file-changed"); |
7633 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7633, &event, ((void*)0)); |
7634 | } |
7635 | } |
7636 | } else { |
7637 | stream->write_function(stream, "Bad args\n"); |
7638 | return SWITCH_STATUS_GENERR; |
7639 | } |
7640 | |
7641 | return 0; |
7642 | } |
7643 | |
7644 | |
7645 | static switch_status_t conf_api_sub_enter_sound(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7646 | { |
7647 | switch_event_t *event; |
7648 | |
7649 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7649, __PRETTY_FUNCTION__)); |
7650 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7650, __PRETTY_FUNCTION__)); |
7651 | |
7652 | if (argc <= 2) { |
7653 | stream->write_function(stream, "Not enough args\n"); |
7654 | return SWITCH_STATUS_GENERR; |
7655 | } |
7656 | |
7657 | if ( !strcasecmp(argv[2], "on") ) { |
7658 | switch_set_flag_locked(conference, CFLAG_ENTER_SOUND)((conference->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conference->flag_mutex != ((void*)0)", "mod_conference.c" , 7658, __PRETTY_FUNCTION__));switch_mutex_lock(conference-> flag_mutex);(conference)->flags |= (CFLAG_ENTER_SOUND);switch_mutex_unlock (conference->flag_mutex);; |
7659 | stream->write_function(stream, "OK %s enter sounds on (%s)\n", argv[0], conference->enter_sound); |
7660 | if (test_eflag(conference, EFLAG_LOCK)((conference)->eflags & EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7660, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7661 | conference_add_event_data(conference, event); |
7662 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "enter-sounds-on"); |
7663 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7663, &event, ((void*)0)); |
7664 | } |
7665 | } else if ( !strcasecmp(argv[2], "off") || !strcasecmp(argv[2], "none") ) { |
7666 | switch_clear_flag_locked(conference, CFLAG_ENTER_SOUND)switch_mutex_lock(conference->flag_mutex); (conference)-> flags &= ~(CFLAG_ENTER_SOUND); switch_mutex_unlock(conference ->flag_mutex);; |
7667 | stream->write_function(stream, "OK %s enter sounds off (%s)\n", argv[0], conference->enter_sound); |
7668 | if (test_eflag(conference, EFLAG_LOCK)((conference)->eflags & EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7668, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7669 | conference_add_event_data(conference, event); |
7670 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "enter-sounds-off"); |
7671 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7671, &event, ((void*)0)); |
7672 | } |
7673 | } else if ( !strcasecmp(argv[2], "file") ) { |
7674 | if (! argv[3]) { |
7675 | stream->write_function(stream, "No filename specified\n"); |
7676 | } else { |
7677 | /* TODO: verify file exists before setting it */ |
7678 | conference->enter_sound = switch_core_strdup(conference->pool, argv[3])switch_core_perform_strdup(conference->pool, argv[3], "mod_conference.c" , (const char *)__func__, 7678); |
7679 | stream->write_function(stream, "OK %s enter sound file set to %s\n", argv[0], conference->enter_sound); |
7680 | if (test_eflag(conference, EFLAG_LOCK)((conference)->eflags & EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7680, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7681 | conference_add_event_data(conference, event); |
7682 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "enter-sound-file-changed"); |
7683 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7683, &event, ((void*)0)); |
7684 | } |
7685 | } |
7686 | } else { |
7687 | stream->write_function(stream, "Bad args\n"); |
7688 | return SWITCH_STATUS_GENERR; |
7689 | } |
7690 | |
7691 | return 0; |
7692 | } |
7693 | |
7694 | |
7695 | static switch_status_t conf_api_sub_dial(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7696 | { |
7697 | switch_call_cause_t cause; |
7698 | |
7699 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7699, __PRETTY_FUNCTION__)); |
7700 | |
7701 | if (argc <= 2) { |
7702 | stream->write_function(stream, "Bad Args\n"); |
7703 | return SWITCH_STATUS_GENERR; |
7704 | } |
7705 | |
7706 | if (conference) { |
7707 | conference_outcall(conference, NULL((void*)0), NULL((void*)0), argv[2], 60, NULL((void*)0), argv[4], argv[3], NULL((void*)0), &cause, NULL((void*)0), NULL((void*)0)); |
7708 | } else { |
7709 | conference_outcall(NULL((void*)0), argv[0], NULL((void*)0), argv[2], 60, NULL((void*)0), argv[4], argv[3], NULL((void*)0), &cause, NULL((void*)0), NULL((void*)0)); |
7710 | } |
7711 | stream->write_function(stream, "Call Requested: result: [%s]\n", switch_channel_cause2str(cause)); |
7712 | |
7713 | return SWITCH_STATUS_SUCCESS; |
7714 | } |
7715 | |
7716 | static switch_status_t conf_api_sub_bgdial(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7717 | { |
7718 | switch_uuid_t uuid; |
7719 | char uuid_str[SWITCH_UUID_FORMATTED_LENGTH256 + 1]; |
7720 | |
7721 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7721, __PRETTY_FUNCTION__)); |
7722 | |
7723 | if (argc <= 2) { |
7724 | stream->write_function(stream, "Bad Args\n"); |
7725 | return SWITCH_STATUS_GENERR; |
7726 | } |
7727 | |
7728 | switch_uuid_get(&uuid); |
7729 | switch_uuid_format(uuid_str, &uuid); |
7730 | |
7731 | if (conference) { |
7732 | conference_outcall_bg(conference, NULL((void*)0), NULL((void*)0), argv[2], 60, NULL((void*)0), argv[4], argv[3], uuid_str, NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
7733 | } else { |
7734 | conference_outcall_bg(NULL((void*)0), argv[0], NULL((void*)0), argv[2], 60, NULL((void*)0), argv[4], argv[3], uuid_str, NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
7735 | } |
7736 | |
7737 | stream->write_function(stream, "OK Job-UUID: %s\n", uuid_str); |
7738 | |
7739 | return SWITCH_STATUS_SUCCESS; |
7740 | } |
7741 | |
7742 | |
7743 | |
7744 | static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7745 | { |
7746 | switch_status_t ret_status = SWITCH_STATUS_SUCCESS; |
7747 | char *conf_name = NULL((void*)0), *profile_name; |
7748 | switch_event_t *params = NULL((void*)0); |
7749 | |
7750 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7750, __PRETTY_FUNCTION__)); |
7751 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7751, __PRETTY_FUNCTION__)); |
7752 | |
7753 | if (argc > 3 && !zstr(argv[2])_zstr(argv[2])) { |
7754 | int x; |
7755 | |
7756 | conf_name = strdup(argv[2])(__extension__ (__builtin_constant_p (argv[2]) && ((size_t )(const void *)((argv[2]) + 1) - (size_t)(const void *)(argv[ 2]) == 1) ? (((const char *) (argv[2]))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( argv[2]) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, argv[2] , __len); __retval; })) : __strdup (argv[2]))); |
7757 | |
7758 | if ((profile_name = strchr(conf_name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conf_name) && ('@') == '\0' ? (char *) __rawmemchr ( conf_name, '@') : __builtin_strchr (conf_name, '@'))))) { |
7759 | *profile_name++ = '\0'; |
7760 | } else { |
7761 | profile_name = "default"; |
7762 | } |
7763 | |
7764 | for (x = 3; x < argc; x++) { |
7765 | conference_member_t *member = NULL((void*)0); |
7766 | uint32_t id = atoi(argv[x]); |
7767 | switch_channel_t *channel; |
7768 | switch_event_t *event; |
7769 | char *xdest = NULL((void*)0); |
7770 | |
7771 | if (!id || !(member = conference_member_get(conference, id))) { |
7772 | stream->write_function(stream, "No Member %u in conference %s.\n", id, conference->name); |
7773 | continue; |
7774 | } |
7775 | |
7776 | channel = switch_core_session_get_channel(member->session); |
7777 | xdest = switch_core_session_sprintf(member->session, "conference:%s@%s", conf_name, profile_name); |
7778 | switch_ivr_session_transfer(member->session, xdest, "inline", NULL((void*)0)); |
7779 | |
7780 | switch_channel_set_variable(channel, "last_transfered_conference", conf_name)switch_channel_set_variable_var_check(channel, "last_transfered_conference" , conf_name, SWITCH_TRUE); |
7781 | |
7782 | stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]); |
7783 | |
7784 | /* tell them what happened */ |
7785 | if (test_eflag(conference, EFLAG_TRANSFER)((conference)->eflags & EFLAG_TRANSFER) && |
7786 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7786, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7787 | conference_add_event_member_data(member, event); |
7788 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-Conference-Name", conference->name); |
7789 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "New-Conference-Name", argv[3]); |
7790 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "transfer"); |
7791 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7791, &event, ((void*)0)); |
7792 | } |
7793 | |
7794 | switch_thread_rwlock_unlock(member->rwlock); |
7795 | } |
7796 | } else { |
7797 | ret_status = SWITCH_STATUS_GENERR; |
7798 | } |
7799 | |
7800 | if (params) { |
7801 | switch_event_destroy(¶ms); |
7802 | } |
7803 | |
7804 | switch_safe_free(conf_name)if (conf_name) {free(conf_name);conf_name=((void*)0);}; |
7805 | |
7806 | return ret_status; |
7807 | } |
7808 | |
7809 | static switch_status_t conf_api_sub_check_record(conference_obj_t *conference, switch_stream_handle_t *stream, int arc, char **argv) |
7810 | { |
7811 | conference_record_t *rec; |
7812 | int x = 0; |
7813 | |
7814 | switch_mutex_lock(conference->flag_mutex); |
7815 | for (rec = conference->rec_node_head; rec; rec = rec->next) { |
7816 | stream->write_function(stream, "Record file %s%s%s\n", rec->path, rec->autorec ? " " : "", rec->autorec ? "(Auto)" : ""); |
7817 | x++; |
7818 | } |
7819 | |
7820 | if (!x) { |
7821 | stream->write_function(stream, "Conference is not being recorded.\n"); |
7822 | } |
7823 | switch_mutex_unlock(conference->flag_mutex); |
7824 | |
7825 | return SWITCH_STATUS_SUCCESS; |
7826 | } |
7827 | |
7828 | static switch_status_t conf_api_sub_record(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7829 | { |
7830 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7830, __PRETTY_FUNCTION__)); |
7831 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7831, __PRETTY_FUNCTION__)); |
7832 | |
7833 | if (argc <= 2) { |
7834 | return SWITCH_STATUS_GENERR; |
7835 | } |
7836 | |
7837 | stream->write_function(stream, "Record file %s\n", argv[2]); |
7838 | conference->record_filename = switch_core_strdup(conference->pool, argv[2])switch_core_perform_strdup(conference->pool, argv[2], "mod_conference.c" , (const char *)__func__, 7838); |
7839 | conference->record_count++; |
7840 | launch_conference_record_thread(conference, argv[2], SWITCH_FALSE); |
7841 | return SWITCH_STATUS_SUCCESS; |
7842 | } |
7843 | |
7844 | static switch_status_t conf_api_sub_norecord(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7845 | { |
7846 | int all, before = conference->record_count, ttl = 0; |
7847 | switch_event_t *event; |
7848 | |
7849 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7849, __PRETTY_FUNCTION__)); |
7850 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7850, __PRETTY_FUNCTION__)); |
7851 | |
7852 | if (argc <= 2) |
7853 | return SWITCH_STATUS_GENERR; |
7854 | |
7855 | all = (strcasecmp(argv[2], "all") == 0); |
7856 | |
7857 | if (!conference_record_stop(conference, stream, all ? NULL((void*)0) : argv[2]) && !all) { |
7858 | stream->write_function(stream, "non-existant recording '%s'\n", argv[2]); |
7859 | } else { |
7860 | if (test_eflag(conference, EFLAG_RECORD)((conference)->eflags & EFLAG_RECORD) && |
7861 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7861, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
7862 | conference_add_event_data(conference, event); |
7863 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-recording"); |
7864 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", all ? "all" : argv[2]); |
7865 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Recordings", conference->record_count ? "true" : "false"); |
7866 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7866, &event, ((void*)0)); |
7867 | } |
7868 | } |
7869 | |
7870 | ttl = before - conference->record_count; |
7871 | stream->write_function(stream, "Stopped recording %d file%s\n", ttl, ttl == 1 ? "" : "s"); |
7872 | |
7873 | return SWITCH_STATUS_SUCCESS; |
7874 | } |
7875 | |
7876 | static switch_status_t conf_api_sub_pauserec(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7877 | { |
7878 | switch_event_t *event; |
7879 | recording_action_type_t action; |
7880 | |
7881 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7881, __PRETTY_FUNCTION__)); |
7882 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7882, __PRETTY_FUNCTION__)); |
7883 | |
7884 | if (argc <= 2) |
7885 | return SWITCH_STATUS_GENERR; |
7886 | |
7887 | if (strcasecmp(argv[1], "pause") == 0) { |
7888 | action = REC_ACTION_PAUSE; |
7889 | } else if (strcasecmp(argv[1], "resume") == 0) { |
7890 | action = REC_ACTION_RESUME; |
7891 | } else { |
7892 | return SWITCH_STATUS_GENERR; |
7893 | } |
7894 | stream->write_function(stream, "%s recording file %s\n", |
7895 | action == REC_ACTION_PAUSE ? "Pause" : "Resume", argv[2]); |
7896 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 7896, ((void*)0), SWITCH_LOG_DEBUG, "%s recording file %s\n", |
7897 | action == REC_ACTION_PAUSE ? "Pause" : "Resume", argv[2]); |
7898 | |
7899 | if (!conference_record_action(conference, argv[2], action)) { |
7900 | stream->write_function(stream, "non-existant recording '%s'\n", argv[2]); |
7901 | } else { |
7902 | if (test_eflag(conference, EFLAG_RECORD)((conference)->eflags & EFLAG_RECORD) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 7902, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) |
7903 | { |
7904 | conference_add_event_data(conference, event); |
7905 | if (action == REC_ACTION_PAUSE) { |
7906 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "pause-recording"); |
7907 | } else { |
7908 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "resume-recording"); |
7909 | } |
7910 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", argv[2]); |
7911 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Recordings", conference->record_count ? "true" : "false"); |
7912 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 7912, &event, ((void*)0)); |
7913 | } |
7914 | } |
7915 | |
7916 | return SWITCH_STATUS_SUCCESS; |
7917 | } |
7918 | |
7919 | static switch_status_t conf_api_sub_recording(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7920 | { |
7921 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 7921, __PRETTY_FUNCTION__)); |
7922 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 7922, __PRETTY_FUNCTION__)); |
7923 | |
7924 | if (argc > 2 && argc <= 3) { |
7925 | if (strcasecmp(argv[2], "stop") == 0 || strcasecmp(argv[2], "check") == 0) { |
7926 | argv[3] = "all"; |
7927 | argc++; |
7928 | } |
7929 | } |
7930 | |
7931 | if (argc <= 3) { |
7932 | /* It means that old syntax is used */ |
7933 | return conf_api_sub_record(conference,stream,argc,argv); |
7934 | } else { |
7935 | /* for new syntax call existing functions with fixed parameter list */ |
7936 | if (strcasecmp(argv[2], "start") == 0) { |
7937 | argv[1] = argv[2]; |
7938 | argv[2] = argv[3]; |
7939 | return conf_api_sub_record(conference,stream,4,argv); |
7940 | } else if (strcasecmp(argv[2], "stop") == 0) { |
7941 | argv[1] = argv[2]; |
7942 | argv[2] = argv[3]; |
7943 | return conf_api_sub_norecord(conference,stream,4,argv); |
7944 | } else if (strcasecmp(argv[2], "check") == 0) { |
7945 | argv[1] = argv[2]; |
7946 | argv[2] = argv[3]; |
7947 | return conf_api_sub_check_record(conference,stream,4,argv); |
7948 | } else if (strcasecmp(argv[2], "pause") == 0) { |
7949 | argv[1] = argv[2]; |
7950 | argv[2] = argv[3]; |
7951 | return conf_api_sub_pauserec(conference,stream,4,argv); |
7952 | } else if (strcasecmp(argv[2], "resume") == 0) { |
7953 | argv[1] = argv[2]; |
7954 | argv[2] = argv[3]; |
7955 | return conf_api_sub_pauserec(conference,stream,4,argv); |
7956 | } else { |
7957 | return SWITCH_STATUS_GENERR; |
7958 | } |
7959 | } |
7960 | } |
7961 | |
7962 | static switch_status_t conf_api_sub_file_vol(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
7963 | { |
7964 | if (argc >= 1) { |
7965 | conference_file_node_t *fnode; |
7966 | int vol = 0; |
7967 | int ok = 0; |
7968 | |
7969 | if (argc < 2) { |
7970 | stream->write_function(stream, "missing args\n"); |
7971 | return SWITCH_STATUS_GENERR; |
7972 | } |
7973 | |
7974 | switch_mutex_lock(conference->mutex); |
7975 | |
7976 | fnode = conference->fnode; |
7977 | |
7978 | vol = atoi(argv[2]); |
7979 | |
7980 | if (argc > 3) { |
7981 | if (strcasecmp(argv[3], "async")) { |
7982 | fnode = conference->async_fnode; |
7983 | } |
7984 | } |
7985 | |
7986 | if (fnode && fnode->type == NODE_TYPE_FILE) { |
7987 | fnode->fh.vol = vol; |
7988 | ok = 1; |
7989 | } |
7990 | switch_mutex_unlock(conference->mutex); |
7991 | |
7992 | |
7993 | if (ok) { |
7994 | stream->write_function(stream, "volume changed\n"); |
7995 | return SWITCH_STATUS_SUCCESS; |
7996 | } else { |
7997 | stream->write_function(stream, "File not playing\n"); |
7998 | return SWITCH_STATUS_GENERR; |
7999 | } |
8000 | |
8001 | |
8002 | } else { |
8003 | stream->write_function(stream, "Invalid parameters:\n"); |
8004 | return SWITCH_STATUS_GENERR; |
8005 | } |
8006 | } |
8007 | |
8008 | static switch_status_t conf_api_sub_pin(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) |
8009 | { |
8010 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 8010, __PRETTY_FUNCTION__)); |
8011 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 8011, __PRETTY_FUNCTION__)); |
8012 | |
8013 | if ((argc == 4) && (!strcmp(argv[2], "mod")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (argv[2]) && __builtin_constant_p ("mod") && (__s1_len = __builtin_strlen (argv[2]), __s2_len = __builtin_strlen ("mod"), (!((size_t)(const void *)((argv[2]) + 1) - (size_t) (const void *)(argv[2]) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("mod") + 1) - (size_t)(const void *)("mod") == 1) || __s2_len >= 4)) ? __builtin_strcmp (argv [2], "mod") : (__builtin_constant_p (argv[2]) && ((size_t )(const void *)((argv[2]) + 1) - (size_t)(const void *)(argv[ 2]) == 1) && (__s1_len = __builtin_strlen (argv[2]), __s1_len < 4) ? (__builtin_constant_p ("mod") && ((size_t) (const void *)(("mod") + 1) - (size_t)(const void *)("mod") == 1) ? __builtin_strcmp (argv[2], "mod") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("mod"); int __result = (((const unsigned char *) (const char *) (argv[2]))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( argv[2]))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( argv[2]))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (argv [2]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("mod") && ((size_t)(const void *)(("mod") + 1) - (size_t )(const void *)("mod") == 1) && (__s2_len = __builtin_strlen ("mod"), __s2_len < 4) ? (__builtin_constant_p (argv[2]) && ((size_t)(const void *)((argv[2]) + 1) - (size_t)(const void *)(argv[2]) == 1) ? __builtin_strcmp (argv[2], "mod") : (- ( __extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (argv[2]); int __result = (((const unsigned char *) (const char *) ("mod"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("mod"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("mod"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) ("mod"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (argv[2], "mod")))); }))) { |
8014 | conference->mpin = switch_core_strdup(conference->pool, argv[3])switch_core_perform_strdup(conference->pool, argv[3], "mod_conference.c" , (const char *)__func__, 8014); |
8015 | stream->write_function(stream, "Moderator Pin for conference %s set: %s\n", argv[0], conference->mpin); |
8016 | return SWITCH_STATUS_SUCCESS; |
8017 | } else if ((argc == 3) && (!strcmp(argv[1], "pin")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (argv[1]) && __builtin_constant_p ("pin") && (__s1_len = __builtin_strlen (argv[1]), __s2_len = __builtin_strlen ("pin"), (!((size_t)(const void *)((argv[1]) + 1) - (size_t) (const void *)(argv[1]) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("pin") + 1) - (size_t)(const void *)("pin") == 1) || __s2_len >= 4)) ? __builtin_strcmp (argv [1], "pin") : (__builtin_constant_p (argv[1]) && ((size_t )(const void *)((argv[1]) + 1) - (size_t)(const void *)(argv[ 1]) == 1) && (__s1_len = __builtin_strlen (argv[1]), __s1_len < 4) ? (__builtin_constant_p ("pin") && ((size_t) (const void *)(("pin") + 1) - (size_t)(const void *)("pin") == 1) ? __builtin_strcmp (argv[1], "pin") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("pin"); int __result = (((const unsigned char *) (const char *) (argv[1]))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( argv[1]))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( argv[1]))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (argv [1]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("pin") && ((size_t)(const void *)(("pin") + 1) - (size_t )(const void *)("pin") == 1) && (__s2_len = __builtin_strlen ("pin"), __s2_len < 4) ? (__builtin_constant_p (argv[1]) && ((size_t)(const void *)((argv[1]) + 1) - (size_t)(const void *)(argv[1]) == 1) ? __builtin_strcmp (argv[1], "pin") : (- ( __extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (argv[1]); int __result = (((const unsigned char *) (const char *) ("pin"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("pin"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("pin"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) ("pin"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (argv[1], "pin")))); }))) { |
8018 | conference->pin = switch_core_strdup(conference->pool, argv[2])switch_core_perform_strdup(conference->pool, argv[2], "mod_conference.c" , (const char *)__func__, 8018); |
8019 | stream->write_function(stream, "Pin for conference %s set: %s\n", argv[0], conference->pin); |
8020 | return SWITCH_STATUS_SUCCESS; |
8021 | } else if (argc == 2 && (!strcmp(argv[1], "nopin")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (argv[1]) && __builtin_constant_p ("nopin") && (__s1_len = __builtin_strlen (argv[1]), __s2_len = __builtin_strlen ("nopin"), (!((size_t)(const void *)((argv[1]) + 1) - (size_t )(const void *)(argv[1]) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("nopin") + 1) - (size_t)(const void *)("nopin") == 1) || __s2_len >= 4)) ? __builtin_strcmp ( argv[1], "nopin") : (__builtin_constant_p (argv[1]) && ((size_t)(const void *)((argv[1]) + 1) - (size_t)(const void *)(argv[1]) == 1) && (__s1_len = __builtin_strlen (argv [1]), __s1_len < 4) ? (__builtin_constant_p ("nopin") && ((size_t)(const void *)(("nopin") + 1) - (size_t)(const void *)("nopin") == 1) ? __builtin_strcmp (argv[1], "nopin") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("nopin"); int __result = (((const unsigned char *) ( const char *) (argv[1]))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (argv[1]))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (argv[1]))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (argv[1]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("nopin") && ((size_t)(const void *)(("nopin") + 1) - (size_t)(const void *)("nopin") == 1) && (__s2_len = __builtin_strlen ("nopin"), __s2_len < 4) ? (__builtin_constant_p (argv[1]) && ((size_t)(const void *)((argv[1]) + 1) - (size_t)(const void *)(argv[1]) == 1) ? __builtin_strcmp (argv [1], "nopin") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (argv[1]); int __result = (((const unsigned char *) (const char *) ("nopin"))[0] - __s2 [0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("nopin"))[1] - __s2 [1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("nopin"))[2] - __s2 [2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("nopin"))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (argv[1], "nopin" )))); }))) { |
8022 | conference->pin = NULL((void*)0); |
8023 | stream->write_function(stream, "Pin for conference %s deleted\n", argv[0]); |
8024 | return SWITCH_STATUS_SUCCESS; |
8025 | } else { |
8026 | stream->write_function(stream, "Invalid parameters:\n"); |
8027 | return SWITCH_STATUS_GENERR; |
8028 | } |
8029 | } |
8030 | |
8031 | static switch_status_t conf_api_sub_get(conference_obj_t *conference, |
8032 | switch_stream_handle_t *stream, int argc, char **argv) { |
8033 | int ret_status = SWITCH_STATUS_GENERR; |
8034 | |
8035 | if (argc != 3) { |
8036 | ret_status = SWITCH_STATUS_FALSE; |
8037 | } else { |
8038 | ret_status = SWITCH_STATUS_SUCCESS; |
8039 | if (strcasecmp(argv[2], "run_time") == 0) { |
8040 | stream->write_function(stream, "%ld", |
8041 | switch_epoch_time_now(NULL((void*)0)) - conference->run_time); |
8042 | } else if (strcasecmp(argv[2], "count") == 0) { |
8043 | stream->write_function(stream, "%d", |
8044 | conference->count); |
8045 | } else if (strcasecmp(argv[2], "count_ghosts") == 0) { |
8046 | stream->write_function(stream, "%d", |
8047 | conference->count_ghosts); |
8048 | } else if (strcasecmp(argv[2], "max_members") == 0) { |
8049 | stream->write_function(stream, "%d", |
8050 | conference->max_members); |
8051 | } else if (strcasecmp(argv[2], "rate") == 0) { |
8052 | stream->write_function(stream, "%d", |
8053 | conference->rate); |
8054 | } else if (strcasecmp(argv[2], "profile_name") == 0) { |
8055 | stream->write_function(stream, "%s", |
8056 | conference->profile_name); |
8057 | } else if (strcasecmp(argv[2], "sound_prefix") == 0) { |
8058 | stream->write_function(stream, "%s", |
8059 | conference->sound_prefix); |
8060 | } else if (strcasecmp(argv[2], "caller_id_name") == 0) { |
8061 | stream->write_function(stream, "%s", |
8062 | conference->caller_id_name); |
8063 | } else if (strcasecmp(argv[2], "caller_id_number") == 0) { |
8064 | stream->write_function(stream, "%s", |
8065 | conference->caller_id_number); |
8066 | } else if (strcasecmp(argv[2], "is_locked") == 0) { |
8067 | stream->write_function(stream, "%s", |
8068 | switch_test_flag(conference, CFLAG_LOCKED)((conference)->flags & CFLAG_LOCKED) ? "locked" : ""); |
8069 | } else if (strcasecmp(argv[2], "endconf_grace_time") == 0) { |
8070 | stream->write_function(stream, "%d", |
8071 | conference->endconf_grace_time); |
8072 | } else if (strcasecmp(argv[2], "uuid") == 0) { |
8073 | stream->write_function(stream, "%s", |
8074 | conference->uuid_str); |
8075 | } else if (strcasecmp(argv[2], "wait_mod") == 0) { |
8076 | stream->write_function(stream, "%s", |
8077 | switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD) ? "true" : ""); |
8078 | } else { |
8079 | ret_status = SWITCH_STATUS_FALSE; |
8080 | } |
8081 | } |
8082 | |
8083 | return ret_status; |
8084 | } |
8085 | |
8086 | static switch_status_t conf_api_sub_set(conference_obj_t *conference, |
8087 | switch_stream_handle_t *stream, int argc, char **argv) { |
8088 | int ret_status = SWITCH_STATUS_GENERR; |
8089 | |
8090 | if (argc != 4 || zstr(argv[3])_zstr(argv[3])) { |
8091 | ret_status = SWITCH_STATUS_FALSE; |
8092 | } else { |
8093 | ret_status = SWITCH_STATUS_SUCCESS; |
8094 | if (strcasecmp(argv[2], "max_members") == 0) { |
8095 | int new_max = atoi(argv[3]); |
8096 | if (new_max >= 0) { |
8097 | stream->write_function(stream, "%d", conference->max_members); |
8098 | conference->max_members = new_max; |
8099 | } else { |
8100 | ret_status = SWITCH_STATUS_FALSE; |
8101 | } |
8102 | } else if (strcasecmp(argv[2], "sound_prefix") == 0) { |
8103 | stream->write_function(stream, "%s",conference->sound_prefix); |
8104 | conference->sound_prefix = switch_core_strdup(conference->pool, argv[3])switch_core_perform_strdup(conference->pool, argv[3], "mod_conference.c" , (const char *)__func__, 8104); |
8105 | } else if (strcasecmp(argv[2], "caller_id_name") == 0) { |
8106 | stream->write_function(stream, "%s",conference->caller_id_name); |
8107 | conference->caller_id_name = switch_core_strdup(conference->pool, argv[3])switch_core_perform_strdup(conference->pool, argv[3], "mod_conference.c" , (const char *)__func__, 8107); |
8108 | } else if (strcasecmp(argv[2], "caller_id_number") == 0) { |
8109 | stream->write_function(stream, "%s",conference->caller_id_number); |
8110 | conference->caller_id_number = switch_core_strdup(conference->pool, argv[3])switch_core_perform_strdup(conference->pool, argv[3], "mod_conference.c" , (const char *)__func__, 8110); |
8111 | } else if (strcasecmp(argv[2], "endconf_grace_time") == 0) { |
8112 | int new_gt = atoi(argv[3]); |
8113 | if (new_gt >= 0) { |
8114 | stream->write_function(stream, "%d", conference->endconf_grace_time); |
8115 | conference->endconf_grace_time = new_gt; |
8116 | } else { |
8117 | ret_status = SWITCH_STATUS_FALSE; |
8118 | } |
8119 | } else { |
8120 | ret_status = SWITCH_STATUS_FALSE; |
8121 | } |
8122 | } |
8123 | |
8124 | return ret_status; |
8125 | } |
8126 | |
8127 | typedef enum { |
8128 | CONF_API_COMMAND_LIST = 0, |
8129 | CONF_API_COMMAND_ENERGY, |
8130 | CONF_API_COMMAND_VOLUME_IN, |
8131 | CONF_API_COMMAND_VOLUME_OUT, |
8132 | CONF_API_COMMAND_PLAY, |
8133 | CONF_API_COMMAND_SAY, |
8134 | CONF_API_COMMAND_SAYMEMBER, |
8135 | CONF_API_COMMAND_STOP, |
8136 | CONF_API_COMMAND_DTMF, |
8137 | CONF_API_COMMAND_KICK, |
8138 | CONF_API_COMMAND_MUTE, |
8139 | CONF_API_COMMAND_UNMUTE, |
8140 | CONF_API_COMMAND_DEAF, |
8141 | CONF_API_COMMAND_UNDEAF, |
8142 | CONF_API_COMMAND_RELATE, |
8143 | CONF_API_COMMAND_LOCK, |
8144 | CONF_API_COMMAND_UNLOCK, |
8145 | CONF_API_COMMAND_DIAL, |
8146 | CONF_API_COMMAND_BGDIAL, |
8147 | CONF_API_COMMAND_TRANSFER, |
8148 | CONF_API_COMMAND_RECORD, |
8149 | CONF_API_COMMAND_NORECORD, |
8150 | CONF_API_COMMAND_EXIT_SOUND, |
8151 | CONF_API_COMMAND_ENTER_SOUND, |
8152 | CONF_API_COMMAND_PIN, |
8153 | CONF_API_COMMAND_NOPIN, |
8154 | CONF_API_COMMAND_GET, |
8155 | CONF_API_COMMAND_SET, |
8156 | } api_command_type_t; |
8157 | |
8158 | /* API Interface Function sub-commands */ |
8159 | /* Entries in this list should be kept in sync with the enum above */ |
8160 | static api_command_t conf_api_sub_commands[] = { |
8161 | {"list", (void_fn_t) & conf_api_sub_list, CONF_API_SUB_ARGS_SPLIT, "list", "[delim <string>]|[count]"}, |
8162 | {"xml_list", (void_fn_t) & conf_api_sub_xml_list, CONF_API_SUB_ARGS_SPLIT, "xml_list", ""}, |
8163 | {"energy", (void_fn_t) & conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET, "energy", "<member_id|all|last|non_moderator> [<newval>]"}, |
8164 | {"volume_in", (void_fn_t) & conf_api_sub_volume_in, CONF_API_SUB_MEMBER_TARGET, "volume_in", "<member_id|all|last|non_moderator> [<newval>]"}, |
8165 | {"volume_out", (void_fn_t) & conf_api_sub_volume_out, CONF_API_SUB_MEMBER_TARGET, "volume_out", "<member_id|all|last|non_moderator> [<newval>]"}, |
8166 | {"position", (void_fn_t) & conf_api_sub_position, CONF_API_SUB_MEMBER_TARGET, "position", "<member_id> <x>,<y>,<z>"}, |
8167 | {"auto-3d-position", (void_fn_t) & conf_api_sub_auto_position, CONF_API_SUB_ARGS_SPLIT, "auto-3d-position", "[on|off]"}, |
8168 | {"play", (void_fn_t) & conf_api_sub_play, CONF_API_SUB_ARGS_SPLIT, "play", "<file_path> [async|<member_id> [nomux]]"}, |
8169 | {"pause_play", (void_fn_t) & conf_api_sub_pause_play, CONF_API_SUB_ARGS_SPLIT, "pause", "[<member_id>]"}, |
8170 | {"file_seek", (void_fn_t) & conf_api_sub_file_seek, CONF_API_SUB_ARGS_SPLIT, "file_seek", "[+-]<val> [<member_id>]"}, |
8171 | {"say", (void_fn_t) & conf_api_sub_say, CONF_API_SUB_ARGS_AS_ONE, "say", "<text>"}, |
8172 | {"saymember", (void_fn_t) & conf_api_sub_saymember, CONF_API_SUB_ARGS_AS_ONE, "saymember", "<member_id> <text>"}, |
8173 | {"stop", (void_fn_t) & conf_api_sub_stop, CONF_API_SUB_ARGS_SPLIT, "stop", "<[current|all|async|last]> [<member_id>]"}, |
8174 | {"dtmf", (void_fn_t) & conf_api_sub_dtmf, CONF_API_SUB_MEMBER_TARGET, "dtmf", "<[member_id|all|last|non_moderator]> <digits>"}, |
8175 | {"kick", (void_fn_t) & conf_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "kick", "<[member_id|all|last|non_moderator]> [<optional sound file>]"}, |
8176 | {"hup", (void_fn_t) & conf_api_sub_hup, CONF_API_SUB_MEMBER_TARGET, "hup", "<[member_id|all|last|non_moderator]>"}, |
8177 | {"mute", (void_fn_t) & conf_api_sub_mute, CONF_API_SUB_MEMBER_TARGET, "mute", "<[member_id|all]|last|non_moderator> [<quiet>]"}, |
8178 | {"tmute", (void_fn_t) & conf_api_sub_tmute, CONF_API_SUB_MEMBER_TARGET, "tmute", "<[member_id|all]|last|non_moderator> [<quiet>]"}, |
8179 | {"unmute", (void_fn_t) & conf_api_sub_unmute, CONF_API_SUB_MEMBER_TARGET, "unmute", "<[member_id|all]|last|non_moderator> [<quiet>]"}, |
8180 | {"deaf", (void_fn_t) & conf_api_sub_deaf, CONF_API_SUB_MEMBER_TARGET, "deaf", "<[member_id|all]|last|non_moderator>"}, |
8181 | {"undeaf", (void_fn_t) & conf_api_sub_undeaf, CONF_API_SUB_MEMBER_TARGET, "undeaf", "<[member_id|all]|last|non_moderator>"}, |
8182 | {"relate", (void_fn_t) & conf_api_sub_relate, CONF_API_SUB_ARGS_SPLIT, "relate", "<member_id> <other_member_id> [nospeak|nohear|clear]"}, |
8183 | {"lock", (void_fn_t) & conf_api_sub_lock, CONF_API_SUB_ARGS_SPLIT, "lock", ""}, |
8184 | {"unlock", (void_fn_t) & conf_api_sub_unlock, CONF_API_SUB_ARGS_SPLIT, "unlock", ""}, |
8185 | {"agc", (void_fn_t) & conf_api_sub_agc, CONF_API_SUB_ARGS_SPLIT, "agc", ""}, |
8186 | {"dial", (void_fn_t) & conf_api_sub_dial, CONF_API_SUB_ARGS_SPLIT, "dial", "<endpoint_module_name>/<destination> <callerid number> <callerid name>"}, |
8187 | {"bgdial", (void_fn_t) & conf_api_sub_bgdial, CONF_API_SUB_ARGS_SPLIT, "bgdial", "<endpoint_module_name>/<destination> <callerid number> <callerid name>"}, |
8188 | {"transfer", (void_fn_t) & conf_api_sub_transfer, CONF_API_SUB_ARGS_SPLIT, "transfer", "<conference_name> <member id> [...<member id>]"}, |
8189 | {"record", (void_fn_t) & conf_api_sub_record, CONF_API_SUB_ARGS_SPLIT, "record", "<filename>"}, |
8190 | {"chkrecord", (void_fn_t) & conf_api_sub_check_record, CONF_API_SUB_ARGS_SPLIT, "chkrecord", "<confname>"}, |
8191 | {"norecord", (void_fn_t) & conf_api_sub_norecord, CONF_API_SUB_ARGS_SPLIT, "norecord", "<[filename|all]>"}, |
8192 | {"pause", (void_fn_t) & conf_api_sub_pauserec, CONF_API_SUB_ARGS_SPLIT, "pause", "<filename>"}, |
8193 | {"resume", (void_fn_t) & conf_api_sub_pauserec, CONF_API_SUB_ARGS_SPLIT, "resume", "<filename>"}, |
8194 | {"recording", (void_fn_t) & conf_api_sub_recording, CONF_API_SUB_ARGS_SPLIT, "recording", "[start|stop|check|pause|resume] [<filename>|all]"}, |
8195 | {"exit_sound", (void_fn_t) & conf_api_sub_exit_sound, CONF_API_SUB_ARGS_SPLIT, "exit_sound", "on|off|none|file <filename>"}, |
8196 | {"enter_sound", (void_fn_t) & conf_api_sub_enter_sound, CONF_API_SUB_ARGS_SPLIT, "enter_sound", "on|off|none|file <filename>"}, |
8197 | {"pin", (void_fn_t) & conf_api_sub_pin, CONF_API_SUB_ARGS_SPLIT, "pin", "<pin#>"}, |
8198 | {"nopin", (void_fn_t) & conf_api_sub_pin, CONF_API_SUB_ARGS_SPLIT, "nopin", ""}, |
8199 | {"get", (void_fn_t) & conf_api_sub_get, CONF_API_SUB_ARGS_SPLIT, "get", "<parameter-name>"}, |
8200 | {"set", (void_fn_t) & conf_api_sub_set, CONF_API_SUB_ARGS_SPLIT, "set", "<max_members|sound_prefix|caller_id_name|caller_id_number|endconf_grace_time> <value>"}, |
8201 | {"file-vol", (void_fn_t) & conf_api_sub_file_vol, CONF_API_SUB_ARGS_SPLIT, "file-vol", "<vol#>"}, |
8202 | {"floor", (void_fn_t) & conf_api_sub_floor, CONF_API_SUB_MEMBER_TARGET, "floor", "<member_id|last>"}, |
8203 | {"vid-floor", (void_fn_t) & conf_api_sub_vid_floor, CONF_API_SUB_MEMBER_TARGET, "vid-floor", "<member_id|last> [force]"}, |
8204 | {"clear-vid-floor", (void_fn_t) & conf_api_sub_clear_vid_floor, CONF_API_SUB_ARGS_AS_ONE, "clear-vid-floor", ""} |
8205 | }; |
8206 | |
8207 | #define CONFFUNCAPISIZE(sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0 ])) (sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0])) |
8208 | |
8209 | switch_status_t conf_api_dispatch(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv, const char *cmdline, int argn) |
8210 | { |
8211 | switch_status_t status = SWITCH_STATUS_FALSE; |
8212 | uint32_t i, found = 0; |
8213 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 8213, __PRETTY_FUNCTION__)); |
8214 | switch_assert(stream != NULL)((stream != ((void*)0)) ? (void) (0) : __assert_fail ("stream != ((void*)0)" , "mod_conference.c", 8214, __PRETTY_FUNCTION__)); |
8215 | |
8216 | /* loop through the command table to find a match */ |
8217 | for (i = 0; i < CONFFUNCAPISIZE(sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0 ])) && !found; i++) { |
8218 | if (strcasecmp(argv[argn], conf_api_sub_commands[i].pname) == 0) { |
8219 | found = 1; |
8220 | switch (conf_api_sub_commands[i].fntype) { |
8221 | |
8222 | /* commands that we've broken the command line into arguments for */ |
8223 | case CONF_API_SUB_ARGS_SPLIT: |
8224 | { |
8225 | conf_api_args_cmd_t pfn = (conf_api_args_cmd_t) conf_api_sub_commands[i].pfnapicmd; |
8226 | |
8227 | if (pfn(conference, stream, argc, argv) != SWITCH_STATUS_SUCCESS) { |
8228 | /* command returned error, so show syntax usage */ |
8229 | stream->write_function(stream, "%s %s", conf_api_sub_commands[i].pcommand, conf_api_sub_commands[i].psyntax); |
8230 | } |
8231 | } |
8232 | break; |
8233 | |
8234 | /* member specific command that can be iterated */ |
8235 | case CONF_API_SUB_MEMBER_TARGET: |
8236 | { |
8237 | uint32_t id = 0; |
8238 | uint8_t all = 0; |
8239 | uint8_t last = 0; |
8240 | uint8_t non_mod = 0; |
8241 | |
8242 | if (argv[argn + 1]) { |
8243 | if (!(id = atoi(argv[argn + 1]))) { |
8244 | all = strcasecmp(argv[argn + 1], "all") ? 0 : 1; |
8245 | non_mod = strcasecmp(argv[argn + 1], "non_moderator") ? 0 : 1; |
8246 | last = strcasecmp(argv[argn + 1], "last") ? 0 : 1; |
8247 | } |
8248 | } |
8249 | |
8250 | if (all || non_mod) { |
8251 | conference_member_itterator(conference, stream, non_mod, (conf_api_member_cmd_t) conf_api_sub_commands[i].pfnapicmd, argv[argn + 2]); |
8252 | } else if (last) { |
8253 | conference_member_t *member = NULL((void*)0); |
8254 | conference_member_t *last_member = NULL((void*)0); |
8255 | |
8256 | switch_mutex_lock(conference->member_mutex); |
8257 | |
8258 | /* find last (oldest) member */ |
8259 | member = conference->members; |
8260 | while (member != NULL((void*)0)) { |
8261 | if (last_member == NULL((void*)0) || member->id > last_member->id) { |
8262 | last_member = member; |
8263 | } |
8264 | member = member->next; |
8265 | } |
8266 | |
8267 | /* exec functio on last (oldest) member */ |
8268 | if (last_member != NULL((void*)0) && last_member->session && !switch_test_flag(last_member, MFLAG_NOCHANNEL)((last_member)->flags & MFLAG_NOCHANNEL)) { |
8269 | conf_api_member_cmd_t pfn = (conf_api_member_cmd_t) conf_api_sub_commands[i].pfnapicmd; |
8270 | pfn(last_member, stream, argv[argn + 2]); |
8271 | } |
8272 | |
8273 | switch_mutex_unlock(conference->member_mutex); |
8274 | } else if (id) { |
8275 | conf_api_member_cmd_t pfn = (conf_api_member_cmd_t) conf_api_sub_commands[i].pfnapicmd; |
8276 | conference_member_t *member = conference_member_get(conference, id); |
8277 | |
8278 | if (member != NULL((void*)0)) { |
8279 | pfn(member, stream, argv[argn + 2]); |
8280 | switch_thread_rwlock_unlock(member->rwlock); |
8281 | } else { |
8282 | stream->write_function(stream, "Non-Existant ID %u\n", id); |
8283 | } |
8284 | } else { |
8285 | stream->write_function(stream, "%s %s", conf_api_sub_commands[i].pcommand, conf_api_sub_commands[i].psyntax); |
8286 | } |
8287 | } |
8288 | break; |
8289 | |
8290 | /* commands that deals with all text after command */ |
8291 | case CONF_API_SUB_ARGS_AS_ONE: |
8292 | { |
8293 | conf_api_text_cmd_t pfn = (conf_api_text_cmd_t) conf_api_sub_commands[i].pfnapicmd; |
8294 | char *start_text; |
8295 | const char *modified_cmdline = cmdline; |
8296 | const char *cmd = conf_api_sub_commands[i].pname; |
8297 | |
8298 | if (!zstr(modified_cmdline)_zstr(modified_cmdline) && (start_text = strstr(modified_cmdline, cmd))) { |
8299 | modified_cmdline = start_text + strlen(cmd); |
8300 | while (modified_cmdline && (*modified_cmdline == ' ' || *modified_cmdline == '\t')) { |
8301 | modified_cmdline++; |
8302 | } |
8303 | } |
8304 | |
8305 | /* call the command handler */ |
8306 | if (pfn(conference, stream, modified_cmdline) != SWITCH_STATUS_SUCCESS) { |
8307 | /* command returned error, so show syntax usage */ |
8308 | stream->write_function(stream, "%s %s", conf_api_sub_commands[i].pcommand, conf_api_sub_commands[i].psyntax); |
8309 | } |
8310 | } |
8311 | break; |
8312 | } |
8313 | } |
8314 | } |
8315 | |
8316 | if (!found) { |
8317 | stream->write_function(stream, "Conference command '%s' not found.\n", argv[argn]); |
8318 | } else { |
8319 | status = SWITCH_STATUS_SUCCESS; |
8320 | } |
8321 | |
8322 | return status; |
8323 | } |
8324 | |
8325 | /* API Interface Function */ |
8326 | SWITCH_STANDARD_API(conf_api_main)static switch_status_t conf_api_main ( const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream) |
8327 | { |
8328 | char *lbuf = NULL((void*)0); |
8329 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
8330 | char *http = NULL((void*)0), *type = NULL((void*)0); |
8331 | int argc; |
8332 | char *argv[25] = { 0 }; |
8333 | |
8334 | if (!cmd) { |
8335 | cmd = "help"; |
8336 | } |
8337 | |
8338 | if (stream->param_event) { |
8339 | http = switch_event_get_header(stream->param_event, "http-host")switch_event_get_header_idx(stream->param_event, "http-host" , -1); |
8340 | type = switch_event_get_header(stream->param_event, "content-type")switch_event_get_header_idx(stream->param_event, "content-type" , -1); |
8341 | } |
8342 | |
8343 | if (http) { |
8344 | /* Output must be to a web browser */ |
8345 | if (type && !strcasecmp(type, "text/html")) { |
8346 | stream->write_function(stream, "<pre>\n"); |
8347 | } |
8348 | } |
8349 | |
8350 | if (!(lbuf = strdup(cmd)(__extension__ (__builtin_constant_p (cmd) && ((size_t )(const void *)((cmd) + 1) - (size_t)(const void *)(cmd) == 1 ) ? (((const char *) (cmd))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (cmd) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, cmd, __len); __retval ; })) : __strdup (cmd))))) { |
8351 | return status; |
8352 | } |
8353 | |
8354 | argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); |
8355 | |
8356 | /* try to find a command to execute */ |
8357 | if (argc && argv[0]) { |
8358 | conference_obj_t *conference = NULL((void*)0); |
8359 | |
8360 | if ((conference = conference_find(argv[0], NULL((void*)0)))) { |
8361 | if (argc >= 2) { |
8362 | conf_api_dispatch(conference, stream, argc, argv, cmd, 1); |
8363 | } else { |
8364 | stream->write_function(stream, "Conference command, not specified.\nTry 'help'\n"); |
8365 | } |
8366 | switch_thread_rwlock_unlock(conference->rwlock); |
8367 | |
8368 | } else if (argv[0]) { |
8369 | /* special case the list command, because it doesn't require a conference argument */ |
8370 | if (strcasecmp(argv[0], "list") == 0) { |
8371 | conf_api_sub_list(NULL((void*)0), stream, argc, argv); |
8372 | } else if (strcasecmp(argv[0], "xml_list") == 0) { |
8373 | conf_api_sub_xml_list(NULL((void*)0), stream, argc, argv); |
8374 | } else if (strcasecmp(argv[0], "help") == 0 || strcasecmp(argv[0], "commands") == 0) { |
8375 | stream->write_function(stream, "%s\n", api_syntax); |
8376 | } else if (argv[1] && strcasecmp(argv[1], "dial") == 0) { |
8377 | if (conf_api_sub_dial(NULL((void*)0), stream, argc, argv) != SWITCH_STATUS_SUCCESS) { |
8378 | /* command returned error, so show syntax usage */ |
8379 | stream->write_function(stream, "%s %s", conf_api_sub_commands[CONF_API_COMMAND_DIAL].pcommand, |
8380 | conf_api_sub_commands[CONF_API_COMMAND_DIAL].psyntax); |
8381 | } |
8382 | } else if (argv[1] && strcasecmp(argv[1], "bgdial") == 0) { |
8383 | if (conf_api_sub_bgdial(NULL((void*)0), stream, argc, argv) != SWITCH_STATUS_SUCCESS) { |
8384 | /* command returned error, so show syntax usage */ |
8385 | stream->write_function(stream, "%s %s", conf_api_sub_commands[CONF_API_COMMAND_BGDIAL].pcommand, |
8386 | conf_api_sub_commands[CONF_API_COMMAND_BGDIAL].psyntax); |
8387 | } |
8388 | } else { |
8389 | stream->write_function(stream, "Conference %s not found\n", argv[0]); |
8390 | } |
8391 | } |
8392 | |
8393 | } else { |
8394 | int i; |
8395 | |
8396 | for (i = 0; i < CONFFUNCAPISIZE(sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0 ])); i++) { |
8397 | stream->write_function(stream, "<conf name> %s %s\n", conf_api_sub_commands[i].pcommand, conf_api_sub_commands[i].psyntax); |
8398 | } |
8399 | } |
8400 | |
8401 | |
8402 | switch_safe_free(lbuf)if (lbuf) {free(lbuf);lbuf=((void*)0);}; |
8403 | |
8404 | return status; |
8405 | } |
8406 | |
8407 | /* generate an outbound call from the conference */ |
8408 | static switch_status_t conference_outcall(conference_obj_t *conference, |
8409 | char *conference_name, |
8410 | switch_core_session_t *session, |
8411 | char *bridgeto, uint32_t timeout, |
8412 | char *flags, char *cid_name, |
8413 | char *cid_num, |
8414 | char *profile, |
8415 | switch_call_cause_t *cause, |
8416 | switch_call_cause_t *cancel_cause, switch_event_t *var_event) |
8417 | { |
8418 | switch_core_session_t *peer_session = NULL((void*)0); |
8419 | switch_channel_t *peer_channel; |
8420 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
8421 | switch_channel_t *caller_channel = NULL((void*)0); |
8422 | char appdata[512]; |
8423 | int rdlock = 0; |
8424 | switch_bool_t have_flags = SWITCH_FALSE; |
8425 | const char *outcall_flags; |
8426 | int track = 0; |
8427 | const char *call_id = NULL((void*)0); |
8428 | |
8429 | if (var_event && switch_true(switch_event_get_header(var_event, "conference_track_status")switch_event_get_header_idx(var_event, "conference_track_status" , -1))) { |
8430 | track++; |
8431 | call_id = switch_event_get_header(var_event, "conference_track_call_id")switch_event_get_header_idx(var_event, "conference_track_call_id" , -1); |
8432 | } |
8433 | |
8434 | *cause = SWITCH_CAUSE_NORMAL_CLEARING; |
8435 | |
8436 | if (conference == NULL((void*)0)) { |
8437 | char *dialstr = switch_mprintf("{ignore_early_media=true}%s", bridgeto); |
8438 | status = switch_ivr_originate(NULL((void*)0), &peer_session, cause, dialstr, 60, NULL((void*)0), cid_name, cid_num, NULL((void*)0), var_event, SOF_NO_LIMITS, NULL((void*)0)); |
8439 | switch_safe_free(dialstr)if (dialstr) {free(dialstr);dialstr=((void*)0);}; |
8440 | |
8441 | if (status != SWITCH_STATUS_SUCCESS) { |
8442 | return status; |
8443 | } |
8444 | |
8445 | peer_channel = switch_core_session_get_channel(peer_session); |
8446 | rdlock = 1; |
8447 | goto callup; |
8448 | } |
8449 | |
8450 | conference_name = conference->name; |
8451 | |
8452 | if (switch_thread_rwlock_tryrdlock(conference->rwlock) != SWITCH_STATUS_SUCCESS) { |
8453 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 8453, (const char*)(session), SWITCH_LOG_CRIT, "Read Lock Fail\n"); |
8454 | return SWITCH_STATUS_FALSE; |
8455 | } |
8456 | |
8457 | if (session != NULL((void*)0)) { |
8458 | caller_channel = switch_core_session_get_channel(session); |
8459 | } |
8460 | |
8461 | if (zstr(cid_name)_zstr(cid_name)) { |
8462 | cid_name = conference->caller_id_name; |
8463 | } |
8464 | |
8465 | if (zstr(cid_num)_zstr(cid_num)) { |
8466 | cid_num = conference->caller_id_number; |
8467 | } |
8468 | |
8469 | /* establish an outbound call leg */ |
8470 | |
8471 | switch_mutex_lock(conference->mutex); |
8472 | conference->originating++; |
8473 | switch_mutex_unlock(conference->mutex); |
8474 | |
8475 | if (track) { |
8476 | send_conference_notify(conference, "SIP/2.0 100 Trying\r\n", call_id, SWITCH_FALSE); |
8477 | } |
8478 | |
8479 | |
8480 | status = switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL((void*)0), cid_name, cid_num, NULL((void*)0), var_event, SOF_NO_LIMITS, cancel_cause); |
8481 | switch_mutex_lock(conference->mutex); |
8482 | conference->originating--; |
8483 | switch_mutex_unlock(conference->mutex); |
8484 | |
8485 | if (status != SWITCH_STATUS_SUCCESS) { |
8486 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 8486, (const char*)(session), SWITCH_LOG_ERROR, "Cannot create outgoing channel, cause: %s\n", |
8487 | switch_channel_cause2str(*cause)); |
8488 | if (caller_channel) { |
8489 | switch_channel_hangup(caller_channel, *cause)switch_channel_perform_hangup(caller_channel, "mod_conference.c" , (const char *)__func__, 8489, *cause); |
8490 | } |
8491 | |
8492 | if (track) { |
8493 | send_conference_notify(conference, "SIP/2.0 481 Failure\r\n", call_id, SWITCH_TRUE); |
8494 | } |
8495 | |
8496 | goto done; |
8497 | } |
8498 | |
8499 | if (track) { |
8500 | send_conference_notify(conference, "SIP/2.0 200 OK\r\n", call_id, SWITCH_TRUE); |
8501 | } |
8502 | |
8503 | rdlock = 1; |
8504 | peer_channel = switch_core_session_get_channel(peer_session); |
8505 | |
8506 | /* make sure the conference still exists */ |
8507 | if (!switch_test_flag(conference, CFLAG_RUNNING)((conference)->flags & CFLAG_RUNNING)) { |
8508 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 8508, (const char*)(session), SWITCH_LOG_ERROR, "Conference is gone now, nevermind..\n"); |
8509 | if (caller_channel) { |
8510 | switch_channel_hangup(caller_channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION)switch_channel_perform_hangup(caller_channel, "mod_conference.c" , (const char *)__func__, 8510, SWITCH_CAUSE_NO_ROUTE_DESTINATION ); |
8511 | } |
8512 | switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION)switch_channel_perform_hangup(peer_channel, "mod_conference.c" , (const char *)__func__, 8512, SWITCH_CAUSE_NO_ROUTE_DESTINATION ); |
8513 | goto done; |
8514 | } |
8515 | |
8516 | if (caller_channel && switch_channel_test_flag(peer_channel, CF_ANSWERED)) { |
8517 | switch_channel_answer(caller_channel)switch_channel_perform_answer(caller_channel, "mod_conference.c" , (const char *)__func__, 8517); |
8518 | } |
8519 | |
8520 | callup: |
8521 | |
8522 | /* if the outbound call leg is ready */ |
8523 | if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) { |
8524 | switch_caller_extension_t *extension = NULL((void*)0); |
8525 | |
8526 | /* build an extension name object */ |
8527 | if ((extension = switch_caller_extension_new(peer_session, conference_name, conference_name)) == 0) { |
8528 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 8528, (const char*)(session), SWITCH_LOG_CRIT, "Memory Error!\n"); |
8529 | status = SWITCH_STATUS_MEMERR; |
8530 | goto done; |
8531 | } |
8532 | |
8533 | if ((outcall_flags = switch_channel_get_variable(peer_channel, "outcall_flags")switch_channel_get_variable_dup(peer_channel, "outcall_flags" , SWITCH_TRUE, -1))) { |
8534 | if (!zstr(outcall_flags)_zstr(outcall_flags)) { |
8535 | flags = (char *)outcall_flags; |
8536 | } |
8537 | } |
8538 | |
8539 | if (flags && strcasecmp(flags, "none")) { |
8540 | have_flags = SWITCH_TRUE; |
8541 | } |
8542 | /* add them to the conference */ |
8543 | |
8544 | switch_snprintf(appdata, sizeof(appdata), "%s%s%s%s%s%s", conference_name, |
8545 | profile?"@":"", profile?profile:"", |
8546 | have_flags?"+flags{":"", have_flags?flags:"", have_flags?"}":""); |
8547 | switch_caller_extension_add_application(peer_session, extension, (char *) global_app_name, appdata); |
8548 | |
8549 | switch_channel_set_caller_extension(peer_channel, extension); |
8550 | switch_channel_set_state(peer_channel, CS_EXECUTE)switch_channel_perform_set_state(peer_channel, "mod_conference.c" , (const char *)__func__, 8550, CS_EXECUTE); |
8551 | |
8552 | } else { |
8553 | switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ANSWER)switch_channel_perform_hangup(peer_channel, "mod_conference.c" , (const char *)__func__, 8553, SWITCH_CAUSE_NO_ANSWER); |
8554 | status = SWITCH_STATUS_FALSE; |
8555 | goto done; |
8556 | } |
8557 | |
8558 | done: |
8559 | if (conference) { |
8560 | switch_thread_rwlock_unlock(conference->rwlock); |
8561 | } |
8562 | if (rdlock && peer_session) { |
8563 | switch_core_session_rwunlock(peer_session); |
8564 | } |
8565 | |
8566 | return status; |
8567 | } |
8568 | |
8569 | struct bg_call { |
8570 | conference_obj_t *conference; |
8571 | switch_core_session_t *session; |
8572 | char *bridgeto; |
8573 | uint32_t timeout; |
8574 | char *flags; |
8575 | char *cid_name; |
8576 | char *cid_num; |
8577 | char *conference_name; |
8578 | char *uuid; |
8579 | char *profile; |
8580 | switch_call_cause_t *cancel_cause; |
8581 | switch_event_t *var_event; |
8582 | switch_memory_pool_t *pool; |
8583 | }; |
8584 | |
8585 | static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread, void *obj) |
8586 | { |
8587 | struct bg_call *call = (struct bg_call *) obj; |
8588 | |
8589 | if (call) { |
8590 | switch_call_cause_t cause; |
8591 | switch_event_t *event; |
8592 | |
8593 | |
8594 | conference_outcall(call->conference, call->conference_name, |
8595 | call->session, call->bridgeto, call->timeout, |
8596 | call->flags, call->cid_name, call->cid_num, call->profile, &cause, call->cancel_cause, call->var_event); |
8597 | |
8598 | if (call->conference && test_eflag(call->conference, EFLAG_BGDIAL_RESULT)((call->conference)->eflags & EFLAG_BGDIAL_RESULT) && |
8599 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 8599, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
8600 | conference_add_event_data(call->conference, event); |
8601 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "bgdial-result"); |
8602 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Result", switch_channel_cause2str(cause)); |
8603 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-UUID", call->uuid); |
8604 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 8604, &event, ((void*)0)); |
8605 | } |
8606 | |
8607 | if (call->var_event) { |
8608 | switch_event_destroy(&call->var_event); |
8609 | } |
8610 | |
8611 | switch_safe_free(call->bridgeto)if (call->bridgeto) {free(call->bridgeto);call->bridgeto =((void*)0);}; |
8612 | switch_safe_free(call->flags)if (call->flags) {free(call->flags);call->flags=((void *)0);}; |
8613 | switch_safe_free(call->cid_name)if (call->cid_name) {free(call->cid_name);call->cid_name =((void*)0);}; |
8614 | switch_safe_free(call->cid_num)if (call->cid_num) {free(call->cid_num);call->cid_num =((void*)0);}; |
8615 | switch_safe_free(call->conference_name)if (call->conference_name) {free(call->conference_name) ;call->conference_name=((void*)0);}; |
8616 | switch_safe_free(call->uuid)if (call->uuid) {free(call->uuid);call->uuid=((void* )0);}; |
8617 | switch_safe_free(call->profile)if (call->profile) {free(call->profile);call->profile =((void*)0);}; |
8618 | if (call->pool) { |
8619 | switch_core_destroy_memory_pool(&call->pool)switch_core_perform_destroy_memory_pool(&call->pool, "mod_conference.c" , (const char *)__func__, 8619); |
8620 | } |
8621 | switch_safe_free(call)if (call) {free(call);call=((void*)0);}; |
8622 | } |
8623 | |
8624 | return NULL((void*)0); |
8625 | } |
8626 | |
8627 | static switch_status_t conference_outcall_bg(conference_obj_t *conference, |
8628 | char *conference_name, |
8629 | switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name, |
8630 | const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause, switch_event_t **var_event) |
8631 | { |
8632 | struct bg_call *call = NULL((void*)0); |
8633 | switch_thread_t *thread; |
8634 | switch_threadattr_t *thd_attr = NULL((void*)0); |
8635 | switch_memory_pool_t *pool = NULL((void*)0); |
8636 | |
8637 | if (!(call = malloc(sizeof(*call)))) |
8638 | return SWITCH_STATUS_MEMERR; |
8639 | |
8640 | memset(call, 0, sizeof(*call)); |
8641 | call->conference = conference; |
8642 | call->session = session; |
8643 | call->timeout = timeout; |
8644 | call->cancel_cause = cancel_cause; |
8645 | |
8646 | if (var_event) { |
8647 | call->var_event = *var_event; |
8648 | var_event = NULL((void*)0); |
8649 | } |
8650 | |
8651 | if (conference) { |
8652 | pool = conference->pool; |
8653 | } else { |
8654 | switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 8654); |
8655 | call->pool = pool; |
8656 | } |
8657 | |
8658 | if (bridgeto) { |
8659 | call->bridgeto = strdup(bridgeto)(__extension__ (__builtin_constant_p (bridgeto) && (( size_t)(const void *)((bridgeto) + 1) - (size_t)(const void * )(bridgeto) == 1) ? (((const char *) (bridgeto))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (bridgeto) + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , bridgeto, __len); __retval; })) : __strdup (bridgeto))); |
8660 | } |
8661 | if (flags) { |
8662 | call->flags = strdup(flags)(__extension__ (__builtin_constant_p (flags) && ((size_t )(const void *)((flags) + 1) - (size_t)(const void *)(flags) == 1) ? (((const char *) (flags))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen (flags) + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, flags, __len ); __retval; })) : __strdup (flags))); |
8663 | } |
8664 | if (cid_name) { |
8665 | call->cid_name = strdup(cid_name)(__extension__ (__builtin_constant_p (cid_name) && (( size_t)(const void *)((cid_name) + 1) - (size_t)(const void * )(cid_name) == 1) ? (((const char *) (cid_name))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (cid_name) + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , cid_name, __len); __retval; })) : __strdup (cid_name))); |
8666 | } |
8667 | if (cid_num) { |
8668 | call->cid_num = strdup(cid_num)(__extension__ (__builtin_constant_p (cid_num) && ((size_t )(const void *)((cid_num) + 1) - (size_t)(const void *)(cid_num ) == 1) ? (((const char *) (cid_num))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (cid_num ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, cid_num , __len); __retval; })) : __strdup (cid_num))); |
8669 | } |
8670 | |
8671 | if (conference_name) { |
8672 | call->conference_name = strdup(conference_name)(__extension__ (__builtin_constant_p (conference_name) && ((size_t)(const void *)((conference_name) + 1) - (size_t)(const void *)(conference_name) == 1) ? (((const char *) (conference_name ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (conference_name) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, conference_name, __len); __retval ; })) : __strdup (conference_name))); |
8673 | } |
8674 | |
8675 | if (call_uuid) { |
8676 | call->uuid = strdup(call_uuid)(__extension__ (__builtin_constant_p (call_uuid) && ( (size_t)(const void *)((call_uuid) + 1) - (size_t)(const void *)(call_uuid) == 1) ? (((const char *) (call_uuid))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (call_uuid) + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, call_uuid, __len); __retval; })) : __strdup (call_uuid ))); |
8677 | } |
8678 | |
8679 | if (profile) { |
8680 | call->profile = strdup(profile)(__extension__ (__builtin_constant_p (profile) && ((size_t )(const void *)((profile) + 1) - (size_t)(const void *)(profile ) == 1) ? (((const char *) (profile))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (profile ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, profile , __len); __retval; })) : __strdup (profile))); |
8681 | } |
8682 | |
8683 | switch_threadattr_create(&thd_attr, pool); |
8684 | switch_threadattr_detach_set(thd_attr, 1); |
8685 | switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024); |
8686 | switch_thread_create(&thread, thd_attr, conference_outcall_run, call, pool); |
8687 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 8687, (const char*)(session), SWITCH_LOG_DEBUG, "Launching BG Thread for outcall\n"); |
8688 | |
8689 | return SWITCH_STATUS_SUCCESS; |
8690 | } |
8691 | |
8692 | /* Play a file */ |
8693 | static switch_status_t conference_local_play_file(conference_obj_t *conference, switch_core_session_t *session, char *path, uint32_t leadin, void *buf, |
8694 | uint32_t buflen) |
8695 | { |
8696 | uint32_t x = 0; |
8697 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
8698 | switch_channel_t *channel; |
8699 | char *expanded = NULL((void*)0); |
8700 | switch_input_args_t args = { 0 }, *ap = NULL((void*)0); |
8701 | |
8702 | if (buf) { |
8703 | args.buf = buf; |
8704 | args.buflen = buflen; |
8705 | ap = &args; |
8706 | } |
8707 | |
8708 | /* generate some space infront of the file to be played */ |
8709 | for (x = 0; x < leadin; x++) { |
8710 | switch_frame_t *read_frame; |
8711 | status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); |
8712 | |
8713 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { |
8714 | break; |
8715 | } |
8716 | } |
8717 | |
8718 | /* if all is well, really play the file */ |
8719 | if (status == SWITCH_STATUS_SUCCESS) { |
8720 | char *dpath = NULL((void*)0); |
8721 | |
8722 | channel = switch_core_session_get_channel(session); |
8723 | if ((expanded = switch_channel_expand_variables(channel, path)switch_channel_expand_variables_check(channel, path, ((void*) 0), ((void*)0), 0)) != path) { |
8724 | path = expanded; |
8725 | } else { |
8726 | expanded = NULL((void*)0); |
8727 | } |
8728 | |
8729 | if (!strncasecmp(path, "say:", 4)) { |
8730 | if (!(conference->tts_engine && conference->tts_voice)) { |
8731 | status = SWITCH_STATUS_FALSE; |
8732 | } else { |
8733 | status = switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, path + 4, ap); |
8734 | } |
8735 | goto done; |
8736 | } |
8737 | |
8738 | if (!switch_is_file_path(path) && conference->sound_prefix) { |
8739 | if (!(dpath = switch_mprintf("%s%s%s", conference->sound_prefix, SWITCH_PATH_SEPARATOR"/", path))) { |
8740 | status = SWITCH_STATUS_MEMERR; |
8741 | goto done; |
8742 | } |
8743 | path = dpath; |
8744 | } |
8745 | |
8746 | status = switch_ivr_play_file(session, NULL((void*)0), path, ap); |
8747 | switch_safe_free(dpath)if (dpath) {free(dpath);dpath=((void*)0);}; |
8748 | } |
8749 | |
8750 | done: |
8751 | switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);}; |
8752 | |
8753 | return status; |
8754 | } |
8755 | |
8756 | static void set_mflags(const char *flags, member_flag_t *f) |
8757 | { |
8758 | if (flags) { |
8759 | char *dup = strdup(flags)(__extension__ (__builtin_constant_p (flags) && ((size_t )(const void *)((flags) + 1) - (size_t)(const void *)(flags) == 1) ? (((const char *) (flags))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen (flags) + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, flags, __len ); __retval; })) : __strdup (flags))); |
8760 | char *p; |
8761 | char *argv[10] = { 0 }; |
8762 | int i, argc = 0; |
8763 | |
8764 | *f |= MFLAG_CAN_SPEAK | MFLAG_CAN_HEAR; |
8765 | |
8766 | for (p = dup; p && *p; p++) { |
8767 | if (*p == ',') { |
8768 | *p = '|'; |
8769 | } |
8770 | } |
8771 | |
8772 | argc = switch_separate_string(dup, '|', argv, (sizeof(argv) / sizeof(argv[0]))); |
8773 | |
8774 | for (i = 0; i < argc && argv[i]; i++) { |
8775 | if (!strcasecmp(argv[i], "mute")) { |
8776 | *f &= ~MFLAG_CAN_SPEAK; |
8777 | *f &= ~MFLAG_TALKING; |
8778 | } else if (!strcasecmp(argv[i], "deaf")) { |
8779 | *f &= ~MFLAG_CAN_HEAR; |
8780 | } else if (!strcasecmp(argv[i], "mute-detect")) { |
8781 | *f |= MFLAG_MUTE_DETECT; |
8782 | } else if (!strcasecmp(argv[i], "dist-dtmf")) { |
8783 | *f |= MFLAG_DIST_DTMF; |
8784 | } else if (!strcasecmp(argv[i], "moderator")) { |
8785 | *f |= MFLAG_MOD; |
8786 | } else if (!strcasecmp(argv[i], "nomoh")) { |
8787 | *f |= MFLAG_NOMOH; |
8788 | } else if (!strcasecmp(argv[i], "endconf")) { |
8789 | *f |= MFLAG_ENDCONF; |
8790 | } else if (!strcasecmp(argv[i], "mintwo")) { |
8791 | *f |= MFLAG_MINTWO; |
8792 | } else if (!strcasecmp(argv[i], "video-bridge")) { |
8793 | *f |= MFLAG_VIDEO_BRIDGE; |
8794 | } else if (!strcasecmp(argv[i], "ghost")) { |
8795 | *f |= MFLAG_GHOST; |
8796 | } else if (!strcasecmp(argv[i], "join-only")) { |
8797 | *f |= MFLAG_JOIN_ONLY; |
8798 | } else if (!strcasecmp(argv[i], "positional")) { |
8799 | *f |= MFLAG_POSITIONAL; |
8800 | } else if (!strcasecmp(argv[i], "no-positional")) { |
8801 | *f |= MFLAG_NO_POSITIONAL; |
8802 | } |
8803 | } |
8804 | |
8805 | free(dup); |
8806 | } |
8807 | } |
8808 | |
8809 | |
8810 | |
8811 | static void set_cflags(const char *flags, uint32_t *f) |
8812 | { |
8813 | if (flags) { |
8814 | char *dup = strdup(flags)(__extension__ (__builtin_constant_p (flags) && ((size_t )(const void *)((flags) + 1) - (size_t)(const void *)(flags) == 1) ? (((const char *) (flags))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen (flags) + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, flags, __len ); __retval; })) : __strdup (flags))); |
8815 | char *p; |
8816 | char *argv[10] = { 0 }; |
8817 | int i, argc = 0; |
8818 | |
8819 | for (p = dup; p && *p; p++) { |
8820 | if (*p == ',') { |
8821 | *p = '|'; |
8822 | } |
8823 | } |
8824 | |
8825 | argc = switch_separate_string(dup, '|', argv, (sizeof(argv) / sizeof(argv[0]))); |
8826 | |
8827 | for (i = 0; i < argc && argv[i]; i++) { |
8828 | if (!strcasecmp(argv[i], "wait-mod")) { |
8829 | *f |= CFLAG_WAIT_MOD; |
8830 | } else if (!strcasecmp(argv[i], "video-floor-only")) { |
8831 | *f |= CFLAG_VID_FLOOR; |
8832 | } else if (!strcasecmp(argv[i], "video-bridge")) { |
8833 | *f |= CFLAG_VIDEO_BRIDGE; |
8834 | } else if (!strcasecmp(argv[i], "audio-always")) { |
8835 | *f |= CFLAG_AUDIO_ALWAYS; |
8836 | } else if (!strcasecmp(argv[i], "restart-auto-record")) { |
8837 | *f |= CFLAG_CONF_RESTART_AUTO_RECORD; |
8838 | } else if (!strcasecmp(argv[i], "json-events")) { |
8839 | *f |= CFLAG_JSON_EVENTS; |
8840 | } else if (!strcasecmp(argv[i], "livearray-sync")) { |
8841 | *f |= CFLAG_LIVEARRAY_SYNC; |
8842 | } else if (!strcasecmp(argv[i], "rfc-4579")) { |
8843 | *f |= CFLAG_RFC4579; |
8844 | } else if (!strcasecmp(argv[i], "auto-3d-position")) { |
8845 | *f |= CFLAG_POSITIONAL; |
8846 | } |
8847 | |
8848 | |
8849 | } |
8850 | |
8851 | free(dup); |
8852 | } |
8853 | } |
8854 | |
8855 | |
8856 | static void clear_eflags(char *events, uint32_t *f) |
8857 | { |
8858 | char buf[512] = ""; |
8859 | char *next = NULL((void*)0); |
8860 | char *event = buf; |
8861 | |
8862 | if (events) { |
8863 | switch_copy_string(buf, events, sizeof(buf)); |
8864 | |
8865 | while (event) { |
8866 | next = strchr(event, ',')(__extension__ (__builtin_constant_p (',') && !__builtin_constant_p (event) && (',') == '\0' ? (char *) __rawmemchr (event , ',') : __builtin_strchr (event, ','))); |
8867 | if (next) { |
8868 | *next++ = '\0'; |
8869 | } |
8870 | |
8871 | if (!strcmp(event, "add-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("add-member") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("add-member"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("add-member") + 1) - (size_t)(const void *)("add-member") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "add-member") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("add-member") && ((size_t)(const void *)(("add-member") + 1) - (size_t)(const void *)("add-member") == 1) ? __builtin_strcmp (event, "add-member" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("add-member"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("add-member") && ((size_t )(const void *)(("add-member") + 1) - (size_t)(const void *)( "add-member") == 1) && (__s2_len = __builtin_strlen ( "add-member"), __s2_len < 4) ? (__builtin_constant_p (event ) && ((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) ? __builtin_strcmp (event, "add-member" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("add-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("add-member"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("add-member"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("add-member"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "add-member")))); })) { |
8872 | *f &= ~EFLAG_ADD_MEMBER; |
8873 | } else if (!strcmp(event, "del-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("del-member") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("del-member"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("del-member") + 1) - (size_t)(const void *)("del-member") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "del-member") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("del-member") && ((size_t)(const void *)(("del-member") + 1) - (size_t)(const void *)("del-member") == 1) ? __builtin_strcmp (event, "del-member" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("del-member"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("del-member") && ((size_t )(const void *)(("del-member") + 1) - (size_t)(const void *)( "del-member") == 1) && (__s2_len = __builtin_strlen ( "del-member"), __s2_len < 4) ? (__builtin_constant_p (event ) && ((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) ? __builtin_strcmp (event, "del-member" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("del-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("del-member"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("del-member"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("del-member"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "del-member")))); })) { |
8874 | *f &= ~EFLAG_DEL_MEMBER; |
8875 | } else if (!strcmp(event, "energy-level")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("energy-level") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("energy-level"), (!((size_t)(const void *)((event) + 1) - ( size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("energy-level") + 1) - (size_t)(const void *)("energy-level") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "energy-level") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("energy-level") && ((size_t)(const void *)(("energy-level") + 1) - (size_t)(const void *)("energy-level") == 1) ? __builtin_strcmp (event, "energy-level" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("energy-level"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("energy-level") && (( size_t)(const void *)(("energy-level") + 1) - (size_t)(const void *)("energy-level") == 1) && (__s2_len = __builtin_strlen ("energy-level"), __s2_len < 4) ? (__builtin_constant_p ( event) && ((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) ? __builtin_strcmp (event, "energy-level" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("energy-level"))[0] - __s2[0]); if ( __s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("energy-level"))[1] - __s2[ 1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("energy-level")) [2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("energy-level" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event , "energy-level")))); })) { |
8876 | *f &= ~EFLAG_ENERGY_LEVEL; |
8877 | } else if (!strcmp(event, "volume-level")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("volume-level") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("volume-level"), (!((size_t)(const void *)((event) + 1) - ( size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("volume-level") + 1) - (size_t)(const void *)("volume-level") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "volume-level") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("volume-level") && ((size_t)(const void *)(("volume-level") + 1) - (size_t)(const void *)("volume-level") == 1) ? __builtin_strcmp (event, "volume-level" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("volume-level"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("volume-level") && (( size_t)(const void *)(("volume-level") + 1) - (size_t)(const void *)("volume-level") == 1) && (__s2_len = __builtin_strlen ("volume-level"), __s2_len < 4) ? (__builtin_constant_p ( event) && ((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) ? __builtin_strcmp (event, "volume-level" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("volume-level"))[0] - __s2[0]); if ( __s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("volume-level"))[1] - __s2[ 1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("volume-level")) [2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("volume-level" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event , "volume-level")))); })) { |
8878 | *f &= ~EFLAG_VOLUME_LEVEL; |
8879 | } else if (!strcmp(event, "gain-level")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("gain-level") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("gain-level"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("gain-level") + 1) - (size_t)(const void *)("gain-level") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "gain-level") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("gain-level") && ((size_t)(const void *)(("gain-level") + 1) - (size_t)(const void *)("gain-level") == 1) ? __builtin_strcmp (event, "gain-level" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("gain-level"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("gain-level") && ((size_t )(const void *)(("gain-level") + 1) - (size_t)(const void *)( "gain-level") == 1) && (__s2_len = __builtin_strlen ( "gain-level"), __s2_len < 4) ? (__builtin_constant_p (event ) && ((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) ? __builtin_strcmp (event, "gain-level" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("gain-level"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("gain-level"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("gain-level"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("gain-level"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "gain-level")))); })) { |
8880 | *f &= ~EFLAG_GAIN_LEVEL; |
8881 | } else if (!strcmp(event, "dtmf")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("dtmf") && ( __s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("dtmf"), (!((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) || __s1_len >= 4) && (! ((size_t)(const void *)(("dtmf") + 1) - (size_t)(const void * )("dtmf") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event , "dtmf") : (__builtin_constant_p (event) && ((size_t )(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("dtmf") && ((size_t )(const void *)(("dtmf") + 1) - (size_t)(const void *)("dtmf" ) == 1) ? __builtin_strcmp (event, "dtmf") : (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) ("dtmf"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("dtmf") && ((size_t)(const void *)(("dtmf") + 1) - ( size_t)(const void *)("dtmf") == 1) && (__s2_len = __builtin_strlen ("dtmf"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) ? __builtin_strcmp (event, "dtmf") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("dtmf"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("dtmf"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("dtmf"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("dtmf"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event, "dtmf")))); })) { |
8882 | *f &= ~EFLAG_DTMF; |
8883 | } else if (!strcmp(event, "stop-talking")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("stop-talking") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("stop-talking"), (!((size_t)(const void *)((event) + 1) - ( size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("stop-talking") + 1) - (size_t)(const void *)("stop-talking") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "stop-talking") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("stop-talking") && ((size_t)(const void *)(("stop-talking") + 1) - (size_t)(const void *)("stop-talking") == 1) ? __builtin_strcmp (event, "stop-talking" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("stop-talking"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("stop-talking") && (( size_t)(const void *)(("stop-talking") + 1) - (size_t)(const void *)("stop-talking") == 1) && (__s2_len = __builtin_strlen ("stop-talking"), __s2_len < 4) ? (__builtin_constant_p ( event) && ((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) ? __builtin_strcmp (event, "stop-talking" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("stop-talking"))[0] - __s2[0]); if ( __s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("stop-talking"))[1] - __s2[ 1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("stop-talking")) [2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("stop-talking" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event , "stop-talking")))); })) { |
8884 | *f &= ~EFLAG_STOP_TALKING; |
8885 | } else if (!strcmp(event, "start-talking")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("start-talking") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("start-talking"), (!((size_t)(const void *)((event) + 1) - ( size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("start-talking") + 1) - (size_t)( const void *)("start-talking") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "start-talking") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("start-talking") && ((size_t)(const void *)(("start-talking") + 1) - ( size_t)(const void *)("start-talking") == 1) ? __builtin_strcmp (event, "start-talking") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("start-talking" ); int __result = (((const unsigned char *) (const char *) (event ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (event) )[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "start-talking") && ((size_t)(const void *)(("start-talking" ) + 1) - (size_t)(const void *)("start-talking") == 1) && (__s2_len = __builtin_strlen ("start-talking"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) ? __builtin_strcmp (event, "start-talking") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("start-talking"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("start-talking"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("start-talking"))[2] - __s2[2]); if ( __s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("start-talking"))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (event, "start-talking" )))); })) { |
8886 | *f &= ~EFLAG_START_TALKING; |
8887 | } else if (!strcmp(event, "mute-detect")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("mute-detect") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("mute-detect"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("mute-detect") + 1) - (size_t)(const void *)("mute-detect") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "mute-detect") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("mute-detect") && ((size_t)(const void *)(("mute-detect") + 1) - (size_t)(const void *)("mute-detect") == 1) ? __builtin_strcmp (event, "mute-detect" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("mute-detect"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("mute-detect") && ((size_t )(const void *)(("mute-detect") + 1) - (size_t)(const void *) ("mute-detect") == 1) && (__s2_len = __builtin_strlen ("mute-detect"), __s2_len < 4) ? (__builtin_constant_p (event ) && ((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) ? __builtin_strcmp (event, "mute-detect" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("mute-detect"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("mute-detect"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("mute-detect"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("mute-detect"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "mute-detect")))); })) { |
8888 | *f &= ~EFLAG_MUTE_DETECT; |
8889 | } else if (!strcmp(event, "mute-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("mute-member") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("mute-member"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("mute-member") + 1) - (size_t)(const void *)("mute-member") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "mute-member") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("mute-member") && ((size_t)(const void *)(("mute-member") + 1) - (size_t)(const void *)("mute-member") == 1) ? __builtin_strcmp (event, "mute-member" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("mute-member"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("mute-member") && ((size_t )(const void *)(("mute-member") + 1) - (size_t)(const void *) ("mute-member") == 1) && (__s2_len = __builtin_strlen ("mute-member"), __s2_len < 4) ? (__builtin_constant_p (event ) && ((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) ? __builtin_strcmp (event, "mute-member" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("mute-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("mute-member"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("mute-member"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("mute-member"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "mute-member")))); })) { |
8890 | *f &= ~EFLAG_MUTE_MEMBER; |
8891 | } else if (!strcmp(event, "unmute-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("unmute-member") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("unmute-member"), (!((size_t)(const void *)((event) + 1) - ( size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("unmute-member") + 1) - (size_t)( const void *)("unmute-member") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "unmute-member") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("unmute-member") && ((size_t)(const void *)(("unmute-member") + 1) - ( size_t)(const void *)("unmute-member") == 1) ? __builtin_strcmp (event, "unmute-member") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("unmute-member" ); int __result = (((const unsigned char *) (const char *) (event ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (event) )[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "unmute-member") && ((size_t)(const void *)(("unmute-member" ) + 1) - (size_t)(const void *)("unmute-member") == 1) && (__s2_len = __builtin_strlen ("unmute-member"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) ? __builtin_strcmp (event, "unmute-member") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("unmute-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("unmute-member"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("unmute-member"))[2] - __s2[2]); if ( __s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("unmute-member"))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (event, "unmute-member" )))); })) { |
8892 | *f &= ~EFLAG_UNMUTE_MEMBER; |
8893 | } else if (!strcmp(event, "kick-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("kick-member") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("kick-member"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("kick-member") + 1) - (size_t)(const void *)("kick-member") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "kick-member") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("kick-member") && ((size_t)(const void *)(("kick-member") + 1) - (size_t)(const void *)("kick-member") == 1) ? __builtin_strcmp (event, "kick-member" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("kick-member"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("kick-member") && ((size_t )(const void *)(("kick-member") + 1) - (size_t)(const void *) ("kick-member") == 1) && (__s2_len = __builtin_strlen ("kick-member"), __s2_len < 4) ? (__builtin_constant_p (event ) && ((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) ? __builtin_strcmp (event, "kick-member" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("kick-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("kick-member"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("kick-member"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("kick-member"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "kick-member")))); })) { |
8894 | *f &= ~EFLAG_KICK_MEMBER; |
8895 | } else if (!strcmp(event, "dtmf-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("dtmf-member") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("dtmf-member"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("dtmf-member") + 1) - (size_t)(const void *)("dtmf-member") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "dtmf-member") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("dtmf-member") && ((size_t)(const void *)(("dtmf-member") + 1) - (size_t)(const void *)("dtmf-member") == 1) ? __builtin_strcmp (event, "dtmf-member" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("dtmf-member"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("dtmf-member") && ((size_t )(const void *)(("dtmf-member") + 1) - (size_t)(const void *) ("dtmf-member") == 1) && (__s2_len = __builtin_strlen ("dtmf-member"), __s2_len < 4) ? (__builtin_constant_p (event ) && ((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) ? __builtin_strcmp (event, "dtmf-member" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("dtmf-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("dtmf-member"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("dtmf-member"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("dtmf-member"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "dtmf-member")))); })) { |
8896 | *f &= ~EFLAG_DTMF_MEMBER; |
8897 | } else if (!strcmp(event, "energy-level-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("energy-level-member" ) && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("energy-level-member"), (!((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("energy-level-member" ) + 1) - (size_t)(const void *)("energy-level-member") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "energy-level-member" ) : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("energy-level-member") && ((size_t)(const void *)(( "energy-level-member") + 1) - (size_t)(const void *)("energy-level-member" ) == 1) ? __builtin_strcmp (event, "energy-level-member") : ( __extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("energy-level-member"); int __result = (( (const unsigned char *) (const char *) (event))[0] - __s2[0]) ; if (__s1_len > 0 && __result == 0) { __result = ( ((const unsigned char *) (const char *) (event))[1] - __s2[1] ); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[ 2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[ 3]); } } __result; }))) : (__builtin_constant_p ("energy-level-member" ) && ((size_t)(const void *)(("energy-level-member") + 1) - (size_t)(const void *)("energy-level-member") == 1) && (__s2_len = __builtin_strlen ("energy-level-member"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t) (const void *)((event) + 1) - (size_t)(const void *)(event) == 1) ? __builtin_strcmp (event, "energy-level-member") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("energy-level-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("energy-level-member"))[1] - __s2[1] ); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("energy-level-member" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("energy-level-member" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event , "energy-level-member")))); })) { |
8898 | *f &= ~EFLAG_ENERGY_LEVEL_MEMBER; |
8899 | } else if (!strcmp(event, "volume-in-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("volume-in-member") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("volume-in-member"), (!((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("volume-in-member") + 1) - (size_t )(const void *)("volume-in-member") == 1) || __s2_len >= 4 )) ? __builtin_strcmp (event, "volume-in-member") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("volume-in-member" ) && ((size_t)(const void *)(("volume-in-member") + 1 ) - (size_t)(const void *)("volume-in-member") == 1) ? __builtin_strcmp (event, "volume-in-member") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("volume-in-member" ); int __result = (((const unsigned char *) (const char *) (event ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (event) )[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "volume-in-member") && ((size_t)(const void *)(("volume-in-member" ) + 1) - (size_t)(const void *)("volume-in-member") == 1) && (__s2_len = __builtin_strlen ("volume-in-member"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) ? __builtin_strcmp (event, "volume-in-member") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("volume-in-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("volume-in-member"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("volume-in-member"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("volume-in-member"))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (event, "volume-in-member" )))); })) { |
8900 | *f &= ~EFLAG_VOLUME_IN_MEMBER; |
8901 | } else if (!strcmp(event, "volume-out-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("volume-out-member" ) && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("volume-out-member"), (!((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("volume-out-member" ) + 1) - (size_t)(const void *)("volume-out-member") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "volume-out-member" ) : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("volume-out-member") && ((size_t)(const void *)(("volume-out-member" ) + 1) - (size_t)(const void *)("volume-out-member") == 1) ? __builtin_strcmp (event, "volume-out-member") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("volume-out-member" ); int __result = (((const unsigned char *) (const char *) (event ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (event) )[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "volume-out-member") && ((size_t)(const void *)(("volume-out-member" ) + 1) - (size_t)(const void *)("volume-out-member") == 1) && (__s2_len = __builtin_strlen ("volume-out-member"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t) (const void *)((event) + 1) - (size_t)(const void *)(event) == 1) ? __builtin_strcmp (event, "volume-out-member") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("volume-out-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("volume-out-member"))[1] - __s2[1]); if ( __s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("volume-out-member"))[2] - __s2 [2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("volume-out-member" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event , "volume-out-member")))); })) { |
8902 | *f &= ~EFLAG_VOLUME_OUT_MEMBER; |
8903 | } else if (!strcmp(event, "play-file")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("play-file") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("play-file"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("play-file") + 1) - (size_t)(const void *)("play-file") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "play-file") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("play-file") && ((size_t)(const void *)(("play-file") + 1) - (size_t)(const void *)("play-file") == 1) ? __builtin_strcmp (event, "play-file" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("play-file"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("play-file") && ((size_t )(const void *)(("play-file") + 1) - (size_t)(const void *)("play-file" ) == 1) && (__s2_len = __builtin_strlen ("play-file") , __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) ? __builtin_strcmp (event, "play-file") : (- ( __extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("play-file"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("play-file"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("play-file"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("play-file"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "play-file")))); })) { |
8904 | *f &= ~EFLAG_PLAY_FILE; |
8905 | } else if (!strcmp(event, "play-file-done")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("play-file-done") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("play-file-done"), (!((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("play-file-done") + 1) - (size_t) (const void *)("play-file-done") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "play-file-done") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("play-file-done" ) && ((size_t)(const void *)(("play-file-done") + 1) - (size_t)(const void *)("play-file-done") == 1) ? __builtin_strcmp (event, "play-file-done") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("play-file-done" ); int __result = (((const unsigned char *) (const char *) (event ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (event) )[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "play-file-done") && ((size_t)(const void *)(("play-file-done" ) + 1) - (size_t)(const void *)("play-file-done") == 1) && (__s2_len = __builtin_strlen ("play-file-done"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) ? __builtin_strcmp (event, "play-file-done") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("play-file-done"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("play-file-done"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("play-file-done"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("play-file-done"))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (event, "play-file-done" )))); })) { |
8906 | *f &= ~EFLAG_PLAY_FILE; |
8907 | } else if (!strcmp(event, "play-file-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("play-file-member") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("play-file-member"), (!((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("play-file-member") + 1) - (size_t )(const void *)("play-file-member") == 1) || __s2_len >= 4 )) ? __builtin_strcmp (event, "play-file-member") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("play-file-member" ) && ((size_t)(const void *)(("play-file-member") + 1 ) - (size_t)(const void *)("play-file-member") == 1) ? __builtin_strcmp (event, "play-file-member") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("play-file-member" ); int __result = (((const unsigned char *) (const char *) (event ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (event) )[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "play-file-member") && ((size_t)(const void *)(("play-file-member" ) + 1) - (size_t)(const void *)("play-file-member") == 1) && (__s2_len = __builtin_strlen ("play-file-member"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) ? __builtin_strcmp (event, "play-file-member") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("play-file-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("play-file-member"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("play-file-member"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("play-file-member"))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (event, "play-file-member" )))); })) { |
8908 | *f &= ~EFLAG_PLAY_FILE_MEMBER; |
8909 | } else if (!strcmp(event, "speak-text")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("speak-text") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("speak-text"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("speak-text") + 1) - (size_t)(const void *)("speak-text") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "speak-text") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("speak-text") && ((size_t)(const void *)(("speak-text") + 1) - (size_t)(const void *)("speak-text") == 1) ? __builtin_strcmp (event, "speak-text" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("speak-text"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("speak-text") && ((size_t )(const void *)(("speak-text") + 1) - (size_t)(const void *)( "speak-text") == 1) && (__s2_len = __builtin_strlen ( "speak-text"), __s2_len < 4) ? (__builtin_constant_p (event ) && ((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) ? __builtin_strcmp (event, "speak-text" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("speak-text"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("speak-text"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("speak-text"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("speak-text"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "speak-text")))); })) { |
8910 | *f &= ~EFLAG_SPEAK_TEXT; |
8911 | } else if (!strcmp(event, "speak-text-member")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("speak-text-member" ) && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("speak-text-member"), (!((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("speak-text-member" ) + 1) - (size_t)(const void *)("speak-text-member") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "speak-text-member" ) : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("speak-text-member") && ((size_t)(const void *)(("speak-text-member" ) + 1) - (size_t)(const void *)("speak-text-member") == 1) ? __builtin_strcmp (event, "speak-text-member") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("speak-text-member" ); int __result = (((const unsigned char *) (const char *) (event ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (event) )[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "speak-text-member") && ((size_t)(const void *)(("speak-text-member" ) + 1) - (size_t)(const void *)("speak-text-member") == 1) && (__s2_len = __builtin_strlen ("speak-text-member"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t) (const void *)((event) + 1) - (size_t)(const void *)(event) == 1) ? __builtin_strcmp (event, "speak-text-member") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("speak-text-member"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("speak-text-member"))[1] - __s2[1]); if ( __s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("speak-text-member"))[2] - __s2 [2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("speak-text-member" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event , "speak-text-member")))); })) { |
8912 | *f &= ~EFLAG_SPEAK_TEXT_MEMBER; |
8913 | } else if (!strcmp(event, "lock")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("lock") && ( __s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("lock"), (!((size_t)(const void *)((event) + 1) - (size_t)( const void *)(event) == 1) || __s1_len >= 4) && (! ((size_t)(const void *)(("lock") + 1) - (size_t)(const void * )("lock") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event , "lock") : (__builtin_constant_p (event) && ((size_t )(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("lock") && ((size_t )(const void *)(("lock") + 1) - (size_t)(const void *)("lock" ) == 1) ? __builtin_strcmp (event, "lock") : (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) ("lock"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("lock") && ((size_t)(const void *)(("lock") + 1) - ( size_t)(const void *)("lock") == 1) && (__s2_len = __builtin_strlen ("lock"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) ? __builtin_strcmp (event, "lock") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("lock"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("lock"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("lock"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("lock"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event, "lock")))); })) { |
8914 | *f &= ~EFLAG_LOCK; |
8915 | } else if (!strcmp(event, "unlock")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("unlock") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("unlock"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("unlock") + 1) - (size_t)(const void *)("unlock") == 1) || __s2_len >= 4)) ? __builtin_strcmp ( event, "unlock") : (__builtin_constant_p (event) && ( (size_t)(const void *)((event) + 1) - (size_t)(const void *)( event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("unlock") && ((size_t)(const void *)(("unlock") + 1) - (size_t)(const void *)("unlock") == 1) ? __builtin_strcmp (event, "unlock") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("unlock"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("unlock") && ((size_t)(const void *)(("unlock") + 1 ) - (size_t)(const void *)("unlock") == 1) && (__s2_len = __builtin_strlen ("unlock"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) ? __builtin_strcmp (event, "unlock" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("unlock"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("unlock"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("unlock"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("unlock"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "unlock")))); })) { |
8916 | *f &= ~EFLAG_UNLOCK; |
8917 | } else if (!strcmp(event, "transfer")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("transfer") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("transfer"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("transfer") + 1) - (size_t)(const void *)("transfer") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "transfer") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("transfer") && ((size_t)(const void *)(("transfer") + 1) - (size_t)(const void *)("transfer") == 1) ? __builtin_strcmp (event, "transfer") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("transfer"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("transfer") && ((size_t )(const void *)(("transfer") + 1) - (size_t)(const void *)("transfer" ) == 1) && (__s2_len = __builtin_strlen ("transfer"), __s2_len < 4) ? (__builtin_constant_p (event) && ( (size_t)(const void *)((event) + 1) - (size_t)(const void *)( event) == 1) ? __builtin_strcmp (event, "transfer") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("transfer"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("transfer"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("transfer"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("transfer"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event, "transfer")))); })) { |
8918 | *f &= ~EFLAG_TRANSFER; |
8919 | } else if (!strcmp(event, "bgdial-result")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("bgdial-result") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("bgdial-result"), (!((size_t)(const void *)((event) + 1) - ( size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("bgdial-result") + 1) - (size_t)( const void *)("bgdial-result") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "bgdial-result") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("bgdial-result") && ((size_t)(const void *)(("bgdial-result") + 1) - ( size_t)(const void *)("bgdial-result") == 1) ? __builtin_strcmp (event, "bgdial-result") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("bgdial-result" ); int __result = (((const unsigned char *) (const char *) (event ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (event ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (event) )[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "bgdial-result") && ((size_t)(const void *)(("bgdial-result" ) + 1) - (size_t)(const void *)("bgdial-result") == 1) && (__s2_len = __builtin_strlen ("bgdial-result"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void *)(event) == 1) ? __builtin_strcmp (event, "bgdial-result") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("bgdial-result"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("bgdial-result"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("bgdial-result"))[2] - __s2[2]); if ( __s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("bgdial-result"))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (event, "bgdial-result" )))); })) { |
8920 | *f &= ~EFLAG_BGDIAL_RESULT; |
8921 | } else if (!strcmp(event, "floor-change")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("floor-change") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("floor-change"), (!((size_t)(const void *)((event) + 1) - ( size_t)(const void *)(event) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("floor-change") + 1) - (size_t)(const void *)("floor-change") == 1) || __s2_len >= 4)) ? __builtin_strcmp (event, "floor-change") : (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t)(const void * )(event) == 1) && (__s1_len = __builtin_strlen (event ), __s1_len < 4) ? (__builtin_constant_p ("floor-change") && ((size_t)(const void *)(("floor-change") + 1) - (size_t)(const void *)("floor-change") == 1) ? __builtin_strcmp (event, "floor-change" ) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("floor-change"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if ( __s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("floor-change") && (( size_t)(const void *)(("floor-change") + 1) - (size_t)(const void *)("floor-change") == 1) && (__s2_len = __builtin_strlen ("floor-change"), __s2_len < 4) ? (__builtin_constant_p ( event) && ((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) ? __builtin_strcmp (event, "floor-change" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("floor-change"))[0] - __s2[0]); if ( __s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("floor-change"))[1] - __s2[ 1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("floor-change")) [2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("floor-change" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (event , "floor-change")))); })) { |
8922 | *f &= ~EFLAG_FLOOR_CHANGE; |
8923 | } else if (!strcmp(event, "record")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (event) && __builtin_constant_p ("record") && (__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen ("record"), (!((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)(("record") + 1) - (size_t)(const void *)("record") == 1) || __s2_len >= 4)) ? __builtin_strcmp ( event, "record") : (__builtin_constant_p (event) && ( (size_t)(const void *)((event) + 1) - (size_t)(const void *)( event) == 1) && (__s1_len = __builtin_strlen (event), __s1_len < 4) ? (__builtin_constant_p ("record") && ((size_t)(const void *)(("record") + 1) - (size_t)(const void *)("record") == 1) ? __builtin_strcmp (event, "record") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("record"); int __result = (((const unsigned char *) (const char *) (event))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (event))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (event))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("record") && ((size_t)(const void *)(("record") + 1 ) - (size_t)(const void *)("record") == 1) && (__s2_len = __builtin_strlen ("record"), __s2_len < 4) ? (__builtin_constant_p (event) && ((size_t)(const void *)((event) + 1) - (size_t )(const void *)(event) == 1) ? __builtin_strcmp (event, "record" ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (event); int __result = (((const unsigned char *) (const char *) ("record"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("record"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("record"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("record"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (event, "record")))); })) { |
8924 | *f &= ~EFLAG_RECORD; |
8925 | } |
8926 | |
8927 | event = next; |
8928 | } |
8929 | } |
8930 | } |
8931 | |
8932 | SWITCH_STANDARD_APP(conference_auto_function)static void conference_auto_function (switch_core_session_t * session, const char *data) |
8933 | { |
8934 | switch_channel_t *channel = switch_core_session_get_channel(session); |
8935 | call_list_t *call_list, *np; |
8936 | |
8937 | call_list = switch_channel_get_private(channel, "_conference_autocall_list_"); |
8938 | |
8939 | if (zstr(data)_zstr(data)) { |
8940 | call_list = NULL((void*)0); |
8941 | } else { |
8942 | np = switch_core_session_alloc(session, sizeof(*np))switch_core_perform_session_alloc(session, sizeof(*np), "mod_conference.c" , (const char *)__func__, 8942); |
8943 | switch_assert(np != NULL)((np != ((void*)0)) ? (void) (0) : __assert_fail ("np != ((void*)0)" , "mod_conference.c", 8943, __PRETTY_FUNCTION__)); |
8944 | |
8945 | np->string = switch_core_session_strdup(session, data)switch_core_perform_session_strdup(session, data, "mod_conference.c" , (const char *)__func__, 8945); |
8946 | if (call_list) { |
8947 | np->next = call_list; |
8948 | np->iteration = call_list->iteration + 1; |
8949 | } else { |
8950 | np->iteration = 1; |
8951 | } |
8952 | call_list = np; |
8953 | } |
8954 | switch_channel_set_private(channel, "_conference_autocall_list_", call_list); |
8955 | } |
8956 | |
8957 | |
8958 | static int setup_media(conference_member_t *member, conference_obj_t *conference) |
8959 | { |
8960 | switch_codec_implementation_t read_impl = { 0 }; |
8961 | switch_core_session_get_read_impl(member->session, &read_impl); |
8962 | |
8963 | if (switch_core_codec_ready(&member->read_codec)) { |
8964 | switch_core_codec_destroy(&member->read_codec); |
8965 | memset(&member->read_codec, 0, sizeof(member->read_codec)); |
8966 | } |
8967 | |
8968 | if (switch_core_codec_ready(&member->write_codec)) { |
8969 | switch_core_codec_destroy(&member->write_codec); |
8970 | memset(&member->write_codec, 0, sizeof(member->write_codec)); |
8971 | } |
8972 | |
8973 | if (member->read_resampler) { |
8974 | switch_resample_destroy(&member->read_resampler); |
8975 | } |
8976 | |
8977 | |
8978 | switch_core_session_get_read_impl(member->session, &member->orig_read_impl); |
8979 | member->native_rate = read_impl.samples_per_second; |
8980 | |
8981 | /* Setup a Signed Linear codec for reading audio. */ |
8982 | if (switch_core_codec_init(&member->read_codec,switch_core_codec_init_with_bitrate(&member->read_codec , "L16", ((void*)0), read_impl.actual_samples_per_second, read_impl .microseconds_per_packet / 1000, read_impl.number_of_channels , 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void *)0), member->pool) |
8983 | "L16",switch_core_codec_init_with_bitrate(&member->read_codec , "L16", ((void*)0), read_impl.actual_samples_per_second, read_impl .microseconds_per_packet / 1000, read_impl.number_of_channels , 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void *)0), member->pool) |
8984 | NULL, read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&member->read_codec , "L16", ((void*)0), read_impl.actual_samples_per_second, read_impl .microseconds_per_packet / 1000, read_impl.number_of_channels , 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void *)0), member->pool) |
8985 | read_impl.number_of_channels,switch_core_codec_init_with_bitrate(&member->read_codec , "L16", ((void*)0), read_impl.actual_samples_per_second, read_impl .microseconds_per_packet / 1000, read_impl.number_of_channels , 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void *)0), member->pool) |
8986 | SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member->pool)switch_core_codec_init_with_bitrate(&member->read_codec , "L16", ((void*)0), read_impl.actual_samples_per_second, read_impl .microseconds_per_packet / 1000, read_impl.number_of_channels , 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void *)0), member->pool) == SWITCH_STATUS_SUCCESS) { |
8987 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 8987, (const char*)(member->session), SWITCH_LOG_DEBUG, |
8988 | "Raw Codec Activation Success L16@%uhz %d channel %dms\n", |
8989 | read_impl.actual_samples_per_second, read_impl.number_of_channels, read_impl.microseconds_per_packet / 1000); |
8990 | |
8991 | } else { |
8992 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 8992, (const char*)(member->session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz %d channel %dms\n", |
8993 | read_impl.actual_samples_per_second, read_impl.number_of_channels, read_impl.microseconds_per_packet / 1000); |
8994 | |
8995 | goto done; |
8996 | } |
8997 | |
8998 | if (!member->frame_size) { |
8999 | member->frame_size = SWITCH_RECOMMENDED_BUFFER_SIZE8192; |
9000 | member->frame = switch_core_alloc(member->pool, member->frame_size)switch_core_perform_alloc(member->pool, member->frame_size , "mod_conference.c", (const char *)__func__, 9000); |
9001 | member->mux_frame = switch_core_alloc(member->pool, member->frame_size)switch_core_perform_alloc(member->pool, member->frame_size , "mod_conference.c", (const char *)__func__, 9001); |
9002 | } |
9003 | |
9004 | if (read_impl.actual_samples_per_second != conference->rate) { |
9005 | if (switch_resample_create(&member->read_resampler,switch_resample_perform_create(&member->read_resampler , read_impl.actual_samples_per_second, conference->rate, member ->frame_size, 2, read_impl.number_of_channels, "mod_conference.c" , (const char *)__func__, 9007) |
9006 | read_impl.actual_samples_per_second,switch_resample_perform_create(&member->read_resampler , read_impl.actual_samples_per_second, conference->rate, member ->frame_size, 2, read_impl.number_of_channels, "mod_conference.c" , (const char *)__func__, 9007) |
9007 | conference->rate, member->frame_size, SWITCH_RESAMPLE_QUALITY, read_impl.number_of_channels)switch_resample_perform_create(&member->read_resampler , read_impl.actual_samples_per_second, conference->rate, member ->frame_size, 2, read_impl.number_of_channels, "mod_conference.c" , (const char *)__func__, 9007) != SWITCH_STATUS_SUCCESS) { |
9008 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9008, (const char*)(member->session), SWITCH_LOG_CRIT, "Unable to create resampler!\n"); |
9009 | goto done; |
9010 | } |
9011 | |
9012 | |
9013 | member->resample_out = switch_core_alloc(member->pool, member->frame_size)switch_core_perform_alloc(member->pool, member->frame_size , "mod_conference.c", (const char *)__func__, 9013); |
9014 | member->resample_out_len = member->frame_size; |
9015 | |
9016 | /* Setup an audio buffer for the resampled audio */ |
9017 | if (switch_buffer_create_dynamic(&member->resample_buffer, CONF_DBLOCK_SIZE1024 * 128, CONF_DBUFFER_SIZE1024 * 128, CONF_DBUFFER_MAX0) |
9018 | != SWITCH_STATUS_SUCCESS) { |
9019 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9019, (const char*)(member->session), SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); |
9020 | goto done; |
9021 | } |
9022 | } |
9023 | |
9024 | |
9025 | /* Setup a Signed Linear codec for writing audio. */ |
9026 | if (switch_core_codec_init(&member->write_codec,switch_core_codec_init_with_bitrate(&member->write_codec , "L16", ((void*)0), conference->rate, read_impl.microseconds_per_packet / 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), member->pool) |
9027 | "L16",switch_core_codec_init_with_bitrate(&member->write_codec , "L16", ((void*)0), conference->rate, read_impl.microseconds_per_packet / 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), member->pool) |
9028 | NULL,switch_core_codec_init_with_bitrate(&member->write_codec , "L16", ((void*)0), conference->rate, read_impl.microseconds_per_packet / 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), member->pool) |
9029 | conference->rate,switch_core_codec_init_with_bitrate(&member->write_codec , "L16", ((void*)0), conference->rate, read_impl.microseconds_per_packet / 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), member->pool) |
9030 | read_impl.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&member->write_codec , "L16", ((void*)0), conference->rate, read_impl.microseconds_per_packet / 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), member->pool) |
9031 | read_impl.number_of_channels,switch_core_codec_init_with_bitrate(&member->write_codec , "L16", ((void*)0), conference->rate, read_impl.microseconds_per_packet / 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), member->pool) |
9032 | SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member->pool)switch_core_codec_init_with_bitrate(&member->write_codec , "L16", ((void*)0), conference->rate, read_impl.microseconds_per_packet / 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void*)0), member->pool) == SWITCH_STATUS_SUCCESS) { |
9033 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9033, (const char*)(member->session), SWITCH_LOG_DEBUG, |
9034 | "Raw Codec Activation Success L16@%uhz %d channel %dms\n", |
9035 | conference->rate, conference->channels, read_impl.microseconds_per_packet / 1000); |
9036 | } else { |
9037 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9037, (const char*)(member->session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz %d channel %dms\n", |
9038 | conference->rate, conference->channels, read_impl.microseconds_per_packet / 1000); |
9039 | goto codec_done2; |
9040 | } |
9041 | |
9042 | /* Setup an audio buffer for the incoming audio */ |
9043 | if (switch_buffer_create_dynamic(&member->audio_buffer, CONF_DBLOCK_SIZE1024 * 128, CONF_DBUFFER_SIZE1024 * 128, CONF_DBUFFER_MAX0) != SWITCH_STATUS_SUCCESS) { |
9044 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9044, (const char*)(member->session), SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); |
9045 | goto codec_done1; |
9046 | } |
9047 | |
9048 | /* Setup an audio buffer for the outgoing audio */ |
9049 | if (switch_buffer_create_dynamic(&member->mux_buffer, CONF_DBLOCK_SIZE1024 * 128, CONF_DBUFFER_SIZE1024 * 128, CONF_DBUFFER_MAX0) != SWITCH_STATUS_SUCCESS) { |
9050 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9050, (const char*)(member->session), SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); |
9051 | goto codec_done1; |
9052 | } |
9053 | |
9054 | return 0; |
9055 | |
9056 | codec_done1: |
9057 | switch_core_codec_destroy(&member->read_codec); |
9058 | codec_done2: |
9059 | switch_core_codec_destroy(&member->write_codec); |
9060 | done: |
9061 | |
9062 | return -1; |
9063 | |
9064 | |
9065 | } |
9066 | |
9067 | #define validate_pin(buf, pin, mpin)pin_valid = (!_zstr(pin) && __extension__ ({ size_t __s1_len , __s2_len; (__builtin_constant_p (buf) && __builtin_constant_p (pin) && (__s1_len = __builtin_strlen (buf), __s2_len = __builtin_strlen (pin), (!((size_t)(const void *)((buf) + 1 ) - (size_t)(const void *)(buf) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((pin) + 1) - (size_t)(const void * )(pin) == 1) || __s2_len >= 4)) ? __builtin_strcmp (buf, pin ) : (__builtin_constant_p (buf) && ((size_t)(const void *)((buf) + 1) - (size_t)(const void *)(buf) == 1) && (__s1_len = __builtin_strlen (buf), __s1_len < 4) ? (__builtin_constant_p (pin) && ((size_t)(const void *)((pin) + 1) - (size_t )(const void *)(pin) == 1) ? __builtin_strcmp (buf, pin) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pin); int __result = (((const unsigned char *) (const char *) (buf))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (buf))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (buf))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (buf))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (pin) && ((size_t)(const void *)((pin) + 1) - (size_t )(const void *)(pin) == 1) && (__s2_len = __builtin_strlen (pin), __s2_len < 4) ? (__builtin_constant_p (buf) && ((size_t)(const void *)((buf) + 1) - (size_t)(const void *)( buf) == 1) ? __builtin_strcmp (buf, pin) : (- (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (buf); int __result = (((const unsigned char *) (const char *) (pin))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( pin))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (pin))[ 3] - __s2[3]); } } __result; })))) : __builtin_strcmp (buf, pin )))); }) == 0); if (!pin_valid && !_zstr(mpin) && __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (buf) && __builtin_constant_p (mpin) && (__s1_len = __builtin_strlen (buf), __s2_len = __builtin_strlen (mpin) , (!((size_t)(const void *)((buf) + 1) - (size_t)(const void * )(buf) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((mpin) + 1) - (size_t)(const void *)(mpin) == 1) || __s2_len >= 4)) ? __builtin_strcmp (buf, mpin) : (__builtin_constant_p (buf) && ((size_t)(const void *)((buf) + 1) - (size_t )(const void *)(buf) == 1) && (__s1_len = __builtin_strlen (buf), __s1_len < 4) ? (__builtin_constant_p (mpin) && ((size_t)(const void *)((mpin) + 1) - (size_t)(const void *) (mpin) == 1) ? __builtin_strcmp (buf, mpin) : (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (mpin); int __result = (((const unsigned char *) (const char *) (buf))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( buf))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (buf ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (buf))[ 3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (mpin ) && ((size_t)(const void *)((mpin) + 1) - (size_t)(const void *)(mpin) == 1) && (__s2_len = __builtin_strlen ( mpin), __s2_len < 4) ? (__builtin_constant_p (buf) && ((size_t)(const void *)((buf) + 1) - (size_t)(const void *)( buf) == 1) ? __builtin_strcmp (buf, mpin) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (buf); int __result = (((const unsigned char *) (const char *) (mpin))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (mpin))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (mpin))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (mpin))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (buf, mpin)))); }) == 0) { switch_log_printf(SWITCH_CHANNEL_ID_SESSION , "mod_conference.c", (const char *)__func__, 9067, (const char *)(session), SWITCH_LOG_DEBUG, "Moderator PIN found!\n"); pin_valid = 1; mpin_matched = 1; } \ |
9068 | pin_valid = (!zstr(pin)_zstr(pin) && strcmp(buf, pin)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (buf) && __builtin_constant_p (pin) && (__s1_len = __builtin_strlen (buf), __s2_len = __builtin_strlen (pin), (!((size_t)(const void *)((buf) + 1) - (size_t)(const void * )(buf) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((pin) + 1) - (size_t)(const void *)(pin) == 1) || __s2_len >= 4)) ? __builtin_strcmp (buf, pin) : (__builtin_constant_p (buf) && ((size_t)(const void *)((buf) + 1) - (size_t )(const void *)(buf) == 1) && (__s1_len = __builtin_strlen (buf), __s1_len < 4) ? (__builtin_constant_p (pin) && ((size_t)(const void *)((pin) + 1) - (size_t)(const void *)( pin) == 1) ? __builtin_strcmp (buf, pin) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pin); int __result = (((const unsigned char *) (const char * ) (buf))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( buf))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (buf ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (buf))[ 3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (pin ) && ((size_t)(const void *)((pin) + 1) - (size_t)(const void *)(pin) == 1) && (__s2_len = __builtin_strlen ( pin), __s2_len < 4) ? (__builtin_constant_p (buf) && ((size_t)(const void *)((buf) + 1) - (size_t)(const void *)( buf) == 1) ? __builtin_strcmp (buf, pin) : (- (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (buf); int __result = (((const unsigned char *) (const char *) (pin))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( pin))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (pin))[ 3] - __s2[3]); } } __result; })))) : __builtin_strcmp (buf, pin )))); }) == 0); \ |
9069 | if (!pin_valid && !zstr(mpin)_zstr(mpin) && strcmp(buf, mpin)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (buf) && __builtin_constant_p (mpin) && (__s1_len = __builtin_strlen (buf), __s2_len = __builtin_strlen (mpin) , (!((size_t)(const void *)((buf) + 1) - (size_t)(const void * )(buf) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((mpin) + 1) - (size_t)(const void *)(mpin) == 1) || __s2_len >= 4)) ? __builtin_strcmp (buf, mpin) : (__builtin_constant_p (buf) && ((size_t)(const void *)((buf) + 1) - (size_t )(const void *)(buf) == 1) && (__s1_len = __builtin_strlen (buf), __s1_len < 4) ? (__builtin_constant_p (mpin) && ((size_t)(const void *)((mpin) + 1) - (size_t)(const void *) (mpin) == 1) ? __builtin_strcmp (buf, mpin) : (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (mpin); int __result = (((const unsigned char *) (const char *) (buf))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( buf))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (buf ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (buf))[ 3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (mpin ) && ((size_t)(const void *)((mpin) + 1) - (size_t)(const void *)(mpin) == 1) && (__s2_len = __builtin_strlen ( mpin), __s2_len < 4) ? (__builtin_constant_p (buf) && ((size_t)(const void *)((buf) + 1) - (size_t)(const void *)( buf) == 1) ? __builtin_strcmp (buf, mpin) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (buf); int __result = (((const unsigned char *) (const char *) (mpin))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (mpin))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (mpin))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (mpin))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (buf, mpin)))); }) == 0) { \ |
9070 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9070, (const char*)(session), SWITCH_LOG_DEBUG, "Moderator PIN found!\n"); \ |
9071 | pin_valid = 1; \ |
9072 | mpin_matched = 1; \ |
9073 | } |
9074 | /* Application interface function that is called from the dialplan to join the channel to a conference */ |
9075 | SWITCH_STANDARD_APP(conference_function)static void conference_function (switch_core_session_t *session , const char *data) |
9076 | { |
9077 | switch_codec_t *read_codec = NULL((void*)0); |
9078 | //uint32_t flags = 0; |
9079 | conference_member_t member = { 0 }; |
9080 | conference_obj_t *conference = NULL((void*)0); |
9081 | switch_channel_t *channel = switch_core_session_get_channel(session); |
9082 | char *mydata = NULL((void*)0); |
9083 | char *conf_name = NULL((void*)0); |
9084 | char *bridge_prefix = "bridge:"; |
9085 | char *flags_prefix = "+flags{"; |
9086 | char *bridgeto = NULL((void*)0); |
9087 | char *profile_name = NULL((void*)0); |
9088 | switch_xml_t cxml = NULL((void*)0), cfg = NULL((void*)0), profiles = NULL((void*)0); |
9089 | const char *flags_str, *v_flags_str; |
9090 | const char *cflags_str, *v_cflags_str; |
9091 | member_flag_t mflags = 0; |
9092 | switch_core_session_message_t msg = { 0 }; |
9093 | uint8_t rl = 0, isbr = 0; |
9094 | char *dpin = ""; |
9095 | const char *mdpin = ""; |
9096 | conf_xml_cfg_t xml_cfg = { 0 }; |
9097 | switch_event_t *params = NULL((void*)0); |
9098 | int locked = 0; |
9099 | int mpin_matched = 0; |
9100 | uint32_t *mid; |
9101 | |
9102 | if (!switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_DONE) && |
9103 | (switch_channel_test_flag(channel, CF_RECOVERED) || switch_true(switch_channel_get_variable(channel, "conference_silent_entry")switch_channel_get_variable_dup(channel, "conference_silent_entry" , SWITCH_TRUE, -1)))) { |
9104 | switch_channel_set_app_flag_key("conf_silent", channel, CONF_SILENT_REQ); |
9105 | } |
9106 | |
9107 | switch_core_session_video_reset(session); |
9108 | |
9109 | switch_channel_set_flag(channel, CF_CONFERENCE)switch_channel_set_flag_value(channel, CF_CONFERENCE, 1); |
9110 | switch_channel_set_flag(channel, CF_VIDEO_PASSIVE)switch_channel_set_flag_value(channel, CF_VIDEO_PASSIVE, 1); |
9111 | |
9112 | |
9113 | if (switch_channel_answer(channel)switch_channel_perform_answer(channel, "mod_conference.c", (const char *)__func__, 9113) != SWITCH_STATUS_SUCCESS) { |
9114 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9114, (const char*)(session), SWITCH_LOG_ERROR, "Channel answer failed.\n"); |
9115 | goto end; |
9116 | } |
9117 | |
9118 | /* Save the original read codec. */ |
9119 | if (!(read_codec = switch_core_session_get_read_codec(session))) { |
9120 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9120, (const char*)(session), SWITCH_LOG_ERROR, "Channel has no media!\n"); |
9121 | goto end; |
9122 | } |
9123 | |
9124 | |
9125 | if (zstr(data)_zstr(data)) { |
9126 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9126, (const char*)(session), SWITCH_LOG_CRIT, "Invalid arguments\n"); |
9127 | goto end; |
9128 | } |
9129 | |
9130 | mydata = switch_core_session_strdup(session, data)switch_core_perform_session_strdup(session, data, "mod_conference.c" , (const char *)__func__, 9130); |
9131 | |
9132 | if (!mydata) { |
9133 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9133, (const char*)(session), SWITCH_LOG_CRIT, "Pool Failure\n"); |
9134 | goto end; |
9135 | } |
9136 | |
9137 | if ((flags_str = strstr(mydata, flags_prefix))) { |
9138 | char *p; |
9139 | *((char *) flags_str) = '\0'; |
9140 | flags_str += strlen(flags_prefix); |
9141 | if ((p = strchr(flags_str, '}')(__extension__ (__builtin_constant_p ('}') && !__builtin_constant_p (flags_str) && ('}') == '\0' ? (char *) __rawmemchr ( flags_str, '}') : __builtin_strchr (flags_str, '}'))))) { |
9142 | *p = '\0'; |
9143 | } |
9144 | } |
9145 | |
9146 | if ((v_flags_str = switch_channel_get_variable(channel, "conference_member_flags")switch_channel_get_variable_dup(channel, "conference_member_flags" , SWITCH_TRUE, -1))) { |
9147 | if (zstr(flags_str)_zstr(flags_str)) { |
9148 | flags_str = v_flags_str; |
9149 | } else { |
9150 | flags_str = switch_core_session_sprintf(session, "%s|%s", flags_str, v_flags_str); |
9151 | } |
9152 | } |
9153 | |
9154 | cflags_str = flags_str; |
9155 | |
9156 | if ((v_cflags_str = switch_channel_get_variable(channel, "conference_flags")switch_channel_get_variable_dup(channel, "conference_flags", SWITCH_TRUE , -1))) { |
9157 | if (zstr(cflags_str)_zstr(cflags_str)) { |
9158 | cflags_str = v_cflags_str; |
9159 | } else { |
9160 | cflags_str = switch_core_session_sprintf(session, "%s|%s", cflags_str, v_cflags_str); |
9161 | } |
9162 | } |
9163 | |
9164 | /* is this a bridging conference ? */ |
9165 | if (!strncasecmp(mydata, bridge_prefix, strlen(bridge_prefix))) { |
9166 | isbr = 1; |
9167 | mydata += strlen(bridge_prefix); |
9168 | if ((bridgeto = strchr(mydata, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p (mydata) && (':') == '\0' ? (char *) __rawmemchr (mydata , ':') : __builtin_strchr (mydata, ':'))))) { |
9169 | *bridgeto++ = '\0'; |
9170 | } else { |
9171 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9171, (const char*)(session), SWITCH_LOG_CRIT, "Config Error!\n"); |
9172 | goto done; |
9173 | } |
9174 | } |
9175 | |
9176 | conf_name = mydata; |
9177 | |
9178 | /* eat all leading spaces on conference name, which can cause problems */ |
9179 | while (*conf_name == ' ') { |
9180 | conf_name++; |
9181 | } |
9182 | |
9183 | /* is there a conference pin ? */ |
9184 | if ((dpin = strchr(conf_name, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p (conf_name) && ('+') == '\0' ? (char *) __rawmemchr ( conf_name, '+') : __builtin_strchr (conf_name, '+'))))) { |
9185 | *dpin++ = '\0'; |
9186 | } else dpin = ""; |
9187 | |
9188 | /* is there profile specification ? */ |
9189 | if ((profile_name = strrchr(conf_name, '@'))) { |
9190 | *profile_name++ = '\0'; |
9191 | } else { |
9192 | profile_name = "default"; |
9193 | } |
9194 | |
9195 | #if 0 |
9196 | if (0) { |
9197 | member.dtmf_parser = conference->dtmf_parser; |
9198 | } else { |
9199 | |
9200 | } |
9201 | #endif |
9202 | |
9203 | if (switch_channel_test_flag(channel, CF_RECOVERED)) { |
9204 | const char *check = switch_channel_get_variable(channel, "last_transfered_conference")switch_channel_get_variable_dup(channel, "last_transfered_conference" , SWITCH_TRUE, -1); |
9205 | |
9206 | if (!zstr(check)_zstr(check)) { |
9207 | conf_name = (char *) check; |
9208 | } |
9209 | } |
9210 | |
9211 | switch_event_create(¶ms, SWITCH_EVENT_COMMAND)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 9211, ¶ms, SWITCH_EVENT_COMMAND , ((void*)0)); |
9212 | switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "mod_conference.c" , 9212, __PRETTY_FUNCTION__)); |
9213 | switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conf_name", conf_name); |
9214 | switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile_name", profile_name); |
9215 | |
9216 | /* Open the config from the xml registry */ |
9217 | if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, params))) { |
9218 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9218, (const char*)(session), SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf_name); |
9219 | goto done; |
9220 | } |
9221 | |
9222 | if ((profiles = switch_xml_child(cfg, "profiles"))) { |
9223 | xml_cfg.profile = switch_xml_find_child(profiles, "profile", "name", profile_name); |
9224 | } |
9225 | |
9226 | /* if this is a bridging call, and it's not a duplicate, build a */ |
9227 | /* conference object, and skip pin handling, and locked checking */ |
9228 | |
9229 | if (!locked) { |
9230 | switch_mutex_lock(globals.setup_mutex); |
9231 | locked = 1; |
9232 | } |
9233 | |
9234 | if (isbr) { |
9235 | char *uuid = switch_core_session_get_uuid(session); |
9236 | |
9237 | if (!strcmp(conf_name, "_uuid_")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (conf_name) && __builtin_constant_p ("_uuid_") && (__s1_len = __builtin_strlen (conf_name), __s2_len = __builtin_strlen ("_uuid_"), (!((size_t)(const void *)((conf_name) + 1) - (size_t )(const void *)(conf_name) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("_uuid_") + 1) - (size_t)(const void *)("_uuid_") == 1) || __s2_len >= 4)) ? __builtin_strcmp ( conf_name, "_uuid_") : (__builtin_constant_p (conf_name) && ((size_t)(const void *)((conf_name) + 1) - (size_t)(const void *)(conf_name) == 1) && (__s1_len = __builtin_strlen ( conf_name), __s1_len < 4) ? (__builtin_constant_p ("_uuid_" ) && ((size_t)(const void *)(("_uuid_") + 1) - (size_t )(const void *)("_uuid_") == 1) ? __builtin_strcmp (conf_name , "_uuid_") : (__extension__ ({ const unsigned char *__s2 = ( const unsigned char *) (const char *) ("_uuid_"); int __result = (((const unsigned char *) (const char *) (conf_name))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (conf_name))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (conf_name))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (conf_name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("_uuid_" ) && ((size_t)(const void *)(("_uuid_") + 1) - (size_t )(const void *)("_uuid_") == 1) && (__s2_len = __builtin_strlen ("_uuid_"), __s2_len < 4) ? (__builtin_constant_p (conf_name ) && ((size_t)(const void *)((conf_name) + 1) - (size_t )(const void *)(conf_name) == 1) ? __builtin_strcmp (conf_name , "_uuid_") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (conf_name); int __result = (((const unsigned char *) (const char *) ("_uuid_"))[0] - __s2 [0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("_uuid_"))[1] - __s2 [1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("_uuid_"))[2] - __s2 [2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("_uuid_"))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (conf_name, "_uuid_" )))); })) { |
9238 | conf_name = uuid; |
9239 | } |
9240 | |
9241 | if ((conference = conference_find(conf_name, NULL((void*)0)))) { |
9242 | switch_thread_rwlock_unlock(conference->rwlock); |
9243 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9243, (const char*)(session), SWITCH_LOG_ERROR, "Conference %s already exists!\n", conf_name); |
9244 | goto done; |
9245 | } |
9246 | |
9247 | /* Create the conference object. */ |
9248 | conference = conference_new(conf_name, xml_cfg, session, NULL((void*)0)); |
9249 | |
9250 | if (!conference) { |
9251 | goto done; |
9252 | } |
9253 | |
9254 | set_cflags(cflags_str, &conference->flags); |
9255 | |
9256 | if (locked) { |
9257 | switch_mutex_unlock(globals.setup_mutex); |
9258 | locked = 0; |
9259 | } |
9260 | |
9261 | switch_channel_set_variable(channel, "conference_name", conference->name)switch_channel_set_variable_var_check(channel, "conference_name" , conference->name, SWITCH_TRUE); |
9262 | |
9263 | /* Set the minimum number of members (once you go above it you cannot go below it) */ |
9264 | conference->min = 2; |
9265 | |
9266 | /* Indicate the conference is dynamic */ |
9267 | switch_set_flag_locked(conference, CFLAG_DYNAMIC)((conference->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conference->flag_mutex != ((void*)0)", "mod_conference.c" , 9267, __PRETTY_FUNCTION__));switch_mutex_lock(conference-> flag_mutex);(conference)->flags |= (CFLAG_DYNAMIC);switch_mutex_unlock (conference->flag_mutex);; |
9268 | |
9269 | /* Indicate the conference has a bridgeto party */ |
9270 | switch_set_flag_locked(conference, CFLAG_BRIDGE_TO)((conference->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conference->flag_mutex != ((void*)0)", "mod_conference.c" , 9270, __PRETTY_FUNCTION__));switch_mutex_lock(conference-> flag_mutex);(conference)->flags |= (CFLAG_BRIDGE_TO);switch_mutex_unlock (conference->flag_mutex);; |
9271 | |
9272 | /* Start the conference thread for this conference */ |
9273 | launch_conference_thread(conference); |
9274 | |
9275 | } else { |
9276 | int enforce_security = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND; |
9277 | const char *pvar = switch_channel_get_variable(channel, "conference_enforce_security")switch_channel_get_variable_dup(channel, "conference_enforce_security" , SWITCH_TRUE, -1); |
9278 | |
9279 | if (pvar) { |
9280 | enforce_security = switch_true(pvar); |
9281 | } |
9282 | |
9283 | if ((conference = conference_find(conf_name, NULL((void*)0)))) { |
9284 | if (locked) { |
9285 | switch_mutex_unlock(globals.setup_mutex); |
9286 | locked = 0; |
9287 | } |
9288 | } |
9289 | |
9290 | /* if the conference exists, get the pointer to it */ |
9291 | if (!conference) { |
9292 | const char *max_members_str; |
9293 | const char *endconf_grace_time_str; |
9294 | const char *auto_record_str; |
9295 | |
9296 | /* no conference yet, so check for join-only flag */ |
9297 | if (flags_str) { |
9298 | set_mflags(flags_str,&mflags); |
9299 | |
9300 | if (!(mflags & MFLAG_CAN_SPEAK)) { |
9301 | if (!(mflags & MFLAG_MUTE_DETECT)) { |
9302 | switch_core_media_hard_mute(session, SWITCH_TRUE); |
9303 | } |
9304 | } |
9305 | |
9306 | if (mflags & MFLAG_JOIN_ONLY) { |
9307 | switch_event_t *event; |
9308 | switch_xml_t jos_xml; |
9309 | char *val; |
9310 | /* send event */ |
9311 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 9311, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance"); |
9312 | switch_channel_event_set_basic_data(channel, event); |
9313 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Name", conf_name); |
9314 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Profile-Name", profile_name); |
9315 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "rejected-join-only"); |
9316 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 9316, &event, ((void*)0)); |
9317 | /* check what sound file to play */ |
9318 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 9318, ((void*)0), SWITCH_LOG_NOTICE, "Cannot create a conference since join-only flag is set\n"); |
9319 | jos_xml = switch_xml_find_child(xml_cfg.profile, "param", "name", "join-only-sound"); |
9320 | if (jos_xml && (val = (char *) switch_xml_attr_soft(jos_xml, "value"))) { |
9321 | switch_channel_answer(channel)switch_channel_perform_answer(channel, "mod_conference.c", (const char *)__func__, 9321); |
9322 | switch_ivr_play_file(session, NULL((void*)0), val, NULL((void*)0)); |
9323 | } |
9324 | if (!switch_false(switch_channel_get_variable(channel, "hangup_after_conference")switch_channel_get_variable_dup(channel, "hangup_after_conference" , SWITCH_TRUE, -1))) { |
9325 | switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(channel, "mod_conference.c", (const char *)__func__, 9325, SWITCH_CAUSE_NORMAL_CLEARING); |
9326 | } |
9327 | goto done; |
9328 | } |
9329 | } |
9330 | |
9331 | /* couldn't find the conference, create one */ |
9332 | conference = conference_new(conf_name, xml_cfg, session, NULL((void*)0)); |
9333 | |
9334 | if (!conference) { |
9335 | goto done; |
9336 | } |
9337 | |
9338 | set_cflags(cflags_str, &conference->flags); |
9339 | |
9340 | if (locked) { |
9341 | switch_mutex_unlock(globals.setup_mutex); |
9342 | locked = 0; |
9343 | } |
9344 | |
9345 | switch_channel_set_variable(channel, "conference_name", conference->name)switch_channel_set_variable_var_check(channel, "conference_name" , conference->name, SWITCH_TRUE); |
9346 | |
9347 | /* Set MOH from variable if not set */ |
9348 | if (zstr(conference->moh_sound)_zstr(conference->moh_sound)) { |
9349 | conference->moh_sound = switch_core_strdup(conference->pool, switch_channel_get_variable(channel, "conference_moh_sound"))switch_core_perform_strdup(conference->pool, switch_channel_get_variable_dup (channel, "conference_moh_sound", SWITCH_TRUE, -1), "mod_conference.c" , (const char *)__func__, 9349); |
9350 | } |
9351 | |
9352 | /* Set perpetual-sound from variable if not set */ |
9353 | if (zstr(conference->perpetual_sound)_zstr(conference->perpetual_sound)) { |
9354 | conference->perpetual_sound = switch_core_strdup(conference->pool, switch_channel_get_variable(channel, "conference_perpetual_sound"))switch_core_perform_strdup(conference->pool, switch_channel_get_variable_dup (channel, "conference_perpetual_sound", SWITCH_TRUE, -1), "mod_conference.c" , (const char *)__func__, 9354); |
9355 | } |
9356 | |
9357 | /* Override auto-record profile parameter from variable */ |
9358 | if (!zstr(auto_record_str = switch_channel_get_variable(channel, "conference_auto_record"))_zstr(auto_record_str = switch_channel_get_variable_dup(channel , "conference_auto_record", SWITCH_TRUE, -1))) { |
9359 | conference->auto_record = switch_core_strdup(conference->pool, auto_record_str)switch_core_perform_strdup(conference->pool, auto_record_str , "mod_conference.c", (const char *)__func__, 9359); |
9360 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 9360, ((void*)0), SWITCH_LOG_DEBUG, |
9361 | "conference_auto_record set from variable to %s\n", auto_record_str); |
9362 | } |
9363 | |
9364 | /* Set the minimum number of members (once you go above it you cannot go below it) */ |
9365 | conference->min = 1; |
9366 | |
9367 | /* check for variable used to specify override for max_members */ |
9368 | if (!zstr(max_members_str = switch_channel_get_variable(channel, "conference_max_members"))_zstr(max_members_str = switch_channel_get_variable_dup(channel , "conference_max_members", SWITCH_TRUE, -1))) { |
9369 | uint32_t max_members_val; |
9370 | errno(*__errno_location ()) = 0; /* sanity first */ |
9371 | max_members_val = strtol(max_members_str, NULL((void*)0), 0); /* base 0 lets 0x... for hex 0... for octal and base 10 otherwise through */ |
9372 | if (errno(*__errno_location ()) == ERANGE34 || errno(*__errno_location ()) == EINVAL22 || (int32_t) max_members_val < 0 || max_members_val == 1) { |
9373 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 9373, ((void*)0), SWITCH_LOG_ERROR, |
9374 | "conference_max_members variable %s is invalid, not setting a limit\n", max_members_str); |
9375 | } else { |
9376 | conference->max_members = max_members_val; |
9377 | } |
9378 | } |
9379 | |
9380 | /* check for variable to override endconf_grace_time profile value */ |
9381 | if (!zstr(endconf_grace_time_str = switch_channel_get_variable(channel, "conference_endconf_grace_time"))_zstr(endconf_grace_time_str = switch_channel_get_variable_dup (channel, "conference_endconf_grace_time", SWITCH_TRUE, -1))) { |
9382 | uint32_t grace_time_val; |
9383 | errno(*__errno_location ()) = 0; /* sanity first */ |
9384 | grace_time_val = strtol(endconf_grace_time_str, NULL((void*)0), 0); /* base 0 lets 0x... for hex 0... for octal and base 10 otherwise through */ |
9385 | if (errno(*__errno_location ()) == ERANGE34 || errno(*__errno_location ()) == EINVAL22 || (int32_t) grace_time_val < 0) { |
9386 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 9386, ((void*)0), SWITCH_LOG_ERROR, |
9387 | "conference_endconf_grace_time variable %s is invalid, not setting a time limit\n", endconf_grace_time_str); |
9388 | } else { |
9389 | conference->endconf_grace_time = grace_time_val; |
9390 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 9390, ((void*)0), SWITCH_LOG_DEBUG, |
9391 | "conference endconf_grace_time set from variable to %d\n", grace_time_val); |
9392 | } |
9393 | } |
9394 | |
9395 | /* Indicate the conference is dynamic */ |
9396 | switch_set_flag_locked(conference, CFLAG_DYNAMIC)((conference->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conference->flag_mutex != ((void*)0)", "mod_conference.c" , 9396, __PRETTY_FUNCTION__));switch_mutex_lock(conference-> flag_mutex);(conference)->flags |= (CFLAG_DYNAMIC);switch_mutex_unlock (conference->flag_mutex);; |
9397 | |
9398 | /* acquire a read lock on the thread so it can't leave without us */ |
9399 | if (switch_thread_rwlock_tryrdlock(conference->rwlock) != SWITCH_STATUS_SUCCESS) { |
9400 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9400, (const char*)(session), SWITCH_LOG_CRIT, "Read Lock Fail\n"); |
9401 | goto done; |
9402 | } |
9403 | |
9404 | rl++; |
9405 | |
9406 | /* Start the conference thread for this conference */ |
9407 | launch_conference_thread(conference); |
9408 | } else { /* setup user variable */ |
9409 | switch_channel_set_variable(channel, "conference_name", conference->name)switch_channel_set_variable_var_check(channel, "conference_name" , conference->name, SWITCH_TRUE); |
9410 | rl++; |
9411 | } |
9412 | |
9413 | /* Moderator PIN as a channel variable */ |
9414 | mdpin = switch_channel_get_variable(channel, "conference_moderator_pin")switch_channel_get_variable_dup(channel, "conference_moderator_pin" , SWITCH_TRUE, -1); |
9415 | |
9416 | if (zstr(dpin)_zstr(dpin) && conference->pin) { |
9417 | dpin = conference->pin; |
9418 | } |
9419 | if (zstr(mdpin)_zstr(mdpin) && conference->mpin) { |
9420 | mdpin = conference->mpin; |
9421 | } |
9422 | |
9423 | |
9424 | /* if this is not an outbound call, deal with conference pins */ |
9425 | if (enforce_security && (!zstr(dpin)_zstr(dpin) || !zstr(mdpin)_zstr(mdpin))) { |
9426 | char pin_buf[80] = ""; |
9427 | int pin_retries = conference->pin_retries; |
9428 | int pin_valid = 0; |
9429 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
9430 | char *supplied_pin_value; |
9431 | |
9432 | /* Answer the channel */ |
9433 | switch_channel_answer(channel)switch_channel_perform_answer(channel, "mod_conference.c", (const char *)__func__, 9433); |
9434 | |
9435 | /* look for PIN in channel variable first. If not present or invalid revert to prompting user */ |
9436 | supplied_pin_value = switch_core_strdup(conference->pool, switch_channel_get_variable(channel, "supplied_pin"))switch_core_perform_strdup(conference->pool, switch_channel_get_variable_dup (channel, "supplied_pin", SWITCH_TRUE, -1), "mod_conference.c" , (const char *)__func__, 9436); |
9437 | if (!zstr(supplied_pin_value)_zstr(supplied_pin_value)) { |
9438 | char *supplied_pin_value_start; |
9439 | int i = 0; |
9440 | if ((supplied_pin_value_start = (char *) switch_stristr(cf_pin_url_param_name, supplied_pin_value))) { |
9441 | /* pin supplied as a URL parameter, move pointer to start of actual pin value */ |
9442 | supplied_pin_value = supplied_pin_value_start + strlen(cf_pin_url_param_name); |
9443 | } |
9444 | while (*supplied_pin_value != 0 && *supplied_pin_value != ';') { |
9445 | pin_buf[i++] = *supplied_pin_value++; |
9446 | } |
9447 | |
9448 | validate_pin(pin_buf, dpin, mdpin)pin_valid = (!_zstr(dpin) && __extension__ ({ size_t __s1_len , __s2_len; (__builtin_constant_p (pin_buf) && __builtin_constant_p (dpin) && (__s1_len = __builtin_strlen (pin_buf), __s2_len = __builtin_strlen (dpin), (!((size_t)(const void *)((pin_buf ) + 1) - (size_t)(const void *)(pin_buf) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((dpin) + 1) - (size_t )(const void *)(dpin) == 1) || __s2_len >= 4)) ? __builtin_strcmp (pin_buf, dpin) : (__builtin_constant_p (pin_buf) && ((size_t)(const void *)((pin_buf) + 1) - (size_t)(const void *)(pin_buf) == 1) && (__s1_len = __builtin_strlen (pin_buf ), __s1_len < 4) ? (__builtin_constant_p (dpin) && ((size_t)(const void *)((dpin) + 1) - (size_t)(const void *) (dpin) == 1) ? __builtin_strcmp (pin_buf, dpin) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (dpin); int __result = (((const unsigned char *) (const char *) (pin_buf))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin_buf))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin_buf))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (pin_buf))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (dpin) && ((size_t)(const void *)((dpin) + 1) - (size_t )(const void *)(dpin) == 1) && (__s2_len = __builtin_strlen (dpin), __s2_len < 4) ? (__builtin_constant_p (pin_buf) && ((size_t)(const void *)((pin_buf) + 1) - (size_t)(const void *)(pin_buf) == 1) ? __builtin_strcmp (pin_buf, dpin) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pin_buf); int __result = (((const unsigned char *) ( const char *) (dpin))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (dpin))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (dpin))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (dpin))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (pin_buf, dpin)))); }) == 0); if (!pin_valid && !_zstr (mdpin) && __extension__ ({ size_t __s1_len, __s2_len ; (__builtin_constant_p (pin_buf) && __builtin_constant_p (mdpin) && (__s1_len = __builtin_strlen (pin_buf), __s2_len = __builtin_strlen (mdpin), (!((size_t)(const void *)((pin_buf ) + 1) - (size_t)(const void *)(pin_buf) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((mdpin) + 1) - (size_t )(const void *)(mdpin) == 1) || __s2_len >= 4)) ? __builtin_strcmp (pin_buf, mdpin) : (__builtin_constant_p (pin_buf) && ((size_t)(const void *)((pin_buf) + 1) - (size_t)(const void *)(pin_buf) == 1) && (__s1_len = __builtin_strlen (pin_buf ), __s1_len < 4) ? (__builtin_constant_p (mdpin) && ((size_t)(const void *)((mdpin) + 1) - (size_t)(const void * )(mdpin) == 1) ? __builtin_strcmp (pin_buf, mdpin) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (mdpin); int __result = (((const unsigned char *) (const char *) (pin_buf))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin_buf))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin_buf))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (pin_buf))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (mdpin) && ((size_t)(const void *)((mdpin) + 1) - (size_t )(const void *)(mdpin) == 1) && (__s2_len = __builtin_strlen (mdpin), __s2_len < 4) ? (__builtin_constant_p (pin_buf) && ((size_t)(const void *)((pin_buf) + 1) - (size_t)(const void *)(pin_buf) == 1) ? __builtin_strcmp (pin_buf, mdpin) : (- ( __extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pin_buf); int __result = (((const unsigned char *) (const char *) (mdpin))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (mdpin))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (mdpin))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (mdpin))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (pin_buf, mdpin)))); }) == 0) { switch_log_printf (SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char * )__func__, 9448, (const char*)(session), SWITCH_LOG_DEBUG, "Moderator PIN found!\n" ); pin_valid = 1; mpin_matched = 1; }; |
9449 | memset(pin_buf, 0, sizeof(pin_buf)); |
9450 | } |
9451 | |
9452 | if (!conference->pin_sound) { |
9453 | conference->pin_sound = switch_core_strdup(conference->pool, "conference/conf-pin.wav")switch_core_perform_strdup(conference->pool, "conference/conf-pin.wav" , "mod_conference.c", (const char *)__func__, 9453); |
9454 | } |
9455 | |
9456 | if (!conference->bad_pin_sound) { |
9457 | conference->bad_pin_sound = switch_core_strdup(conference->pool, "conference/conf-bad-pin.wav")switch_core_perform_strdup(conference->pool, "conference/conf-bad-pin.wav" , "mod_conference.c", (const char *)__func__, 9457); |
9458 | } |
9459 | |
9460 | while (!pin_valid && pin_retries && status == SWITCH_STATUS_SUCCESS) { |
9461 | size_t dpin_length = dpin ? strlen(dpin) : 0; |
9462 | size_t mdpin_length = mdpin ? strlen(mdpin) : 0; |
9463 | int maxpin = dpin_length > mdpin_length ? (int)dpin_length : (int)mdpin_length; |
9464 | switch_status_t pstatus = SWITCH_STATUS_FALSE; |
9465 | |
9466 | /* be friendly */ |
9467 | if (conference->pin_sound) { |
9468 | pstatus = conference_local_play_file(conference, session, conference->pin_sound, 20, pin_buf, sizeof(pin_buf)); |
9469 | } else if (conference->tts_engine && conference->tts_voice) { |
9470 | pstatus = |
9471 | switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, "please enter the conference pin number", NULL((void*)0)); |
9472 | } else { |
9473 | pstatus = switch_ivr_speak_text(session, "flite", "slt", "please enter the conference pin number", NULL((void*)0)); |
9474 | } |
9475 | |
9476 | if (pstatus != SWITCH_STATUS_SUCCESS && pstatus != SWITCH_STATUS_BREAK) { |
9477 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9477, (const char*)(session), SWITCH_LOG_WARNING, "Cannot ask the user for a pin, ending call\n"); |
9478 | switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "mod_conference.c", (const char *)__func__, 9478, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ); |
9479 | } |
9480 | |
9481 | /* wait for them if neccessary */ |
9482 | if ((int)strlen(pin_buf) < maxpin) { |
9483 | char *buf = pin_buf + strlen(pin_buf); |
9484 | char term = '\0'; |
9485 | |
9486 | status = switch_ivr_collect_digits_count(session, |
9487 | buf, |
9488 | sizeof(pin_buf) - strlen(pin_buf), maxpin - strlen(pin_buf), "#", &term, 10000, 0, 0); |
9489 | if (status == SWITCH_STATUS_TIMEOUT) { |
9490 | status = SWITCH_STATUS_SUCCESS; |
9491 | } |
9492 | } |
9493 | |
9494 | if (status == SWITCH_STATUS_SUCCESS) { |
9495 | validate_pin(pin_buf, dpin, mdpin)pin_valid = (!_zstr(dpin) && __extension__ ({ size_t __s1_len , __s2_len; (__builtin_constant_p (pin_buf) && __builtin_constant_p (dpin) && (__s1_len = __builtin_strlen (pin_buf), __s2_len = __builtin_strlen (dpin), (!((size_t)(const void *)((pin_buf ) + 1) - (size_t)(const void *)(pin_buf) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((dpin) + 1) - (size_t )(const void *)(dpin) == 1) || __s2_len >= 4)) ? __builtin_strcmp (pin_buf, dpin) : (__builtin_constant_p (pin_buf) && ((size_t)(const void *)((pin_buf) + 1) - (size_t)(const void *)(pin_buf) == 1) && (__s1_len = __builtin_strlen (pin_buf ), __s1_len < 4) ? (__builtin_constant_p (dpin) && ((size_t)(const void *)((dpin) + 1) - (size_t)(const void *) (dpin) == 1) ? __builtin_strcmp (pin_buf, dpin) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (dpin); int __result = (((const unsigned char *) (const char *) (pin_buf))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin_buf))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin_buf))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (pin_buf))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (dpin) && ((size_t)(const void *)((dpin) + 1) - (size_t )(const void *)(dpin) == 1) && (__s2_len = __builtin_strlen (dpin), __s2_len < 4) ? (__builtin_constant_p (pin_buf) && ((size_t)(const void *)((pin_buf) + 1) - (size_t)(const void *)(pin_buf) == 1) ? __builtin_strcmp (pin_buf, dpin) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pin_buf); int __result = (((const unsigned char *) ( const char *) (dpin))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (dpin))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (dpin))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (dpin))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (pin_buf, dpin)))); }) == 0); if (!pin_valid && !_zstr (mdpin) && __extension__ ({ size_t __s1_len, __s2_len ; (__builtin_constant_p (pin_buf) && __builtin_constant_p (mdpin) && (__s1_len = __builtin_strlen (pin_buf), __s2_len = __builtin_strlen (mdpin), (!((size_t)(const void *)((pin_buf ) + 1) - (size_t)(const void *)(pin_buf) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((mdpin) + 1) - (size_t )(const void *)(mdpin) == 1) || __s2_len >= 4)) ? __builtin_strcmp (pin_buf, mdpin) : (__builtin_constant_p (pin_buf) && ((size_t)(const void *)((pin_buf) + 1) - (size_t)(const void *)(pin_buf) == 1) && (__s1_len = __builtin_strlen (pin_buf ), __s1_len < 4) ? (__builtin_constant_p (mdpin) && ((size_t)(const void *)((mdpin) + 1) - (size_t)(const void * )(mdpin) == 1) ? __builtin_strcmp (pin_buf, mdpin) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (mdpin); int __result = (((const unsigned char *) (const char *) (pin_buf))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin_buf))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pin_buf))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (pin_buf))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (mdpin) && ((size_t)(const void *)((mdpin) + 1) - (size_t )(const void *)(mdpin) == 1) && (__s2_len = __builtin_strlen (mdpin), __s2_len < 4) ? (__builtin_constant_p (pin_buf) && ((size_t)(const void *)((pin_buf) + 1) - (size_t)(const void *)(pin_buf) == 1) ? __builtin_strcmp (pin_buf, mdpin) : (- ( __extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pin_buf); int __result = (((const unsigned char *) (const char *) (mdpin))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (mdpin))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (mdpin))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (mdpin))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (pin_buf, mdpin)))); }) == 0) { switch_log_printf (SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char * )__func__, 9495, (const char*)(session), SWITCH_LOG_DEBUG, "Moderator PIN found!\n" ); pin_valid = 1; mpin_matched = 1; }; |
9496 | } |
9497 | |
9498 | if (!pin_valid) { |
9499 | /* zero the collected pin */ |
9500 | memset(pin_buf, 0, sizeof(pin_buf)); |
9501 | |
9502 | /* more friendliness */ |
9503 | if (conference->bad_pin_sound) { |
9504 | conference_local_play_file(conference, session, conference->bad_pin_sound, 20, NULL((void*)0), 0); |
9505 | } |
9506 | switch_channel_flush_dtmf(channel); |
9507 | } |
9508 | pin_retries--; |
9509 | } |
9510 | |
9511 | if (!pin_valid) { |
9512 | conference_cdr_rejected(conference, channel, CDRR_PIN); |
9513 | goto done; |
9514 | } |
9515 | } |
9516 | |
9517 | if (conference->special_announce && !switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ)) { |
9518 | conference_local_play_file(conference, session, conference->special_announce, CONF_DEFAULT_LEADIN20, NULL((void*)0), 0); |
9519 | } |
9520 | |
9521 | /* don't allow more callers if the conference is locked, unless we invited them */ |
9522 | if (switch_test_flag(conference, CFLAG_LOCKED)((conference)->flags & CFLAG_LOCKED) && enforce_security) { |
9523 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9523, (const char*)(session), SWITCH_LOG_NOTICE, "Conference %s is locked.\n", conf_name); |
9524 | conference_cdr_rejected(conference, channel, CDRR_LOCKED); |
9525 | if (conference->locked_sound) { |
9526 | /* Answer the channel */ |
9527 | switch_channel_answer(channel)switch_channel_perform_answer(channel, "mod_conference.c", (const char *)__func__, 9527); |
9528 | conference_local_play_file(conference, session, conference->locked_sound, 20, NULL((void*)0), 0); |
9529 | } |
9530 | goto done; |
9531 | } |
9532 | |
9533 | /* dont allow more callers than the max_members allows for -- I explicitly didnt allow outbound calls |
9534 | * someone else can add that (see above) if they feel that outbound calls should be able to violate the |
9535 | * max_members limit |
9536 | */ |
9537 | if ((conference->max_members > 0) && (conference->count >= conference->max_members)) { |
9538 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_conference.c", (const char *) __func__, 9538, (const char*)(session), SWITCH_LOG_NOTICE, "Conference %s is full.\n", conf_name); |
9539 | conference_cdr_rejected(conference, channel, CDRR_MAXMEMBERS); |
9540 | if (conference->maxmember_sound) { |
9541 | /* Answer the channel */ |
9542 | switch_channel_answer(channel)switch_channel_perform_answer(channel, "mod_conference.c", (const char *)__func__, 9542); |
9543 | conference_local_play_file(conference, session, conference->maxmember_sound, 20, NULL((void*)0), 0); |
9544 | } |
9545 | goto done; |
9546 | } |
9547 | |
9548 | } |
9549 | |
9550 | /* Release the config registry handle */ |
9551 | if (cxml) { |
9552 | switch_xml_free(cxml); |
9553 | cxml = NULL((void*)0); |
9554 | } |
9555 | |
9556 | /* if we're using "bridge:" make an outbound call and bridge it in */ |
9557 | if (!zstr(bridgeto)_zstr(bridgeto) && strcasecmp(bridgeto, "none")) { |
9558 | switch_call_cause_t cause; |
9559 | if (conference_outcall(conference, NULL((void*)0), session, bridgeto, 60, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), &cause, NULL((void*)0), NULL((void*)0)) != SWITCH_STATUS_SUCCESS) { |
9560 | goto done; |
9561 | } |
9562 | } else { |
9563 | /* if we're not using "bridge:" set the conference answered flag */ |
9564 | /* and this isn't an outbound channel, answer the call */ |
9565 | if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) |
9566 | switch_set_flag(conference, CFLAG_ANSWERED)(conference)->flags |= (CFLAG_ANSWERED); |
9567 | } |
9568 | |
9569 | member.session = session; |
9570 | member.channel = switch_core_session_get_channel(session); |
9571 | member.pool = switch_core_session_get_pool(session); |
9572 | |
9573 | if (setup_media(&member, conference)) { |
9574 | //flags = 0; |
9575 | goto done; |
9576 | } |
9577 | |
9578 | |
9579 | if (!(mid = switch_channel_get_private(channel, "__confmid"))) { |
9580 | mid = switch_core_session_alloc(session, sizeof(*mid))switch_core_perform_session_alloc(session, sizeof(*mid), "mod_conference.c" , (const char *)__func__, 9580); |
9581 | *mid = next_member_id(); |
9582 | switch_channel_set_private(channel, "__confmid", mid); |
9583 | } |
9584 | |
9585 | switch_channel_set_variable_printf(channel, "conference_member_id", "%u", *mid); |
9586 | |
9587 | /* Prepare MUTEXS */ |
9588 | member.id = *mid; |
9589 | switch_mutex_init(&member.flag_mutex, SWITCH_MUTEX_NESTED0x1, member.pool); |
9590 | switch_mutex_init(&member.write_mutex, SWITCH_MUTEX_NESTED0x1, member.pool); |
9591 | switch_mutex_init(&member.read_mutex, SWITCH_MUTEX_NESTED0x1, member.pool); |
9592 | switch_mutex_init(&member.fnode_mutex, SWITCH_MUTEX_NESTED0x1, member.pool); |
9593 | switch_mutex_init(&member.audio_in_mutex, SWITCH_MUTEX_NESTED0x1, member.pool); |
9594 | switch_mutex_init(&member.audio_out_mutex, SWITCH_MUTEX_NESTED0x1, member.pool); |
9595 | switch_thread_rwlock_create(&member.rwlock, member.pool); |
9596 | |
9597 | /* Install our Signed Linear codec so we get the audio in that format */ |
9598 | switch_core_session_set_read_codec(member.session, &member.read_codec); |
9599 | |
9600 | |
9601 | mflags = conference->mflags; |
9602 | set_mflags(flags_str, &mflags); |
9603 | mflags |= MFLAG_RUNNING; |
9604 | |
9605 | if (!(mflags & MFLAG_CAN_SPEAK)) { |
9606 | if (!(mflags & MFLAG_MUTE_DETECT)) { |
9607 | switch_core_media_hard_mute(member.session, SWITCH_TRUE); |
9608 | } |
9609 | } |
9610 | |
9611 | if (mpin_matched) { |
9612 | mflags |= MFLAG_MOD; |
9613 | } |
9614 | switch_set_flag_locked((&member), mflags)(((&member)->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("(&member)->flag_mutex != ((void*)0)", "mod_conference.c" , 9614, __PRETTY_FUNCTION__));switch_mutex_lock((&member) ->flag_mutex);((&member))->flags |= (mflags);switch_mutex_unlock ((&member)->flag_mutex);; |
9615 | |
9616 | if (mflags & MFLAG_MINTWO) { |
9617 | conference->min = 2; |
9618 | } |
9619 | |
9620 | /* Add the caller to the conference */ |
9621 | if (conference_add_member(conference, &member) != SWITCH_STATUS_SUCCESS) { |
9622 | switch_core_codec_destroy(&member.read_codec); |
9623 | goto done; |
9624 | } |
9625 | |
9626 | msg.from = __FILE__"mod_conference.c"; |
9627 | |
9628 | /* Tell the channel we are going to be in a bridge */ |
9629 | msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE; |
9630 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "mod_conference.c", (const char *)__func__, 9630); |
9631 | |
9632 | /* Run the conference loop */ |
9633 | do { |
9634 | conference_loop_output(&member); |
9635 | } while (member.loop_loop); |
9636 | |
9637 | switch_channel_set_private(channel, "_conference_autocall_list_", NULL((void*)0)); |
9638 | |
9639 | /* Tell the channel we are no longer going to be in a bridge */ |
9640 | msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE; |
9641 | switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg , "mod_conference.c", (const char *)__func__, 9641); |
9642 | |
9643 | /* Remove the caller from the conference */ |
9644 | conference_del_member(member.conference, &member); |
9645 | |
9646 | /* Put the original codec back */ |
9647 | switch_core_session_set_read_codec(member.session, NULL((void*)0)); |
9648 | |
9649 | /* Clean Up. */ |
9650 | |
9651 | done: |
9652 | |
9653 | if (locked) { |
9654 | switch_mutex_unlock(globals.setup_mutex); |
9655 | } |
9656 | |
9657 | if (member.read_resampler) { |
9658 | switch_resample_destroy(&member.read_resampler); |
9659 | } |
9660 | |
9661 | switch_event_destroy(¶ms); |
9662 | switch_buffer_destroy(&member.resample_buffer); |
9663 | switch_buffer_destroy(&member.audio_buffer); |
9664 | switch_buffer_destroy(&member.mux_buffer); |
9665 | |
9666 | if (conference) { |
9667 | switch_mutex_lock(conference->mutex); |
9668 | if (switch_test_flag(conference, CFLAG_DYNAMIC)((conference)->flags & CFLAG_DYNAMIC) && conference->count == 0) { |
9669 | switch_set_flag_locked(conference, CFLAG_DESTRUCT)((conference->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conference->flag_mutex != ((void*)0)", "mod_conference.c" , 9669, __PRETTY_FUNCTION__));switch_mutex_lock(conference-> flag_mutex);(conference)->flags |= (CFLAG_DESTRUCT);switch_mutex_unlock (conference->flag_mutex);; |
9670 | } |
9671 | switch_mutex_unlock(conference->mutex); |
9672 | } |
9673 | |
9674 | /* Release the config registry handle */ |
9675 | if (cxml) { |
9676 | switch_xml_free(cxml); |
9677 | } |
9678 | |
9679 | if (conference && switch_test_flag(&member, MFLAG_KICKED)((&member)->flags & MFLAG_KICKED) && conference->kicked_sound) { |
9680 | char *toplay = NULL((void*)0); |
9681 | char *dfile = NULL((void*)0); |
9682 | char *expanded = NULL((void*)0); |
9683 | char *src = member.kicked_sound ? member.kicked_sound : conference->kicked_sound; |
9684 | |
9685 | |
9686 | if (!strncasecmp(src, "say:", 4)) { |
9687 | if (conference->tts_engine && conference->tts_voice) { |
9688 | switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, src + 4, NULL((void*)0)); |
9689 | } |
9690 | } else { |
9691 | if ((expanded = switch_channel_expand_variables(switch_core_session_get_channel(session), src)switch_channel_expand_variables_check(switch_core_session_get_channel (session), src, ((void*)0), ((void*)0), 0)) != src) { |
9692 | toplay = expanded; |
9693 | } else { |
9694 | expanded = NULL((void*)0); |
9695 | toplay = src; |
9696 | } |
9697 | |
9698 | if (!switch_is_file_path(toplay) && conference->sound_prefix) { |
9699 | dfile = switch_mprintf("%s%s%s", conference->sound_prefix, SWITCH_PATH_SEPARATOR"/", toplay); |
9700 | switch_assert(dfile)((dfile) ? (void) (0) : __assert_fail ("dfile", "mod_conference.c" , 9700, __PRETTY_FUNCTION__)); |
9701 | toplay = dfile; |
9702 | } |
9703 | |
9704 | switch_ivr_play_file(session, NULL((void*)0), toplay, NULL((void*)0)); |
9705 | switch_safe_free(dfile)if (dfile) {free(dfile);dfile=((void*)0);}; |
9706 | switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);}; |
9707 | } |
9708 | } |
9709 | |
9710 | switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); |
9711 | |
9712 | /* release the readlock */ |
9713 | if (rl) { |
9714 | switch_thread_rwlock_unlock(conference->rwlock); |
9715 | } |
9716 | |
9717 | switch_channel_set_variable(channel, "last_transfered_conference", NULL)switch_channel_set_variable_var_check(channel, "last_transfered_conference" , ((void*)0), SWITCH_TRUE); |
9718 | |
9719 | end: |
9720 | |
9721 | switch_channel_clear_flag(channel, CF_CONFERENCE); |
9722 | switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE); |
9723 | |
9724 | switch_core_session_video_reset(session); |
9725 | } |
9726 | |
9727 | /* Create a thread for the conference and launch it */ |
9728 | static void launch_conference_thread(conference_obj_t *conference) |
9729 | { |
9730 | switch_thread_t *thread; |
9731 | switch_threadattr_t *thd_attr = NULL((void*)0); |
9732 | |
9733 | switch_set_flag_locked(conference, CFLAG_RUNNING)((conference->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("conference->flag_mutex != ((void*)0)", "mod_conference.c" , 9733, __PRETTY_FUNCTION__));switch_mutex_lock(conference-> flag_mutex);(conference)->flags |= (CFLAG_RUNNING);switch_mutex_unlock (conference->flag_mutex);; |
9734 | switch_threadattr_create(&thd_attr, conference->pool); |
9735 | switch_threadattr_detach_set(thd_attr, 1); |
9736 | switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); |
9737 | switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024); |
9738 | switch_mutex_lock(globals.hash_mutex); |
9739 | switch_mutex_unlock(globals.hash_mutex); |
9740 | switch_thread_create(&thread, thd_attr, conference_thread_run, conference, conference->pool); |
9741 | } |
9742 | |
9743 | static switch_thread_t *launch_thread_detached(switch_thread_start_t func, switch_memory_pool_t *pool, void *data) |
9744 | { |
9745 | switch_thread_t *thread; |
9746 | switch_threadattr_t *thd_attr = NULL((void*)0); |
9747 | |
9748 | switch_threadattr_create(&thd_attr, pool); |
9749 | switch_threadattr_detach_set(thd_attr, 1); |
9750 | switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024); |
9751 | switch_thread_create(&thread, thd_attr, func, data, pool); |
9752 | |
9753 | return thread; |
9754 | } |
9755 | |
9756 | /* Create a video thread for the conference and launch it */ |
9757 | static void launch_conference_video_thread(conference_obj_t *conference) |
9758 | { |
9759 | launch_thread_detached(conference_video_thread_run, conference->pool, conference); |
9760 | conference->video_running = 1; |
9761 | } |
9762 | |
9763 | /* Create a video thread for the conference and launch it */ |
9764 | static int launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b) |
9765 | { |
9766 | conference_obj_t *conference = member_a->conference; |
9767 | switch_memory_pool_t *pool = conference->pool; |
9768 | int sanity = 10000, r = 0; |
9769 | |
9770 | memset(conference->vh, 0, sizeof(conference->vh)); |
9771 | |
9772 | conference->vh[0].member_a = member_a; |
9773 | conference->vh[0].member_b = member_b; |
9774 | |
9775 | conference->vh[1].member_a = member_b; |
9776 | conference->vh[1].member_b = member_a; |
9777 | |
9778 | launch_thread_detached(conference_video_bridge_thread_run, pool, &conference->vh[0]); |
9779 | launch_thread_detached(conference_video_bridge_thread_run, pool, &conference->vh[1]); |
9780 | |
9781 | while(!(conference->vh[0].up && conference->vh[1].up) && --sanity > 0) { |
9782 | switch_cond_next(); |
9783 | } |
9784 | |
9785 | if (conference->vh[0].up == 1 && conference->vh[1].up != 1) { |
9786 | conference->vh[0].up = -1; |
9787 | r = -1; |
9788 | } |
9789 | |
9790 | if (conference->vh[1].up == 1 && conference->vh[0].up != 1) { |
9791 | conference->vh[1].up = -1; |
9792 | r = -1; |
9793 | } |
9794 | |
9795 | return r; |
9796 | |
9797 | } |
9798 | |
9799 | static void launch_conference_record_thread(conference_obj_t *conference, char *path, switch_bool_t autorec) |
9800 | { |
9801 | switch_thread_t *thread; |
9802 | switch_threadattr_t *thd_attr = NULL((void*)0); |
9803 | switch_memory_pool_t *pool; |
9804 | conference_record_t *rec; |
9805 | |
9806 | /* Setup a memory pool to use. */ |
9807 | if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 9807) != SWITCH_STATUS_SUCCESS) { |
9808 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 9808, ((void*)0), SWITCH_LOG_CRIT, "Pool Failure\n"); |
9809 | } |
9810 | |
9811 | /* Create a node object */ |
9812 | if (!(rec = switch_core_alloc(pool, sizeof(*rec))switch_core_perform_alloc(pool, sizeof(*rec), "mod_conference.c" , (const char *)__func__, 9812))) { |
9813 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 9813, ((void*)0), SWITCH_LOG_CRIT, "Alloc Failure\n"); |
9814 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 9814); |
9815 | return; |
9816 | } |
9817 | |
9818 | rec->conference = conference; |
9819 | rec->path = switch_core_strdup(pool, path)switch_core_perform_strdup(pool, path, "mod_conference.c", (const char *)__func__, 9819); |
9820 | rec->pool = pool; |
9821 | rec->autorec = autorec; |
9822 | |
9823 | switch_mutex_lock(conference->flag_mutex); |
9824 | rec->next = conference->rec_node_head; |
9825 | conference->rec_node_head = rec; |
9826 | switch_mutex_unlock(conference->flag_mutex); |
9827 | |
9828 | switch_threadattr_create(&thd_attr, rec->pool); |
9829 | switch_threadattr_detach_set(thd_attr, 1); |
9830 | switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024); |
9831 | switch_thread_create(&thread, thd_attr, conference_record_thread_run, rec, rec->pool); |
9832 | } |
9833 | |
9834 | static switch_status_t chat_send(switch_event_t *message_event) |
9835 | { |
9836 | char name[512] = "", *p, *lbuf = NULL((void*)0); |
9837 | conference_obj_t *conference = NULL((void*)0); |
9838 | switch_stream_handle_t stream = { 0 }; |
9839 | const char *proto; |
9840 | const char *from; |
9841 | const char *to; |
9842 | //const char *subject; |
9843 | const char *body; |
9844 | //const char *type; |
9845 | const char *hint; |
9846 | |
9847 | proto = switch_event_get_header(message_event, "proto")switch_event_get_header_idx(message_event, "proto", -1); |
9848 | from = switch_event_get_header(message_event, "from")switch_event_get_header_idx(message_event, "from", -1); |
9849 | to = switch_event_get_header(message_event, "to")switch_event_get_header_idx(message_event, "to", -1); |
9850 | body = switch_event_get_body(message_event); |
9851 | hint = switch_event_get_header(message_event, "hint")switch_event_get_header_idx(message_event, "hint", -1); |
9852 | |
9853 | |
9854 | if ((p = strchr(to, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p (to) && ('+') == '\0' ? (char *) __rawmemchr (to, '+' ) : __builtin_strchr (to, '+'))))) { |
9855 | to = ++p; |
9856 | } |
9857 | |
9858 | if (!body) { |
9859 | return SWITCH_STATUS_SUCCESS; |
9860 | } |
9861 | |
9862 | if ((p = strchr(to, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (to) && ('@') == '\0' ? (char *) __rawmemchr (to, '@' ) : __builtin_strchr (to, '@'))))) { |
9863 | switch_copy_string(name, to, ++p - to); |
9864 | } else { |
9865 | switch_copy_string(name, to, sizeof(name)); |
9866 | } |
9867 | |
9868 | if (!(conference = conference_find(name, NULL((void*)0)))) { |
9869 | switch_core_chat_send_args(proto, CONF_CHAT_PROTO"conf", to, hint && strchr(hint, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p (hint) && ('/') == '\0' ? (char *) __rawmemchr (hint , '/') : __builtin_strchr (hint, '/'))) ? hint : from, "", |
9870 | "Conference not active.", NULL((void*)0), NULL((void*)0), SWITCH_FALSE); |
9871 | return SWITCH_STATUS_FALSE; |
9872 | } |
9873 | |
9874 | SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc( 1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data" , "mod_conference.c", 9874, __PRETTY_FUNCTION__)); memset(stream .data, 0, 1024); stream.end = stream.data; stream.data_size = 1024; stream.write_function = switch_console_stream_write; stream .raw_write_function = switch_console_stream_raw_write; stream .alloc_len = 1024; stream.alloc_chunk = 1024; |
9875 | |
9876 | if (body != NULL((void*)0) && (lbuf = strdup(body)(__extension__ (__builtin_constant_p (body) && ((size_t )(const void *)((body) + 1) - (size_t)(const void *)(body) == 1) ? (((const char *) (body))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen (body) + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, body, __len) ; __retval; })) : __strdup (body))))) { |
9877 | /* special case list */ |
9878 | if (conference->broadcast_chat_messages) { |
9879 | chat_message_broadcast(conference, message_event); |
9880 | } else if (switch_stristr("list", lbuf)) { |
9881 | conference_list_pretty(conference, &stream); |
9882 | /* provide help */ |
9883 | } else { |
9884 | return SWITCH_STATUS_SUCCESS; |
9885 | } |
9886 | } |
9887 | |
9888 | switch_safe_free(lbuf)if (lbuf) {free(lbuf);lbuf=((void*)0);}; |
9889 | |
9890 | if (!conference->broadcast_chat_messages) { |
9891 | switch_core_chat_send_args(proto, CONF_CHAT_PROTO"conf", to, hint && strchr(hint, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p (hint) && ('/') == '\0' ? (char *) __rawmemchr (hint , '/') : __builtin_strchr (hint, '/'))) ? hint : from, "", stream.data, NULL((void*)0), NULL((void*)0), SWITCH_FALSE); |
9892 | } |
9893 | |
9894 | switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);}; |
9895 | switch_thread_rwlock_unlock(conference->rwlock); |
9896 | |
9897 | return SWITCH_STATUS_SUCCESS; |
9898 | } |
9899 | |
9900 | static conference_obj_t *conference_find(char *name, char *domain) |
9901 | { |
9902 | conference_obj_t *conference; |
9903 | |
9904 | switch_mutex_lock(globals.hash_mutex); |
9905 | if ((conference = switch_core_hash_find(globals.conference_hash, name))) { |
9906 | if (switch_test_flag(conference, CFLAG_DESTRUCT)((conference)->flags & CFLAG_DESTRUCT)) { |
9907 | switch_core_hash_delete(globals.conference_hash, conference->name); |
9908 | switch_clear_flag(conference, CFLAG_INHASH)(conference)->flags &= ~(CFLAG_INHASH); |
9909 | conference = NULL((void*)0); |
9910 | } else if (!zstr(domain)_zstr(domain) && conference->domain && strcasecmp(domain, conference->domain)) { |
9911 | conference = NULL((void*)0); |
9912 | } |
9913 | } |
9914 | if (conference) { |
9915 | if (switch_thread_rwlock_tryrdlock(conference->rwlock) != SWITCH_STATUS_SUCCESS) { |
9916 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 9916, ((void*)0), SWITCH_LOG_CRIT, "Read Lock Fail\n"); |
9917 | conference = NULL((void*)0); |
9918 | } |
9919 | } |
9920 | switch_mutex_unlock(globals.hash_mutex); |
9921 | |
9922 | return conference; |
9923 | } |
9924 | |
9925 | /* create a new conferene with a specific profile */ |
9926 | static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_core_session_t *session, switch_memory_pool_t *pool) |
9927 | { |
9928 | conference_obj_t *conference; |
9929 | switch_xml_t xml_kvp; |
9930 | char *timer_name = NULL((void*)0); |
9931 | char *domain = NULL((void*)0); |
9932 | char *desc = NULL((void*)0); |
9933 | char *name_domain = NULL((void*)0); |
9934 | char *tts_engine = NULL((void*)0); |
9935 | char *tts_voice = NULL((void*)0); |
9936 | char *enter_sound = NULL((void*)0); |
9937 | char *sound_prefix = NULL((void*)0); |
9938 | char *exit_sound = NULL((void*)0); |
9939 | char *alone_sound = NULL((void*)0); |
9940 | char *ack_sound = NULL((void*)0); |
9941 | char *nack_sound = NULL((void*)0); |
9942 | char *muted_sound = NULL((void*)0); |
9943 | char *mute_detect_sound = NULL((void*)0); |
9944 | char *unmuted_sound = NULL((void*)0); |
9945 | char *locked_sound = NULL((void*)0); |
9946 | char *is_locked_sound = NULL((void*)0); |
9947 | char *is_unlocked_sound = NULL((void*)0); |
9948 | char *kicked_sound = NULL((void*)0); |
9949 | char *join_only_sound = NULL((void*)0); |
9950 | char *pin = NULL((void*)0); |
9951 | char *mpin = NULL((void*)0); |
9952 | char *pin_sound = NULL((void*)0); |
9953 | char *bad_pin_sound = NULL((void*)0); |
9954 | char *energy_level = NULL((void*)0); |
9955 | char *auto_gain_level = NULL((void*)0); |
9956 | char *caller_id_name = NULL((void*)0); |
9957 | char *caller_id_number = NULL((void*)0); |
9958 | char *caller_controls = NULL((void*)0); |
9959 | char *moderator_controls = NULL((void*)0); |
9960 | char *member_flags = NULL((void*)0); |
9961 | char *conference_flags = NULL((void*)0); |
9962 | char *perpetual_sound = NULL((void*)0); |
9963 | char *moh_sound = NULL((void*)0); |
9964 | char *outcall_templ = NULL((void*)0); |
9965 | uint32_t max_members = 0; |
9966 | uint32_t announce_count = 0; |
9967 | char *maxmember_sound = NULL((void*)0); |
9968 | uint32_t rate = 8000, interval = 20; |
9969 | uint32_t channels = 1; |
9970 | int broadcast_chat_messages = 1; |
9971 | int comfort_noise_level = 0; |
9972 | int pin_retries = 3; |
9973 | int ivr_dtmf_timeout = 500; |
9974 | int ivr_input_timeout = 0; |
9975 | char *suppress_events = NULL((void*)0); |
9976 | char *verbose_events = NULL((void*)0); |
9977 | char *auto_record = NULL((void*)0); |
9978 | int min_recording_participants = 2; |
9979 | char *conference_log_dir = NULL((void*)0); |
9980 | char *cdr_event_mode = NULL((void*)0); |
9981 | char *terminate_on_silence = NULL((void*)0); |
9982 | char *endconf_grace_time = NULL((void*)0); |
9983 | char uuid_str[SWITCH_UUID_FORMATTED_LENGTH256+1]; |
9984 | switch_uuid_t uuid; |
9985 | switch_codec_implementation_t read_impl = { 0 }; |
9986 | switch_channel_t *channel = NULL((void*)0); |
9987 | const char *force_rate = NULL((void*)0), *force_interval = NULL((void*)0), *force_channels = NULL((void*)0), *presence_id = NULL((void*)0); |
9988 | uint32_t force_rate_i = 0, force_interval_i = 0, force_channels_i = 0; |
9989 | |
9990 | /* Validate the conference name */ |
9991 | if (zstr(name)_zstr(name)) { |
9992 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 9992, ((void*)0), SWITCH_LOG_ERROR, "Invalid Record! no name.\n"); |
9993 | return NULL((void*)0); |
9994 | } |
9995 | |
9996 | if (session) { |
9997 | uint32_t tmp; |
9998 | |
9999 | switch_core_session_get_read_impl(session, &read_impl); |
10000 | channel = switch_core_session_get_channel(session); |
10001 | |
10002 | presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE , -1); |
10003 | |
10004 | if ((force_rate = switch_channel_get_variable(channel, "conference_force_rate")switch_channel_get_variable_dup(channel, "conference_force_rate" , SWITCH_TRUE, -1))) { |
10005 | if (!strcasecmp(force_rate, "auto")) { |
10006 | force_rate_i = read_impl.actual_samples_per_second; |
10007 | } else { |
10008 | tmp = atoi(force_rate); |
10009 | |
10010 | if (tmp == 8000 || tmp == 12000 || tmp == 16000 || tmp == 24000 || tmp == 32000 || tmp == 44100 || tmp == 48000) { |
10011 | force_rate_i = rate = tmp; |
10012 | } |
10013 | } |
10014 | } |
10015 | |
10016 | if ((force_channels = switch_channel_get_variable(channel, "conference_force_channels")switch_channel_get_variable_dup(channel, "conference_force_channels" , SWITCH_TRUE, -1))) { |
10017 | if (!strcasecmp(force_channels, "auto")) { |
10018 | force_rate_i = read_impl.number_of_channels; |
10019 | } else { |
10020 | tmp = atoi(force_channels); |
10021 | |
10022 | if (tmp == 1 || tmp == 2) { |
10023 | force_channels_i = channels = tmp; |
10024 | } |
10025 | } |
10026 | } |
10027 | |
10028 | if ((force_interval = switch_channel_get_variable(channel, "conference_force_interval")switch_channel_get_variable_dup(channel, "conference_force_interval" , SWITCH_TRUE, -1))) { |
10029 | if (!strcasecmp(force_interval, "auto")) { |
10030 | force_interval_i = read_impl.microseconds_per_packet / 1000; |
10031 | } else { |
10032 | tmp = atoi(force_interval); |
10033 | |
10034 | if (SWITCH_ACCEPTABLE_INTERVAL(tmp)(tmp && tmp <= 120 && (tmp % 10) == 0)) { |
10035 | force_interval_i = interval = tmp; |
10036 | } |
10037 | } |
10038 | } |
10039 | } |
10040 | |
10041 | switch_mutex_lock(globals.hash_mutex); |
10042 | |
10043 | /* parse the profile tree for param values */ |
10044 | if (cfg.profile) |
10045 | for (xml_kvp = switch_xml_child(cfg.profile, "param"); xml_kvp; xml_kvp = xml_kvp->next) { |
10046 | char *var = (char *) switch_xml_attr_soft(xml_kvp, "name"); |
10047 | char *val = (char *) switch_xml_attr_soft(xml_kvp, "value"); |
10048 | char buf[128] = ""; |
10049 | char *p; |
10050 | |
10051 | if (strchr(var, '_')(__extension__ (__builtin_constant_p ('_') && !__builtin_constant_p (var) && ('_') == '\0' ? (char *) __rawmemchr (var, '_' ) : __builtin_strchr (var, '_')))) { |
10052 | switch_copy_string(buf, var, sizeof(buf)); |
10053 | for (p = buf; *p; p++) { |
10054 | if (*p == '_') { |
10055 | *p = '-'; |
10056 | } |
10057 | } |
10058 | var = buf; |
10059 | } |
10060 | |
10061 | if (!force_rate_i && !strcasecmp(var, "rate") && !zstr(val)_zstr(val)) { |
10062 | uint32_t tmp = atoi(val); |
10063 | if (session && tmp == 0) { |
10064 | if (!strcasecmp(val, "auto")) { |
10065 | rate = read_impl.actual_samples_per_second; |
10066 | } |
10067 | } else { |
10068 | if (tmp == 8000 || tmp == 12000 || tmp == 16000 || tmp == 24000 || tmp == 32000 || tmp == 44100 || tmp == 48000) { |
10069 | rate = tmp; |
10070 | } |
10071 | } |
10072 | } else if (!force_channels_i && !strcasecmp(var, "channels") && !zstr(val)_zstr(val)) { |
10073 | uint32_t tmp = atoi(val); |
10074 | if (session && tmp == 0) { |
10075 | if (!strcasecmp(val, "auto")) { |
10076 | channels = read_impl.number_of_channels; |
10077 | } |
10078 | } else { |
10079 | if (tmp == 1 || tmp == 2) { |
10080 | channels = tmp; |
10081 | } |
10082 | } |
10083 | } else if (!strcasecmp(var, "domain") && !zstr(val)_zstr(val)) { |
10084 | domain = val; |
10085 | } else if (!strcasecmp(var, "description") && !zstr(val)_zstr(val)) { |
10086 | desc = val; |
10087 | } else if (!force_interval_i && !strcasecmp(var, "interval") && !zstr(val)_zstr(val)) { |
10088 | uint32_t tmp = atoi(val); |
10089 | |
10090 | if (session && tmp == 0) { |
10091 | if (!strcasecmp(val, "auto")) { |
10092 | interval = read_impl.microseconds_per_packet / 1000; |
10093 | } |
10094 | } else { |
10095 | if (SWITCH_ACCEPTABLE_INTERVAL(tmp)(tmp && tmp <= 120 && (tmp % 10) == 0)) { |
10096 | interval = tmp; |
10097 | } else { |
10098 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10098, ((void*)0), SWITCH_LOG_WARNING, |
10099 | "Interval must be multipe of 10 and less than %d, Using default of 20\n", SWITCH_MAX_INTERVAL120); |
10100 | } |
10101 | } |
10102 | } else if (!strcasecmp(var, "timer-name") && !zstr(val)_zstr(val)) { |
10103 | timer_name = val; |
10104 | } else if (!strcasecmp(var, "tts-engine") && !zstr(val)_zstr(val)) { |
10105 | tts_engine = val; |
10106 | } else if (!strcasecmp(var, "tts-voice") && !zstr(val)_zstr(val)) { |
10107 | tts_voice = val; |
10108 | } else if (!strcasecmp(var, "enter-sound") && !zstr(val)_zstr(val)) { |
10109 | enter_sound = val; |
10110 | } else if (!strcasecmp(var, "outcall-templ") && !zstr(val)_zstr(val)) { |
10111 | outcall_templ = val; |
10112 | } else if (!strcasecmp(var, "exit-sound") && !zstr(val)_zstr(val)) { |
10113 | exit_sound = val; |
10114 | } else if (!strcasecmp(var, "alone-sound") && !zstr(val)_zstr(val)) { |
10115 | alone_sound = val; |
10116 | } else if (!strcasecmp(var, "perpetual-sound") && !zstr(val)_zstr(val)) { |
10117 | perpetual_sound = val; |
10118 | } else if (!strcasecmp(var, "moh-sound") && !zstr(val)_zstr(val)) { |
10119 | moh_sound = val; |
10120 | } else if (!strcasecmp(var, "ack-sound") && !zstr(val)_zstr(val)) { |
10121 | ack_sound = val; |
10122 | } else if (!strcasecmp(var, "nack-sound") && !zstr(val)_zstr(val)) { |
10123 | nack_sound = val; |
10124 | } else if (!strcasecmp(var, "muted-sound") && !zstr(val)_zstr(val)) { |
10125 | muted_sound = val; |
10126 | } else if (!strcasecmp(var, "mute-detect-sound") && !zstr(val)_zstr(val)) { |
10127 | mute_detect_sound = val; |
10128 | } else if (!strcasecmp(var, "unmuted-sound") && !zstr(val)_zstr(val)) { |
10129 | unmuted_sound = val; |
10130 | } else if (!strcasecmp(var, "locked-sound") && !zstr(val)_zstr(val)) { |
10131 | locked_sound = val; |
10132 | } else if (!strcasecmp(var, "is-locked-sound") && !zstr(val)_zstr(val)) { |
10133 | is_locked_sound = val; |
10134 | } else if (!strcasecmp(var, "is-unlocked-sound") && !zstr(val)_zstr(val)) { |
10135 | is_unlocked_sound = val; |
10136 | } else if (!strcasecmp(var, "member-flags") && !zstr(val)_zstr(val)) { |
10137 | member_flags = val; |
10138 | } else if (!strcasecmp(var, "conference-flags") && !zstr(val)_zstr(val)) { |
10139 | conference_flags = val; |
10140 | } else if (!strcasecmp(var, "cdr-log-dir") && !zstr(val)_zstr(val)) { |
10141 | conference_log_dir = val; |
10142 | } else if (!strcasecmp(var, "cdr-event-mode") && !zstr(val)_zstr(val)) { |
10143 | cdr_event_mode = val; |
10144 | } else if (!strcasecmp(var, "kicked-sound") && !zstr(val)_zstr(val)) { |
10145 | kicked_sound = val; |
10146 | } else if (!strcasecmp(var, "join-only-sound") && !zstr(val)_zstr(val)) { |
10147 | join_only_sound = val; |
10148 | } else if (!strcasecmp(var, "pin") && !zstr(val)_zstr(val)) { |
10149 | pin = val; |
10150 | } else if (!strcasecmp(var, "moderator-pin") && !zstr(val)_zstr(val)) { |
10151 | mpin = val; |
10152 | } else if (!strcasecmp(var, "pin-retries") && !zstr(val)_zstr(val)) { |
10153 | int tmp = atoi(val); |
10154 | if (tmp >= 0) { |
10155 | pin_retries = tmp; |
10156 | } |
10157 | } else if (!strcasecmp(var, "pin-sound") && !zstr(val)_zstr(val)) { |
10158 | pin_sound = val; |
10159 | } else if (!strcasecmp(var, "bad-pin-sound") && !zstr(val)_zstr(val)) { |
10160 | bad_pin_sound = val; |
10161 | } else if (!strcasecmp(var, "energy-level") && !zstr(val)_zstr(val)) { |
10162 | energy_level = val; |
10163 | } else if (!strcasecmp(var, "auto-gain-level") && !zstr(val)_zstr(val)) { |
10164 | auto_gain_level = val; |
10165 | } else if (!strcasecmp(var, "caller-id-name") && !zstr(val)_zstr(val)) { |
10166 | caller_id_name = val; |
10167 | } else if (!strcasecmp(var, "caller-id-number") && !zstr(val)_zstr(val)) { |
10168 | caller_id_number = val; |
10169 | } else if (!strcasecmp(var, "caller-controls") && !zstr(val)_zstr(val)) { |
10170 | caller_controls = val; |
10171 | } else if (!strcasecmp(var, "ivr-dtmf-timeout") && !zstr(val)_zstr(val)) { |
10172 | ivr_dtmf_timeout = atoi(val); |
10173 | if (ivr_dtmf_timeout < 500) { |
10174 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10174, ((void*)0), SWITCH_LOG_WARNING, "not very smart value for ivr-dtmf-timeout found (%d), defaulting to 500ms\n", ivr_dtmf_timeout); |
10175 | ivr_dtmf_timeout = 500; |
10176 | } |
10177 | } else if (!strcasecmp(var, "ivr-input-timeout") && !zstr(val)_zstr(val)) { |
10178 | ivr_input_timeout = atoi(val); |
10179 | if (ivr_input_timeout != 0 && ivr_input_timeout < 500) { |
10180 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10180, ((void*)0), SWITCH_LOG_WARNING, "not very smart value for ivr-input-timeout found (%d), defaulting to 500ms\n", ivr_input_timeout); |
10181 | ivr_input_timeout = 5000; |
10182 | } |
10183 | } else if (!strcasecmp(var, "moderator-controls") && !zstr(val)_zstr(val)) { |
10184 | moderator_controls = val; |
10185 | } else if (!strcasecmp(var, "broadcast-chat-messages") && !zstr(val)_zstr(val)) { |
10186 | broadcast_chat_messages = switch_true(val); |
10187 | } else if (!strcasecmp(var, "comfort-noise") && !zstr(val)_zstr(val)) { |
10188 | int tmp; |
10189 | tmp = atoi(val); |
10190 | if (tmp > 1 && tmp < 10000) { |
10191 | comfort_noise_level = tmp; |
10192 | } else if (switch_true(val)) { |
10193 | comfort_noise_level = 1400; |
10194 | } |
10195 | } else if (!strcasecmp(var, "sound-prefix") && !zstr(val)_zstr(val)) { |
10196 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10196, ((void*)0), SWITCH_LOG_DEBUG, "override sound-prefix with: %s\n", val); |
10197 | sound_prefix = val; |
10198 | } else if (!strcasecmp(var, "max-members") && !zstr(val)_zstr(val)) { |
10199 | errno(*__errno_location ()) = 0; /* sanity first */ |
10200 | max_members = strtol(val, NULL((void*)0), 0); /* base 0 lets 0x... for hex 0... for octal and base 10 otherwise through */ |
10201 | if (errno(*__errno_location ()) == ERANGE34 || errno(*__errno_location ()) == EINVAL22 || (int32_t) max_members < 0 || max_members == 1) { |
10202 | /* a negative wont work well, and its foolish to have a conference limited to 1 person unless the outbound |
10203 | * stuff is added, see comments above |
10204 | */ |
10205 | max_members = 0; /* set to 0 to disable max counts */ |
10206 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10206, ((void*)0), SWITCH_LOG_ERROR, "max-members %s is invalid, not setting a limit\n", val); |
10207 | } |
10208 | } else if (!strcasecmp(var, "max-members-sound") && !zstr(val)_zstr(val)) { |
10209 | maxmember_sound = val; |
10210 | } else if (!strcasecmp(var, "announce-count") && !zstr(val)_zstr(val)) { |
10211 | errno(*__errno_location ()) = 0; /* safety first */ |
10212 | announce_count = strtol(val, NULL((void*)0), 0); |
10213 | if (errno(*__errno_location ()) == ERANGE34 || errno(*__errno_location ()) == EINVAL22) { |
10214 | announce_count = 0; |
10215 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10215, ((void*)0), SWITCH_LOG_ERROR, "announce-count is invalid, not anouncing member counts\n"); |
10216 | } |
10217 | } else if (!strcasecmp(var, "suppress-events") && !zstr(val)_zstr(val)) { |
10218 | suppress_events = val; |
10219 | } else if (!strcasecmp(var, "verbose-events") && !zstr(val)_zstr(val)) { |
10220 | verbose_events = val; |
10221 | } else if (!strcasecmp(var, "auto-record") && !zstr(val)_zstr(val)) { |
10222 | auto_record = val; |
10223 | } else if (!strcasecmp(var, "min-required-recording-participants") && !zstr(val)_zstr(val)) { |
10224 | if (!strcmp(val, "1")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (val) && __builtin_constant_p ("1") && (__s1_len = __builtin_strlen (val), __s2_len = __builtin_strlen ("1"), (!((size_t)(const void *)((val) + 1) - (size_t)(const void * )(val) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("1") + 1) - (size_t)(const void *)("1") == 1) || __s2_len >= 4)) ? __builtin_strcmp (val, "1") : (__builtin_constant_p (val) && ((size_t)(const void *)((val) + 1) - (size_t )(const void *)(val) == 1) && (__s1_len = __builtin_strlen (val), __s1_len < 4) ? (__builtin_constant_p ("1") && ((size_t)(const void *)(("1") + 1) - (size_t)(const void *)( "1") == 1) ? __builtin_strcmp (val, "1") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("1"); int __result = (((const unsigned char *) (const char * ) (val))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( val))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (val ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (val))[ 3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("1" ) && ((size_t)(const void *)(("1") + 1) - (size_t)(const void *)("1") == 1) && (__s2_len = __builtin_strlen ( "1"), __s2_len < 4) ? (__builtin_constant_p (val) && ((size_t)(const void *)((val) + 1) - (size_t)(const void *)( val) == 1) ? __builtin_strcmp (val, "1") : (- (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (val); int __result = (((const unsigned char *) (const char *) ("1"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "1"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("1" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("1"))[ 3] - __s2[3]); } } __result; })))) : __builtin_strcmp (val, "1" )))); })) { |
10225 | min_recording_participants = 1; |
10226 | } else if (!strcmp(val, "2")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (val) && __builtin_constant_p ("2") && (__s1_len = __builtin_strlen (val), __s2_len = __builtin_strlen ("2"), (!((size_t)(const void *)((val) + 1) - (size_t)(const void * )(val) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("2") + 1) - (size_t)(const void *)("2") == 1) || __s2_len >= 4)) ? __builtin_strcmp (val, "2") : (__builtin_constant_p (val) && ((size_t)(const void *)((val) + 1) - (size_t )(const void *)(val) == 1) && (__s1_len = __builtin_strlen (val), __s1_len < 4) ? (__builtin_constant_p ("2") && ((size_t)(const void *)(("2") + 1) - (size_t)(const void *)( "2") == 1) ? __builtin_strcmp (val, "2") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("2"); int __result = (((const unsigned char *) (const char * ) (val))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( val))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (val ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (val))[ 3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("2" ) && ((size_t)(const void *)(("2") + 1) - (size_t)(const void *)("2") == 1) && (__s2_len = __builtin_strlen ( "2"), __s2_len < 4) ? (__builtin_constant_p (val) && ((size_t)(const void *)((val) + 1) - (size_t)(const void *)( val) == 1) ? __builtin_strcmp (val, "2") : (- (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (val); int __result = (((const unsigned char *) (const char *) ("2"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "2"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("2" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("2"))[ 3] - __s2[3]); } } __result; })))) : __builtin_strcmp (val, "2" )))); })) { |
10227 | min_recording_participants = 2; |
10228 | } else { |
10229 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10229, ((void*)0), SWITCH_LOG_ERROR, "min-required-recording-participants is invalid, leaving set to %d\n", min_recording_participants); |
10230 | } |
10231 | } else if (!strcasecmp(var, "terminate-on-silence") && !zstr(val)_zstr(val)) { |
10232 | terminate_on_silence = val; |
10233 | } else if (!strcasecmp(var, "endconf-grace-time") && !zstr(val)_zstr(val)) { |
10234 | endconf_grace_time = val; |
10235 | } |
10236 | } |
10237 | |
10238 | /* Set defaults and various paramaters */ |
10239 | |
10240 | /* Timer module to use */ |
10241 | if (zstr(timer_name)_zstr(timer_name)) { |
10242 | timer_name = "soft"; |
10243 | } |
10244 | |
10245 | /* Caller ID Name */ |
10246 | if (zstr(caller_id_name)_zstr(caller_id_name)) { |
10247 | caller_id_name = (char *) global_app_name; |
10248 | } |
10249 | |
10250 | /* Caller ID Number */ |
10251 | if (zstr(caller_id_number)_zstr(caller_id_number)) { |
10252 | caller_id_number = SWITCH_DEFAULT_CLID_NUMBER"0000000000"; |
10253 | } |
10254 | |
10255 | if (!pool) { |
10256 | /* Setup a memory pool to use. */ |
10257 | if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 10257) != SWITCH_STATUS_SUCCESS) { |
10258 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10258, ((void*)0), SWITCH_LOG_CRIT, "Pool Failure\n"); |
10259 | conference = NULL((void*)0); |
10260 | goto end; |
10261 | } |
10262 | } |
10263 | |
10264 | /* Create the conference object. */ |
10265 | if (!(conference = switch_core_alloc(pool, sizeof(*conference))switch_core_perform_alloc(pool, sizeof(*conference), "mod_conference.c" , (const char *)__func__, 10265))) { |
10266 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10266, ((void*)0), SWITCH_LOG_CRIT, "Memory Error!\n"); |
10267 | conference = NULL((void*)0); |
10268 | goto end; |
10269 | } |
10270 | |
10271 | conference->start_time = switch_epoch_time_now(NULL((void*)0)); |
10272 | |
10273 | /* initialize the conference object with settings from the specified profile */ |
10274 | conference->pool = pool; |
10275 | conference->profile_name = switch_core_strdup(conference->pool, cfg.profile ? switch_xml_attr_soft(cfg.profile, "name") : "none")switch_core_perform_strdup(conference->pool, cfg.profile ? switch_xml_attr_soft(cfg.profile, "name") : "none", "mod_conference.c" , (const char *)__func__, 10275); |
10276 | if (timer_name) { |
10277 | conference->timer_name = switch_core_strdup(conference->pool, timer_name)switch_core_perform_strdup(conference->pool, timer_name, "mod_conference.c" , (const char *)__func__, 10277); |
10278 | } |
10279 | if (tts_engine) { |
10280 | conference->tts_engine = switch_core_strdup(conference->pool, tts_engine)switch_core_perform_strdup(conference->pool, tts_engine, "mod_conference.c" , (const char *)__func__, 10280); |
10281 | } |
10282 | if (tts_voice) { |
10283 | conference->tts_voice = switch_core_strdup(conference->pool, tts_voice)switch_core_perform_strdup(conference->pool, tts_voice, "mod_conference.c" , (const char *)__func__, 10283); |
10284 | } |
10285 | |
10286 | conference->comfort_noise_level = comfort_noise_level; |
10287 | conference->pin_retries = pin_retries; |
10288 | conference->caller_id_name = switch_core_strdup(conference->pool, caller_id_name)switch_core_perform_strdup(conference->pool, caller_id_name , "mod_conference.c", (const char *)__func__, 10288); |
10289 | conference->caller_id_number = switch_core_strdup(conference->pool, caller_id_number)switch_core_perform_strdup(conference->pool, caller_id_number , "mod_conference.c", (const char *)__func__, 10289); |
10290 | conference->caller_controls = switch_core_strdup(conference->pool, caller_controls)switch_core_perform_strdup(conference->pool, caller_controls , "mod_conference.c", (const char *)__func__, 10290); |
10291 | conference->moderator_controls = switch_core_strdup(conference->pool, moderator_controls)switch_core_perform_strdup(conference->pool, moderator_controls , "mod_conference.c", (const char *)__func__, 10291); |
10292 | conference->broadcast_chat_messages = broadcast_chat_messages; |
10293 | |
10294 | if (outcall_templ) { |
10295 | conference->outcall_templ = switch_core_strdup(conference->pool, outcall_templ)switch_core_perform_strdup(conference->pool, outcall_templ , "mod_conference.c", (const char *)__func__, 10295); |
10296 | } |
10297 | conference->run_time = switch_epoch_time_now(NULL((void*)0)); |
10298 | |
10299 | if (!zstr(conference_log_dir)_zstr(conference_log_dir)) { |
10300 | char *path; |
10301 | |
10302 | if (!strcmp(conference_log_dir, "auto")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (conference_log_dir) && __builtin_constant_p ("auto" ) && (__s1_len = __builtin_strlen (conference_log_dir ), __s2_len = __builtin_strlen ("auto"), (!((size_t)(const void *)((conference_log_dir) + 1) - (size_t)(const void *)(conference_log_dir ) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("auto") + 1) - (size_t)(const void *)("auto") == 1) || __s2_len >= 4)) ? __builtin_strcmp (conference_log_dir, "auto") : ( __builtin_constant_p (conference_log_dir) && ((size_t )(const void *)((conference_log_dir) + 1) - (size_t)(const void *)(conference_log_dir) == 1) && (__s1_len = __builtin_strlen (conference_log_dir), __s1_len < 4) ? (__builtin_constant_p ("auto") && ((size_t)(const void *)(("auto") + 1) - ( size_t)(const void *)("auto") == 1) ? __builtin_strcmp (conference_log_dir , "auto") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("auto"); int __result = ((( const unsigned char *) (const char *) (conference_log_dir))[0 ] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (conference_log_dir ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (conference_log_dir ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (conference_log_dir ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "auto") && ((size_t)(const void *)(("auto") + 1) - (size_t )(const void *)("auto") == 1) && (__s2_len = __builtin_strlen ("auto"), __s2_len < 4) ? (__builtin_constant_p (conference_log_dir ) && ((size_t)(const void *)((conference_log_dir) + 1 ) - (size_t)(const void *)(conference_log_dir) == 1) ? __builtin_strcmp (conference_log_dir, "auto") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (conference_log_dir ); int __result = (((const unsigned char *) (const char *) ("auto" ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("auto" ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("auto" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("auto" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (conference_log_dir , "auto")))); })) { |
10303 | path = switch_core_sprintf(conference->pool, "%s%sconference_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/"); |
10304 | } else if (!switch_is_file_path(conference_log_dir)) { |
10305 | path = switch_core_sprintf(conference->pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/", conference_log_dir); |
10306 | } else { |
10307 | path = switch_core_strdup(conference->pool, conference_log_dir)switch_core_perform_strdup(conference->pool, conference_log_dir , "mod_conference.c", (const char *)__func__, 10307); |
10308 | } |
10309 | |
10310 | switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, conference->pool); |
10311 | conference->log_dir = path; |
10312 | |
10313 | } |
10314 | |
10315 | if (!zstr(cdr_event_mode)_zstr(cdr_event_mode)) { |
10316 | if (!strcmp(cdr_event_mode, "content")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (cdr_event_mode) && __builtin_constant_p ("content") && (__s1_len = __builtin_strlen (cdr_event_mode), __s2_len = __builtin_strlen ("content"), (!((size_t)(const void *)((cdr_event_mode ) + 1) - (size_t)(const void *)(cdr_event_mode) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("content") + 1 ) - (size_t)(const void *)("content") == 1) || __s2_len >= 4)) ? __builtin_strcmp (cdr_event_mode, "content") : (__builtin_constant_p (cdr_event_mode) && ((size_t)(const void *)((cdr_event_mode ) + 1) - (size_t)(const void *)(cdr_event_mode) == 1) && (__s1_len = __builtin_strlen (cdr_event_mode), __s1_len < 4) ? (__builtin_constant_p ("content") && ((size_t)( const void *)(("content") + 1) - (size_t)(const void *)("content" ) == 1) ? __builtin_strcmp (cdr_event_mode, "content") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("content"); int __result = (((const unsigned char * ) (const char *) (cdr_event_mode))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (cdr_event_mode))[1] - __s2[1]); if ( __s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (cdr_event_mode))[2] - __s2[ 2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (cdr_event_mode))[3 ] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("content" ) && ((size_t)(const void *)(("content") + 1) - (size_t )(const void *)("content") == 1) && (__s2_len = __builtin_strlen ("content"), __s2_len < 4) ? (__builtin_constant_p (cdr_event_mode ) && ((size_t)(const void *)((cdr_event_mode) + 1) - ( size_t)(const void *)(cdr_event_mode) == 1) ? __builtin_strcmp (cdr_event_mode, "content") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (cdr_event_mode ); int __result = (((const unsigned char *) (const char *) ("content" ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("content" ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("content" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("content" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (cdr_event_mode , "content")))); })) { |
10317 | conference->cdr_event_mode = CDRE_AS_CONTENT; |
10318 | } else if (!strcmp(cdr_event_mode, "file")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (cdr_event_mode) && __builtin_constant_p ("file") && (__s1_len = __builtin_strlen (cdr_event_mode), __s2_len = __builtin_strlen ("file"), (!((size_t)(const void *)((cdr_event_mode) + 1) - ( size_t)(const void *)(cdr_event_mode) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("file") + 1) - (size_t )(const void *)("file") == 1) || __s2_len >= 4)) ? __builtin_strcmp (cdr_event_mode, "file") : (__builtin_constant_p (cdr_event_mode ) && ((size_t)(const void *)((cdr_event_mode) + 1) - ( size_t)(const void *)(cdr_event_mode) == 1) && (__s1_len = __builtin_strlen (cdr_event_mode), __s1_len < 4) ? (__builtin_constant_p ("file") && ((size_t)(const void *)(("file") + 1) - ( size_t)(const void *)("file") == 1) ? __builtin_strcmp (cdr_event_mode , "file") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("file"); int __result = ((( const unsigned char *) (const char *) (cdr_event_mode))[0] - __s2 [0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (cdr_event_mode)) [1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (cdr_event_mode ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (cdr_event_mode ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( "file") && ((size_t)(const void *)(("file") + 1) - (size_t )(const void *)("file") == 1) && (__s2_len = __builtin_strlen ("file"), __s2_len < 4) ? (__builtin_constant_p (cdr_event_mode ) && ((size_t)(const void *)((cdr_event_mode) + 1) - ( size_t)(const void *)(cdr_event_mode) == 1) ? __builtin_strcmp (cdr_event_mode, "file") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (cdr_event_mode ); int __result = (((const unsigned char *) (const char *) ("file" ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("file" ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("file" ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("file" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (cdr_event_mode , "file")))); })) { |
10319 | if (!zstr(conference->log_dir)_zstr(conference->log_dir)) { |
10320 | conference->cdr_event_mode = CDRE_AS_FILE; |
10321 | } else { |
10322 | conference->cdr_event_mode = CDRE_NONE; |
10323 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10323, ((void*)0), SWITCH_LOG_WARNING, "'cdr-log-dir' parameter not set; CDR event mode 'file' ignored"); |
10324 | } |
10325 | } else { |
10326 | conference->cdr_event_mode = CDRE_NONE; |
10327 | } |
10328 | } |
10329 | |
10330 | if (!zstr(perpetual_sound)_zstr(perpetual_sound)) { |
10331 | conference->perpetual_sound = switch_core_strdup(conference->pool, perpetual_sound)switch_core_perform_strdup(conference->pool, perpetual_sound , "mod_conference.c", (const char *)__func__, 10331); |
10332 | } |
10333 | |
10334 | conference->mflags = MFLAG_CAN_SPEAK | MFLAG_CAN_HEAR; |
10335 | |
10336 | if (!zstr(moh_sound)_zstr(moh_sound) && switch_is_moh(moh_sound)) { |
10337 | conference->moh_sound = switch_core_strdup(conference->pool, moh_sound)switch_core_perform_strdup(conference->pool, moh_sound, "mod_conference.c" , (const char *)__func__, 10337); |
10338 | } |
10339 | |
10340 | if (member_flags) { |
10341 | set_mflags(member_flags, &conference->mflags); |
10342 | } |
10343 | |
10344 | if (conference_flags) { |
10345 | set_cflags(conference_flags, &conference->flags); |
10346 | } |
10347 | |
10348 | if (!zstr(sound_prefix)_zstr(sound_prefix)) { |
10349 | conference->sound_prefix = switch_core_strdup(conference->pool, sound_prefix)switch_core_perform_strdup(conference->pool, sound_prefix, "mod_conference.c", (const char *)__func__, 10349); |
10350 | } else { |
10351 | const char *val; |
10352 | if ((val = switch_channel_get_variable(channel, "sound_prefix")switch_channel_get_variable_dup(channel, "sound_prefix", SWITCH_TRUE , -1)) && !zstr(val)_zstr(val)) { |
10353 | /* if no sound_prefix was set, use the channel sound_prefix */ |
10354 | conference->sound_prefix = switch_core_strdup(conference->pool, val)switch_core_perform_strdup(conference->pool, val, "mod_conference.c" , (const char *)__func__, 10354); |
10355 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10355, ((void*)0), SWITCH_LOG_INFO, "using channel sound prefix: %s\n", conference->sound_prefix); |
10356 | } |
10357 | } |
10358 | |
10359 | if (!zstr(enter_sound)_zstr(enter_sound)) { |
10360 | conference->enter_sound = switch_core_strdup(conference->pool, enter_sound)switch_core_perform_strdup(conference->pool, enter_sound, "mod_conference.c" , (const char *)__func__, 10360); |
10361 | } |
10362 | |
10363 | if (!zstr(exit_sound)_zstr(exit_sound)) { |
10364 | conference->exit_sound = switch_core_strdup(conference->pool, exit_sound)switch_core_perform_strdup(conference->pool, exit_sound, "mod_conference.c" , (const char *)__func__, 10364); |
10365 | } |
10366 | |
10367 | if (!zstr(ack_sound)_zstr(ack_sound)) { |
10368 | conference->ack_sound = switch_core_strdup(conference->pool, ack_sound)switch_core_perform_strdup(conference->pool, ack_sound, "mod_conference.c" , (const char *)__func__, 10368); |
10369 | } |
10370 | |
10371 | if (!zstr(nack_sound)_zstr(nack_sound)) { |
10372 | conference->nack_sound = switch_core_strdup(conference->pool, nack_sound)switch_core_perform_strdup(conference->pool, nack_sound, "mod_conference.c" , (const char *)__func__, 10372); |
10373 | } |
10374 | |
10375 | if (!zstr(muted_sound)_zstr(muted_sound)) { |
10376 | conference->muted_sound = switch_core_strdup(conference->pool, muted_sound)switch_core_perform_strdup(conference->pool, muted_sound, "mod_conference.c" , (const char *)__func__, 10376); |
10377 | } |
10378 | |
10379 | if (zstr(mute_detect_sound)_zstr(mute_detect_sound)) { |
10380 | if (!zstr(muted_sound)_zstr(muted_sound)) { |
10381 | conference->mute_detect_sound = switch_core_strdup(conference->pool, muted_sound)switch_core_perform_strdup(conference->pool, muted_sound, "mod_conference.c" , (const char *)__func__, 10381); |
10382 | } |
10383 | } else { |
10384 | conference->mute_detect_sound = switch_core_strdup(conference->pool, mute_detect_sound)switch_core_perform_strdup(conference->pool, mute_detect_sound , "mod_conference.c", (const char *)__func__, 10384); |
10385 | } |
10386 | |
10387 | if (!zstr(unmuted_sound)_zstr(unmuted_sound)) { |
10388 | conference->unmuted_sound = switch_core_strdup(conference->pool, unmuted_sound)switch_core_perform_strdup(conference->pool, unmuted_sound , "mod_conference.c", (const char *)__func__, 10388); |
10389 | } |
10390 | |
10391 | if (!zstr(kicked_sound)_zstr(kicked_sound)) { |
10392 | conference->kicked_sound = switch_core_strdup(conference->pool, kicked_sound)switch_core_perform_strdup(conference->pool, kicked_sound, "mod_conference.c", (const char *)__func__, 10392); |
10393 | } |
10394 | |
10395 | if (!zstr(join_only_sound)_zstr(join_only_sound)) { |
10396 | conference->join_only_sound = switch_core_strdup(conference->pool, join_only_sound)switch_core_perform_strdup(conference->pool, join_only_sound , "mod_conference.c", (const char *)__func__, 10396); |
10397 | } |
10398 | |
10399 | if (!zstr(pin_sound)_zstr(pin_sound)) { |
10400 | conference->pin_sound = switch_core_strdup(conference->pool, pin_sound)switch_core_perform_strdup(conference->pool, pin_sound, "mod_conference.c" , (const char *)__func__, 10400); |
10401 | } |
10402 | |
10403 | if (!zstr(bad_pin_sound)_zstr(bad_pin_sound)) { |
10404 | conference->bad_pin_sound = switch_core_strdup(conference->pool, bad_pin_sound)switch_core_perform_strdup(conference->pool, bad_pin_sound , "mod_conference.c", (const char *)__func__, 10404); |
10405 | } |
10406 | |
10407 | if (!zstr(pin)_zstr(pin)) { |
10408 | conference->pin = switch_core_strdup(conference->pool, pin)switch_core_perform_strdup(conference->pool, pin, "mod_conference.c" , (const char *)__func__, 10408); |
10409 | } |
10410 | |
10411 | if (!zstr(mpin)_zstr(mpin)) { |
10412 | conference->mpin = switch_core_strdup(conference->pool, mpin)switch_core_perform_strdup(conference->pool, mpin, "mod_conference.c" , (const char *)__func__, 10412); |
10413 | } |
10414 | |
10415 | if (!zstr(alone_sound)_zstr(alone_sound)) { |
10416 | conference->alone_sound = switch_core_strdup(conference->pool, alone_sound)switch_core_perform_strdup(conference->pool, alone_sound, "mod_conference.c" , (const char *)__func__, 10416); |
10417 | } |
10418 | |
10419 | if (!zstr(locked_sound)_zstr(locked_sound)) { |
10420 | conference->locked_sound = switch_core_strdup(conference->pool, locked_sound)switch_core_perform_strdup(conference->pool, locked_sound, "mod_conference.c", (const char *)__func__, 10420); |
10421 | } |
10422 | |
10423 | if (!zstr(is_locked_sound)_zstr(is_locked_sound)) { |
10424 | conference->is_locked_sound = switch_core_strdup(conference->pool, is_locked_sound)switch_core_perform_strdup(conference->pool, is_locked_sound , "mod_conference.c", (const char *)__func__, 10424); |
10425 | } |
10426 | |
10427 | if (!zstr(is_unlocked_sound)_zstr(is_unlocked_sound)) { |
10428 | conference->is_unlocked_sound = switch_core_strdup(conference->pool, is_unlocked_sound)switch_core_perform_strdup(conference->pool, is_unlocked_sound , "mod_conference.c", (const char *)__func__, 10428); |
10429 | } |
10430 | |
10431 | if (!zstr(energy_level)_zstr(energy_level)) { |
10432 | conference->energy_level = atoi(energy_level); |
10433 | if (conference->energy_level < 0) { |
10434 | conference->energy_level = 0; |
10435 | } |
10436 | } |
10437 | |
10438 | if (!zstr(auto_gain_level)_zstr(auto_gain_level)) { |
10439 | int level = 0; |
10440 | |
10441 | if (switch_true(auto_gain_level) && !switch_is_number(auto_gain_level)) { |
10442 | level = DEFAULT_AGC_LEVEL1100; |
10443 | } else { |
10444 | level = atoi(auto_gain_level); |
10445 | } |
10446 | |
10447 | if (level > 0 && level > conference->energy_level) { |
10448 | conference->agc_level = level; |
10449 | } |
10450 | } |
10451 | |
10452 | if (!zstr(maxmember_sound)_zstr(maxmember_sound)) { |
10453 | conference->maxmember_sound = switch_core_strdup(conference->pool, maxmember_sound)switch_core_perform_strdup(conference->pool, maxmember_sound , "mod_conference.c", (const char *)__func__, 10453); |
10454 | } |
10455 | /* its going to be 0 by default, set to a value otherwise so this should be safe */ |
10456 | conference->max_members = max_members; |
10457 | conference->announce_count = announce_count; |
10458 | |
10459 | conference->name = switch_core_strdup(conference->pool, name)switch_core_perform_strdup(conference->pool, name, "mod_conference.c" , (const char *)__func__, 10459); |
10460 | |
10461 | if ((name_domain = strchr(conference->name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conference->name) && ('@') == '\0' ? (char *) __rawmemchr (conference->name, '@') : __builtin_strchr (conference-> name, '@'))))) { |
10462 | name_domain++; |
10463 | conference->domain = switch_core_strdup(conference->pool, name_domain)switch_core_perform_strdup(conference->pool, name_domain, "mod_conference.c" , (const char *)__func__, 10463); |
10464 | } else if (domain) { |
10465 | conference->domain = switch_core_strdup(conference->pool, domain)switch_core_perform_strdup(conference->pool, domain, "mod_conference.c" , (const char *)__func__, 10465); |
10466 | } else if (presence_id && (name_domain = strchr(presence_id, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (presence_id) && ('@') == '\0' ? (char *) __rawmemchr (presence_id, '@') : __builtin_strchr (presence_id, '@'))))) { |
10467 | name_domain++; |
10468 | conference->domain = switch_core_strdup(conference->pool, name_domain)switch_core_perform_strdup(conference->pool, name_domain, "mod_conference.c" , (const char *)__func__, 10468); |
10469 | } else { |
10470 | conference->domain = "cluecon.com"; |
10471 | } |
10472 | |
10473 | conference->chat_id = switch_core_sprintf(conference->pool, "conf+%s@%s", conference->name, conference->domain); |
10474 | |
10475 | conference->channels = channels; |
10476 | conference->rate = rate; |
10477 | conference->interval = interval; |
10478 | conference->ivr_dtmf_timeout = ivr_dtmf_timeout; |
10479 | conference->ivr_input_timeout = ivr_input_timeout; |
10480 | |
10481 | conference->eflags = 0xFFFFFFFF; |
10482 | if (!zstr(suppress_events)_zstr(suppress_events)) { |
10483 | clear_eflags(suppress_events, &conference->eflags); |
10484 | } |
10485 | |
10486 | if (!zstr(auto_record)_zstr(auto_record)) { |
10487 | conference->auto_record = switch_core_strdup(conference->pool, auto_record)switch_core_perform_strdup(conference->pool, auto_record, "mod_conference.c" , (const char *)__func__, 10487); |
10488 | } |
10489 | |
10490 | conference->min_recording_participants = min_recording_participants; |
10491 | |
10492 | if (!zstr(desc)_zstr(desc)) { |
10493 | conference->desc = switch_core_strdup(conference->pool, desc)switch_core_perform_strdup(conference->pool, desc, "mod_conference.c" , (const char *)__func__, 10493); |
10494 | } |
10495 | |
10496 | if (!zstr(terminate_on_silence)_zstr(terminate_on_silence)) { |
10497 | conference->terminate_on_silence = atoi(terminate_on_silence); |
10498 | } |
10499 | if (!zstr(endconf_grace_time)_zstr(endconf_grace_time)) { |
10500 | conference->endconf_grace_time = atoi(endconf_grace_time); |
10501 | } |
10502 | |
10503 | if (!zstr(verbose_events)_zstr(verbose_events) && switch_true(verbose_events)) { |
10504 | conference->verbose_events = 1; |
10505 | } |
10506 | |
10507 | /* Create the conference unique identifier */ |
10508 | switch_uuid_get(&uuid); |
10509 | switch_uuid_format(uuid_str, &uuid); |
10510 | conference->uuid_str = switch_core_strdup(conference->pool, uuid_str)switch_core_perform_strdup(conference->pool, uuid_str, "mod_conference.c" , (const char *)__func__, 10510); |
10511 | |
10512 | /* Set enter sound and exit sound flags so that default is on */ |
10513 | switch_set_flag(conference, CFLAG_ENTER_SOUND)(conference)->flags |= (CFLAG_ENTER_SOUND); |
10514 | switch_set_flag(conference, CFLAG_EXIT_SOUND)(conference)->flags |= (CFLAG_EXIT_SOUND); |
10515 | |
10516 | /* Activate the conference mutex for exclusivity */ |
10517 | switch_mutex_init(&conference->mutex, SWITCH_MUTEX_NESTED0x1, conference->pool); |
10518 | switch_mutex_init(&conference->flag_mutex, SWITCH_MUTEX_NESTED0x1, conference->pool); |
10519 | switch_thread_rwlock_create(&conference->rwlock, conference->pool); |
10520 | switch_mutex_init(&conference->member_mutex, SWITCH_MUTEX_NESTED0x1, conference->pool); |
10521 | |
10522 | switch_mutex_lock(globals.hash_mutex); |
10523 | switch_set_flag(conference, CFLAG_INHASH)(conference)->flags |= (CFLAG_INHASH); |
10524 | switch_core_hash_insert(globals.conference_hash, conference->name, conference)switch_core_hash_insert_destructor(globals.conference_hash, conference ->name, conference, ((void*)0)); |
10525 | switch_mutex_unlock(globals.hash_mutex); |
10526 | |
10527 | end: |
10528 | |
10529 | switch_mutex_unlock(globals.hash_mutex); |
10530 | |
10531 | return conference; |
10532 | } |
10533 | |
10534 | static void conference_send_presence(conference_obj_t *conference) |
10535 | { |
10536 | switch_event_t *event; |
10537 | |
10538 | if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 10538, &event, SWITCH_EVENT_PRESENCE_IN , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
10539 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO"conf"); |
10540 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", conference->name); |
10541 | if (strchr(conference->name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conference->name) && ('@') == '\0' ? (char *) __rawmemchr (conference->name, '@') : __builtin_strchr (conference-> name, '@')))) { |
10542 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", conference->name); |
10543 | } else { |
10544 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain); |
10545 | } |
10546 | |
10547 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); |
10548 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); |
10549 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++); |
10550 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", conference->name); |
10551 | |
10552 | if (conference->count) { |
10553 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "force-status", "Active (%d caller%s)", conference->count, conference->count == 1 ? "" : "s"); |
10554 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_ROUTING"); |
10555 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", conference->count == 1 ? "early" : "confirmed"); |
10556 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "presence-call-direction", conference->count == 1 ? "outbound" : "inbound"); |
10557 | } else { |
10558 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "force-status", "Inactive"); |
10559 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_HANGUP"); |
10560 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "terminated"); |
10561 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound"); |
10562 | } |
10563 | |
10564 | |
10565 | |
10566 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 10566, &event, ((void*)0)); |
10567 | } |
10568 | |
10569 | } |
10570 | #if 0 |
10571 | static uint32_t kickall_matching_var(conference_obj_t *conference, const char *var, const char *val) |
10572 | { |
10573 | conference_member_t *member = NULL((void*)0); |
10574 | const char *vval = NULL((void*)0); |
10575 | uint32_t r = 0; |
10576 | |
10577 | switch_mutex_lock(conference->mutex); |
10578 | switch_mutex_lock(conference->member_mutex); |
10579 | |
10580 | for (member = conference->members; member; member = member->next) { |
10581 | switch_channel_t *channel = NULL((void*)0); |
10582 | |
10583 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
10584 | continue; |
10585 | } |
10586 | |
10587 | channel = switch_core_session_get_channel(member->session); |
10588 | vval = switch_channel_get_variable(channel, var)switch_channel_get_variable_dup(channel, var, SWITCH_TRUE, -1 ); |
10589 | |
10590 | if (vval && !strcmp(vval, val)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (vval) && __builtin_constant_p (val) && (__s1_len = __builtin_strlen (vval), __s2_len = __builtin_strlen (val) , (!((size_t)(const void *)((vval) + 1) - (size_t)(const void *)(vval) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((val) + 1) - (size_t)(const void *)(val) == 1) || __s2_len >= 4)) ? __builtin_strcmp (vval, val) : (__builtin_constant_p (vval) && ((size_t)(const void *)((vval) + 1) - (size_t )(const void *)(vval) == 1) && (__s1_len = __builtin_strlen (vval), __s1_len < 4) ? (__builtin_constant_p (val) && ((size_t)(const void *)((val) + 1) - (size_t)(const void *)( val) == 1) ? __builtin_strcmp (vval, val) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (val); int __result = (((const unsigned char *) (const char *) (vval))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( vval))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( vval))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (vval ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( val) && ((size_t)(const void *)((val) + 1) - (size_t) (const void *)(val) == 1) && (__s2_len = __builtin_strlen (val), __s2_len < 4) ? (__builtin_constant_p (vval) && ((size_t)(const void *)((vval) + 1) - (size_t)(const void *) (vval) == 1) ? __builtin_strcmp (vval, val) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (vval); int __result = (((const unsigned char *) (const char *) (val))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (val))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (val))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (val))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (vval, val)))); })) { |
10591 | switch_set_flag_locked(member, MFLAG_KICKED)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 10591 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_KICKED);switch_mutex_unlock(member ->flag_mutex);; |
10592 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
10593 | switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(member->session, "mod_conference.c" , (const char *)__func__, 10593, SWITCH_SIG_BREAK); |
10594 | r++; |
10595 | } |
10596 | |
10597 | } |
10598 | |
10599 | switch_mutex_unlock(conference->member_mutex); |
10600 | switch_mutex_unlock(conference->mutex); |
10601 | |
10602 | return r; |
10603 | } |
10604 | #endif |
10605 | |
10606 | static void call_setup_event_handler(switch_event_t *event) |
10607 | { |
10608 | switch_status_t status = SWITCH_STATUS_FALSE; |
10609 | conference_obj_t *conference = NULL((void*)0); |
10610 | char *conf = switch_event_get_header(event, "Target-Component")switch_event_get_header_idx(event, "Target-Component", -1); |
10611 | char *domain = switch_event_get_header(event, "Target-Domain")switch_event_get_header_idx(event, "Target-Domain", -1); |
10612 | char *dial_str = switch_event_get_header(event, "Request-Target")switch_event_get_header_idx(event, "Request-Target", -1); |
10613 | char *dial_uri = switch_event_get_header(event, "Request-Target-URI")switch_event_get_header_idx(event, "Request-Target-URI", -1); |
10614 | char *action = switch_event_get_header(event, "Request-Action")switch_event_get_header_idx(event, "Request-Action", -1); |
10615 | char *ext = switch_event_get_header(event, "Request-Target-Extension")switch_event_get_header_idx(event, "Request-Target-Extension" , -1); |
10616 | char *ext_domain = switch_event_get_header(event, "Request-Target-Domain")switch_event_get_header_idx(event, "Request-Target-Domain", - 1); |
10617 | char *full_url = switch_event_get_header(event, "full_url")switch_event_get_header_idx(event, "full_url", -1); |
10618 | char *call_id = switch_event_get_header(event, "Request-Call-ID")switch_event_get_header_idx(event, "Request-Call-ID", -1); |
10619 | |
10620 | if (!ext) ext = dial_str; |
10621 | |
10622 | if (!zstr(conf)_zstr(conf) && !zstr(dial_str)_zstr(dial_str) && !zstr(action)_zstr(action) && (conference = conference_find(conf, domain))) { |
10623 | switch_event_t *var_event; |
10624 | switch_event_header_t *hp; |
10625 | |
10626 | if (switch_test_flag(conference, CFLAG_RFC4579)((conference)->flags & CFLAG_RFC4579)) { |
10627 | char *key = switch_mprintf("conf_%s_%s_%s_%s", conference->name, conference->domain, ext, ext_domain); |
10628 | char *expanded = NULL((void*)0), *ostr = dial_str;; |
10629 | |
10630 | if (!strcasecmp(action, "call")) { |
10631 | if((conference->max_members > 0) && (conference->count >= conference->max_members)) { |
10632 | // Conference member limit has been reached; do not proceed with setup request |
10633 | status = SWITCH_STATUS_FALSE; |
10634 | } else { |
10635 | if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) { |
10636 | abort(); |
10637 | } |
10638 | |
10639 | for(hp = event->headers; hp; hp = hp->next) { |
10640 | if (!strncasecmp(hp->name, "var_", 4)) { |
10641 | switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, hp->name + 4, hp->value); |
10642 | } |
10643 | } |
10644 | |
10645 | switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_call_key", key); |
10646 | switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_destination_number", ext); |
10647 | |
10648 | switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_invite_uri", dial_uri); |
10649 | |
10650 | switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_status", "true"); |
10651 | switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_call_id", call_id); |
10652 | switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_invite_domain", domain); |
10653 | switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_invite_contact_params", "~isfocus"); |
10654 | |
10655 | if (!strncasecmp(ostr, "url+", 4)) { |
10656 | ostr += 4; |
10657 | } else if (!switch_true(full_url) && conference->outcall_templ) { |
10658 | if ((expanded = switch_event_expand_headers(var_event, conference->outcall_templ)switch_event_expand_headers_check(var_event, conference->outcall_templ , ((void*)0), ((void*)0), 0))) { |
10659 | ostr = expanded; |
10660 | } |
10661 | } |
10662 | |
10663 | status = conference_outcall_bg(conference, NULL((void*)0), NULL((void*)0), ostr, 60, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), &var_event); |
10664 | |
10665 | if (expanded && expanded != conference->outcall_templ) { |
10666 | switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);}; |
10667 | } |
10668 | } |
10669 | |
10670 | } else if (!strcasecmp(action, "end")) { |
10671 | if (switch_core_session_hupall_matching_var("conference_call_key", key, SWITCH_CAUSE_NORMAL_CLEARING)switch_core_session_hupall_matching_var_ans("conference_call_key" , key, SWITCH_CAUSE_NORMAL_CLEARING, SHT_UNANSWERED | SHT_ANSWERED )) { |
10672 | send_conference_notify(conference, "SIP/2.0 200 OK\r\n", call_id, SWITCH_TRUE); |
10673 | } else { |
10674 | send_conference_notify(conference, "SIP/2.0 481 Failure\r\n", call_id, SWITCH_TRUE); |
10675 | } |
10676 | status = SWITCH_STATUS_SUCCESS; |
10677 | } |
10678 | |
10679 | switch_safe_free(key)if (key) {free(key);key=((void*)0);}; |
10680 | } else { // Conference found but doesn't support referral. |
10681 | status = SWITCH_STATUS_FALSE; |
10682 | } |
10683 | |
10684 | |
10685 | switch_thread_rwlock_unlock(conference->rwlock); |
10686 | } else { // Couldn't find associated conference. Indicate failure on refer subscription |
10687 | status = SWITCH_STATUS_FALSE; |
10688 | } |
10689 | |
10690 | if(status != SWITCH_STATUS_SUCCESS) { |
10691 | // Unable to setup call, need to generate final NOTIFY |
10692 | if (switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 10692, &event, SWITCH_EVENT_CONFERENCE_DATA , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
10693 | event->flags |= EF_UNIQ_HEADERS; |
10694 | |
10695 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-name", conf); |
10696 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-domain", domain); |
10697 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-event", "refer"); |
10698 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", call_id); |
10699 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "final", "true"); |
10700 | switch_event_add_body(event, "%s", "SIP/2.0 481 Failure\r\n"); |
10701 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 10701, &event, ((void*)0)); |
10702 | } |
10703 | } |
10704 | |
10705 | } |
10706 | |
10707 | static void conf_data_event_handler(switch_event_t *event) |
10708 | { |
10709 | switch_event_t *revent; |
10710 | char *name = switch_event_get_header(event, "conference-name")switch_event_get_header_idx(event, "conference-name", -1); |
10711 | char *domain = switch_event_get_header(event, "conference-domain")switch_event_get_header_idx(event, "conference-domain", -1); |
10712 | conference_obj_t *conference = NULL((void*)0); |
10713 | char *body = NULL((void*)0); |
10714 | |
10715 | if (!zstr(name)_zstr(name) && (conference = conference_find(name, domain))) { |
10716 | if (switch_test_flag(conference, CFLAG_RFC4579)((conference)->flags & CFLAG_RFC4579)) { |
10717 | switch_event_dup(&revent, event); |
10718 | revent->event_id = SWITCH_EVENT_CONFERENCE_DATA; |
10719 | revent->flags |= EF_UNIQ_HEADERS; |
10720 | switch_event_add_header(revent, SWITCH_STACK_TOP, "Event-Name", "CONFERENCE_DATA"); |
10721 | |
10722 | body = conference_rfc4579_render(conference, event, revent); |
10723 | switch_event_add_body(revent, "%s", body); |
10724 | switch_event_fire(&revent)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 10724, &revent, ((void*)0)); |
10725 | switch_safe_free(body)if (body) {free(body);body=((void*)0);}; |
10726 | } |
10727 | switch_thread_rwlock_unlock(conference->rwlock); |
10728 | } |
10729 | } |
10730 | |
10731 | |
10732 | static void pres_event_handler(switch_event_t *event) |
10733 | { |
10734 | char *to = switch_event_get_header(event, "to")switch_event_get_header_idx(event, "to", -1); |
10735 | char *domain_name = NULL((void*)0); |
10736 | char *dup_to = NULL((void*)0), *conf_name, *dup_conf_name = NULL((void*)0); |
10737 | conference_obj_t *conference; |
10738 | |
10739 | if (!to || strncasecmp(to, "conf+", 5) || !strchr(to, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (to) && ('@') == '\0' ? (char *) __rawmemchr (to, '@' ) : __builtin_strchr (to, '@')))) { |
10740 | return; |
10741 | } |
10742 | |
10743 | if (!(dup_to = strdup(to)(__extension__ (__builtin_constant_p (to) && ((size_t )(const void *)((to) + 1) - (size_t)(const void *)(to) == 1) ? (((const char *) (to))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (to) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, to, __len); __retval; })) : __strdup (to))))) { |
10744 | return; |
10745 | } |
10746 | |
10747 | |
10748 | conf_name = dup_to + 5; |
10749 | |
10750 | if ((domain_name = strchr(conf_name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conf_name) && ('@') == '\0' ? (char *) __rawmemchr ( conf_name, '@') : __builtin_strchr (conf_name, '@'))))) { |
10751 | *domain_name++ = '\0'; |
10752 | } |
10753 | |
10754 | dup_conf_name = switch_mprintf("%q@%q", conf_name, domain_name); |
10755 | |
10756 | |
10757 | if ((conference = conference_find(conf_name, NULL((void*)0))) || (conference = conference_find(dup_conf_name, NULL((void*)0)))) { |
10758 | if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 10758, &event, SWITCH_EVENT_PRESENCE_IN , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
10759 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO"conf"); |
10760 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", conference->name); |
10761 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain); |
10762 | |
10763 | |
10764 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "force-status", "Active (%d caller%s)", conference->count, conference->count == 1 ? "" : "s"); |
10765 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); |
10766 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); |
10767 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++); |
10768 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", conf_name); |
10769 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_ROUTING"); |
10770 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", conference->count == 1 ? "early" : "confirmed"); |
10771 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", conference->count == 1 ? "outbound" : "inbound"); |
10772 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 10772, &event, ((void*)0)); |
10773 | } |
10774 | switch_thread_rwlock_unlock(conference->rwlock); |
10775 | } else if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 10775, &event, SWITCH_EVENT_PRESENCE_IN , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
10776 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO"conf"); |
10777 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", conf_name); |
10778 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", to); |
10779 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "force-status", "Idle"); |
10780 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown"); |
10781 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); |
10782 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); |
10783 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++); |
10784 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", conf_name); |
10785 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_HANGUP"); |
10786 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "terminated"); |
10787 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound"); |
10788 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 10788, &event, ((void*)0)); |
10789 | } |
10790 | |
10791 | switch_safe_free(dup_to)if (dup_to) {free(dup_to);dup_to=((void*)0);}; |
10792 | switch_safe_free(dup_conf_name)if (dup_conf_name) {free(dup_conf_name);dup_conf_name=((void* )0);}; |
10793 | } |
10794 | |
10795 | static void send_presence(switch_event_types_t id) |
10796 | { |
10797 | switch_xml_t cxml, cfg, advertise, room; |
10798 | switch_event_t *params = NULL((void*)0); |
10799 | |
10800 | switch_event_create(¶ms, SWITCH_EVENT_COMMAND)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 10800, ¶ms, SWITCH_EVENT_COMMAND , ((void*)0)); |
10801 | switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "mod_conference.c" , 10801, __PRETTY_FUNCTION__)); |
10802 | switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "presence", "true"); |
10803 | |
10804 | |
10805 | /* Open the config from the xml registry */ |
10806 | if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, params))) { |
10807 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10807, ((void*)0), SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf_name); |
10808 | goto done; |
10809 | } |
10810 | |
10811 | if ((advertise = switch_xml_child(cfg, "advertise"))) { |
10812 | for (room = switch_xml_child(advertise, "room"); room; room = room->next) { |
10813 | char *name = (char *) switch_xml_attr_soft(room, "name"); |
10814 | char *status = (char *) switch_xml_attr_soft(room, "status"); |
10815 | switch_event_t *event; |
10816 | |
10817 | if (name && switch_event_create(&event, id)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 10817, &event, id, ((void *)0)) == SWITCH_STATUS_SUCCESS) { |
10818 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO"conf"); |
10819 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", name); |
10820 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", name); |
10821 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "force-status", status ? status : "Available"); |
10822 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown"); |
10823 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); |
10824 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 10824, &event, ((void*)0)); |
10825 | } |
10826 | } |
10827 | } |
10828 | |
10829 | done: |
10830 | switch_event_destroy(¶ms); |
10831 | |
10832 | /* Release the config registry handle */ |
10833 | if (cxml) { |
10834 | switch_xml_free(cxml); |
10835 | cxml = NULL((void*)0); |
10836 | } |
10837 | } |
10838 | |
10839 | typedef void (*conf_key_callback_t) (conference_member_t *, struct caller_control_actions *); |
10840 | |
10841 | typedef struct { |
10842 | conference_member_t *member; |
10843 | caller_control_action_t action; |
10844 | conf_key_callback_t handler; |
10845 | } key_binding_t; |
10846 | |
10847 | |
10848 | static switch_status_t dmachine_dispatcher(switch_ivr_dmachine_match_t *match) |
10849 | { |
10850 | key_binding_t *binding = match->user_data; |
10851 | switch_channel_t *channel; |
10852 | |
10853 | if (!binding) return SWITCH_STATUS_FALSE; |
10854 | |
10855 | channel = switch_core_session_get_channel(binding->member->session); |
10856 | switch_channel_set_variable(channel, "conference_last_matching_digits", match->match_digits)switch_channel_set_variable_var_check(channel, "conference_last_matching_digits" , match->match_digits, SWITCH_TRUE); |
10857 | |
10858 | if (binding->action.data) { |
10859 | binding->action.expanded_data = switch_channel_expand_variables(channel, binding->action.data)switch_channel_expand_variables_check(channel, binding->action .data, ((void*)0), ((void*)0), 0); |
10860 | } |
10861 | |
10862 | binding->handler(binding->member, &binding->action); |
10863 | |
10864 | if (binding->action.expanded_data != binding->action.data) { |
10865 | free(binding->action.expanded_data); |
10866 | binding->action.expanded_data = NULL((void*)0); |
10867 | } |
10868 | |
10869 | switch_set_flag_locked(binding->member, MFLAG_FLUSH_BUFFER)((binding->member->flag_mutex != ((void*)0)) ? (void) ( 0) : __assert_fail ("binding->member->flag_mutex != ((void*)0)" , "mod_conference.c", 10869, __PRETTY_FUNCTION__));switch_mutex_lock (binding->member->flag_mutex);(binding->member)-> flags |= (MFLAG_FLUSH_BUFFER);switch_mutex_unlock(binding-> member->flag_mutex);; |
10870 | |
10871 | return SWITCH_STATUS_SUCCESS; |
10872 | } |
10873 | |
10874 | static void do_binding(conference_member_t *member, conf_key_callback_t handler, const char *digits, const char *data) |
10875 | { |
10876 | key_binding_t *binding; |
10877 | |
10878 | binding = switch_core_alloc(member->pool, sizeof(*binding))switch_core_perform_alloc(member->pool, sizeof(*binding), "mod_conference.c" , (const char *)__func__, 10878); |
10879 | binding->member = member; |
10880 | |
10881 | binding->action.binded_dtmf = switch_core_strdup(member->pool, digits)switch_core_perform_strdup(member->pool, digits, "mod_conference.c" , (const char *)__func__, 10881); |
10882 | |
10883 | if (data) { |
10884 | binding->action.data = switch_core_strdup(member->pool, data)switch_core_perform_strdup(member->pool, data, "mod_conference.c" , (const char *)__func__, 10884); |
10885 | } |
10886 | |
10887 | binding->handler = handler; |
10888 | switch_ivr_dmachine_bind(member->dmachine, "conf", digits, 0, dmachine_dispatcher, binding); |
10889 | |
10890 | } |
10891 | |
10892 | struct _mapping { |
10893 | const char *name; |
10894 | conf_key_callback_t handler; |
10895 | }; |
10896 | |
10897 | static struct _mapping control_mappings[] = { |
10898 | {"mute", conference_loop_fn_mute_toggle}, |
10899 | {"mute on", conference_loop_fn_mute_on}, |
10900 | {"mute off", conference_loop_fn_mute_off}, |
10901 | {"deaf mute", conference_loop_fn_deafmute_toggle}, |
10902 | {"energy up", conference_loop_fn_energy_up}, |
10903 | {"energy equ", conference_loop_fn_energy_equ_conf}, |
10904 | {"energy dn", conference_loop_fn_energy_dn}, |
10905 | {"vol talk up", conference_loop_fn_volume_talk_up}, |
10906 | {"vol talk zero", conference_loop_fn_volume_talk_zero}, |
10907 | {"vol talk dn", conference_loop_fn_volume_talk_dn}, |
10908 | {"vol listen up", conference_loop_fn_volume_listen_up}, |
10909 | {"vol listen zero", conference_loop_fn_volume_listen_zero}, |
10910 | {"vol listen dn", conference_loop_fn_volume_listen_dn}, |
10911 | {"hangup", conference_loop_fn_hangup}, |
10912 | {"event", conference_loop_fn_event}, |
10913 | {"lock", conference_loop_fn_lock_toggle}, |
10914 | {"transfer", conference_loop_fn_transfer}, |
10915 | {"execute_application", conference_loop_fn_exec_app}, |
10916 | {"floor", conference_loop_fn_floor_toggle}, |
10917 | {"vid-floor", conference_loop_fn_vid_floor_toggle}, |
10918 | {"vid-floor-force", conference_loop_fn_vid_floor_force} |
10919 | }; |
10920 | #define MAPPING_LEN(sizeof(control_mappings)/sizeof(control_mappings[0])) (sizeof(control_mappings)/sizeof(control_mappings[0])) |
10921 | |
10922 | static void member_bind_controls(conference_member_t *member, const char *controls) |
10923 | { |
10924 | switch_xml_t cxml, cfg, xgroups, xcontrol; |
10925 | switch_event_t *params; |
10926 | int i; |
10927 | |
10928 | switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 10928, ¶ms, SWITCH_EVENT_REQUEST_PARAMS , ((void*)0)); |
10929 | switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Conf-Name", member->conference->name); |
10930 | switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Action", "request-controls"); |
10931 | switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Controls", controls); |
10932 | |
10933 | if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, params))) { |
10934 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10934, ((void*)0), SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf_name); |
10935 | goto end; |
10936 | } |
10937 | |
10938 | if (!(xgroups = switch_xml_child(cfg, "caller-controls"))) { |
10939 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10939, ((void*)0), SWITCH_LOG_ERROR, "Can't find caller-controls in %s\n", global_cf_name); |
10940 | goto end; |
10941 | } |
10942 | |
10943 | if (!(xgroups = switch_xml_find_child(xgroups, "group", "name", controls))) { |
10944 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10944, ((void*)0), SWITCH_LOG_ERROR, "Can't find group '%s' in caller-controls section of %s\n", switch_str_nil(controls)(controls ? controls : ""), global_cf_name); |
10945 | goto end; |
10946 | } |
10947 | |
10948 | |
10949 | for (xcontrol = switch_xml_child(xgroups, "control"); xcontrol; xcontrol = xcontrol->next) { |
10950 | const char *key = switch_xml_attr(xcontrol, "action"); |
10951 | const char *digits = switch_xml_attr(xcontrol, "digits"); |
10952 | const char *data = switch_xml_attr_soft(xcontrol, "data"); |
10953 | |
10954 | if (zstr(key)_zstr(key) || zstr(digits)_zstr(digits)) continue; |
10955 | |
10956 | for(i = 0; i < MAPPING_LEN(sizeof(control_mappings)/sizeof(control_mappings[0])); i++) { |
10957 | if (!strcasecmp(key, control_mappings[i].name)) { |
10958 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 10958, ((void*)0), SWITCH_LOG_INFO, "%s binding '%s' to '%s'\n", |
10959 | switch_core_session_get_name(member->session)switch_channel_get_name(switch_core_session_get_channel(member ->session)), digits, key); |
10960 | |
10961 | do_binding(member, control_mappings[i].handler, digits, data); |
10962 | } |
10963 | } |
10964 | } |
10965 | |
10966 | end: |
10967 | |
10968 | /* Release the config registry handle */ |
10969 | if (cxml) { |
10970 | switch_xml_free(cxml); |
10971 | cxml = NULL((void*)0); |
10972 | } |
10973 | |
10974 | if (params) switch_event_destroy(¶ms); |
10975 | |
10976 | } |
10977 | |
10978 | |
10979 | |
10980 | |
10981 | /* Called by FreeSWITCH when the module loads */ |
10982 | SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load)switch_status_t mod_conference_load (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) |
10983 | { |
10984 | uint32_t i; |
10985 | size_t nl, ol = 0; |
10986 | char *p = NULL((void*)0), *tmp = NULL((void*)0); |
10987 | switch_chat_interface_t *chat_interface; |
10988 | switch_api_interface_t *api_interface; |
10989 | switch_application_interface_t *app_interface; |
10990 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
10991 | char cmd_str[256]; |
10992 | |
10993 | memset(&globals, 0, sizeof(globals)); |
10994 | |
10995 | /* Connect my internal structure to the blank pointer passed to me */ |
10996 | *module_interface = switch_loadable_module_create_module_interface(pool, modname); |
10997 | |
10998 | switch_console_add_complete_func("::conference::list_conferences", list_conferences); |
10999 | |
11000 | |
11001 | switch_event_channel_bind("conference", conference_event_channel_handler, &globals.event_channel_id); |
11002 | switch_event_channel_bind("conference-liveArray", conference_la_event_channel_handler, &globals.event_channel_id); |
11003 | switch_event_channel_bind("conference-mod", conference_mod_event_channel_handler, &globals.event_channel_id); |
11004 | |
11005 | /* build api interface help ".syntax" field string */ |
11006 | p = strdup("")(__extension__ (__builtin_constant_p ("") && ((size_t )(const void *)(("") + 1) - (size_t)(const void *)("") == 1) ? (((const char *) (""))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "", __len); __retval; })) : __strdup (""))); |
11007 | for (i = 0; i < CONFFUNCAPISIZE(sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0 ])); i++) { |
11008 | nl = strlen(conf_api_sub_commands[i].pcommand) + strlen(conf_api_sub_commands[i].psyntax) + 5; |
11009 | |
11010 | switch_snprintf(cmd_str, sizeof(cmd_str), "add conference ::conference::list_conferences %s", conf_api_sub_commands[i].pcommand); |
11011 | switch_console_set_complete(cmd_str); |
11012 | |
11013 | if (p != NULL((void*)0)) { |
11014 | ol = strlen(p); |
11015 | } |
11016 | tmp = realloc(p, ol + nl); |
11017 | if (tmp != NULL((void*)0)) { |
11018 | p = tmp; |
11019 | strcat(p, "\t\t"); |
11020 | strcat(p, conf_api_sub_commands[i].pcommand); |
11021 | if (!zstr(conf_api_sub_commands[i].psyntax)_zstr(conf_api_sub_commands[i].psyntax)) { |
11022 | strcat(p, " "); |
11023 | strcat(p, conf_api_sub_commands[i].psyntax); |
11024 | } |
11025 | if (i < CONFFUNCAPISIZE(sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0 ])) - 1) { |
11026 | strcat(p, "\n"); |
11027 | } |
11028 | } else { |
11029 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 11029, ((void*)0), SWITCH_LOG_ERROR, "Couldn't realloc\n"); |
11030 | return SWITCH_STATUS_TERM; |
11031 | } |
11032 | |
11033 | } |
11034 | api_syntax = p; |
11035 | |
11036 | /* create/register custom event message type */ |
11037 | if (switch_event_reserve_subclass(CONF_EVENT_MAINT)switch_event_reserve_subclass_detailed("mod_conference.c", "conference::maintenance" ) != SWITCH_STATUS_SUCCESS) { |
11038 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 11038, ((void*)0), SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", CONF_EVENT_MAINT"conference::maintenance"); |
11039 | return SWITCH_STATUS_TERM; |
11040 | } |
11041 | |
11042 | /* Setup the pool */ |
11043 | globals.conference_pool = pool; |
11044 | |
11045 | /* Setup a hash to store conferences by name */ |
11046 | switch_core_hash_init(&globals.conference_hash)switch_core_hash_init_case(&globals.conference_hash, SWITCH_TRUE ); |
11047 | switch_mutex_init(&globals.conference_mutex, SWITCH_MUTEX_NESTED0x1, globals.conference_pool); |
11048 | switch_mutex_init(&globals.id_mutex, SWITCH_MUTEX_NESTED0x1, globals.conference_pool); |
11049 | switch_mutex_init(&globals.hash_mutex, SWITCH_MUTEX_NESTED0x1, globals.conference_pool); |
11050 | switch_mutex_init(&globals.setup_mutex, SWITCH_MUTEX_NESTED0x1, globals.conference_pool); |
11051 | |
11052 | /* Subscribe to presence request events */ |
11053 | if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), pres_event_handler, NULL((void*)0)) != SWITCH_STATUS_SUCCESS) { |
11054 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 11054, ((void*)0), SWITCH_LOG_ERROR, "Couldn't subscribe to presence request events!\n"); |
11055 | } |
11056 | |
11057 | if (switch_event_bind(modname, SWITCH_EVENT_CONFERENCE_DATA_QUERY, SWITCH_EVENT_SUBCLASS_ANY((void*)0), conf_data_event_handler, NULL((void*)0)) != SWITCH_STATUS_SUCCESS) { |
11058 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 11058, ((void*)0), SWITCH_LOG_ERROR, "Couldn't subscribe to conference data query events!\n"); |
11059 | } |
11060 | |
11061 | if (switch_event_bind(modname, SWITCH_EVENT_CALL_SETUP_REQ, SWITCH_EVENT_SUBCLASS_ANY((void*)0), call_setup_event_handler, NULL((void*)0)) != SWITCH_STATUS_SUCCESS) { |
11062 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 11062, ((void*)0), SWITCH_LOG_ERROR, "Couldn't subscribe to conference data query events!\n"); |
11063 | } |
11064 | |
11065 | SWITCH_ADD_API(api_interface, "conference", "Conference module commands", conf_api_main, p)for (;;) { api_interface = (switch_api_interface_t *)switch_loadable_module_create_interface (*module_interface, SWITCH_API_INTERFACE); api_interface-> interface_name = "conference"; api_interface->desc = "Conference module commands" ; api_interface->function = conf_api_main; api_interface-> syntax = p; break; }; |
11066 | SWITCH_ADD_APP(app_interface, global_app_name, global_app_name, NULL, conference_function, NULL, SAF_NONE)for (;;) { app_interface = (switch_application_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_APPLICATION_INTERFACE ); app_interface->interface_name = global_app_name; app_interface ->application_function = conference_function; app_interface ->short_desc = global_app_name; app_interface->long_desc = ((void*)0); app_interface->syntax = ((void*)0); app_interface ->flags = SAF_NONE; break; }; |
11067 | SWITCH_ADD_APP(app_interface, "conference_set_auto_outcall", "conference_set_auto_outcall", NULL, conference_auto_function, NULL, SAF_NONE)for (;;) { app_interface = (switch_application_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_APPLICATION_INTERFACE ); app_interface->interface_name = "conference_set_auto_outcall" ; app_interface->application_function = conference_auto_function ; app_interface->short_desc = "conference_set_auto_outcall" ; app_interface->long_desc = ((void*)0); app_interface-> syntax = ((void*)0); app_interface->flags = SAF_NONE; break ; }; |
11068 | SWITCH_ADD_CHAT(chat_interface, CONF_CHAT_PROTO, chat_send)for (;;) { chat_interface = (switch_chat_interface_t *)switch_loadable_module_create_interface (*module_interface, SWITCH_CHAT_INTERFACE); chat_interface-> chat_send = chat_send; chat_interface->interface_name = "conf" ; break; }; |
11069 | |
11070 | send_presence(SWITCH_EVENT_PRESENCE_IN); |
11071 | |
11072 | globals.running = 1; |
11073 | /* indicate that the module should continue to be loaded */ |
11074 | return status; |
11075 | } |
11076 | |
11077 | SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_conference_shutdown)switch_status_t mod_conference_shutdown (void) |
11078 | { |
11079 | if (globals.running) { |
11080 | |
11081 | /* signal all threads to shutdown */ |
11082 | globals.running = 0; |
11083 | |
11084 | switch_event_channel_unbind(NULL((void*)0), conference_event_channel_handler); |
11085 | switch_event_channel_unbind(NULL((void*)0), conference_la_event_channel_handler); |
11086 | |
11087 | switch_console_del_complete_func("::conference::list_conferences"); |
11088 | |
11089 | /* wait for all threads */ |
11090 | while (globals.threads) { |
11091 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 11091, ((void*)0), SWITCH_LOG_DEBUG, "Waiting for %d threads\n", globals.threads); |
11092 | switch_yield(100000)switch_sleep(100000);; |
11093 | } |
11094 | |
11095 | switch_event_unbind_callback(pres_event_handler); |
11096 | switch_event_unbind_callback(conf_data_event_handler); |
11097 | switch_event_unbind_callback(call_setup_event_handler); |
11098 | switch_event_free_subclass(CONF_EVENT_MAINT)switch_event_free_subclass_detailed("mod_conference.c", "conference::maintenance" ); |
11099 | |
11100 | /* free api interface help ".syntax" field string */ |
11101 | switch_safe_free(api_syntax)if (api_syntax) {free(api_syntax);api_syntax=((void*)0);}; |
11102 | } |
11103 | switch_core_hash_destroy(&globals.conference_hash); |
11104 | |
11105 | return SWITCH_STATUS_SUCCESS; |
11106 | } |
11107 | |
11108 | /* For Emacs: |
11109 | * Local Variables: |
11110 | * mode:c |
11111 | * indent-tabs-mode:t |
11112 | * tab-width:4 |
11113 | * c-basic-offset:4 |
11114 | * End: |
11115 | * For VIM: |
11116 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: |
11117 | */ |