File: | src/mod/applications/mod_conference/mod_conference.c |
Location: | line 11029, column 4 |
Description: | Potential leak of memory pointed to by 'p' |
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 | */ |