File: | src/mod/applications/mod_conference/mod_conference.c |
Location: | line 9884, column 11 |
Description: | Potential leak of memory pointed to by 'stream.end' |
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; | |||
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 | */ |