| File: | src/mod/applications/mod_conference/mod_conference.c |
| Location: | line 3385, column 6 |
| Description: | Value stored to 'ok' is never read |
| 1 | /* |
| 2 | * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application |
| 3 | * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org> |
| 4 | * |
| 5 | * Version: MPL 1.1 |
| 6 | * |
| 7 | * The contents of this file are subject to the Mozilla Public License Version |
| 8 | * 1.1 (the "License"); you may not use this file except in compliance with |
| 9 | * the License. You may obtain a copy of the License at |
| 10 | * http://www.mozilla.org/MPL/ |
| 11 | * |
| 12 | * Software distributed under the License is distributed on an "AS IS" basis, |
| 13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| 14 | * for the specific language governing rights and limitations under the |
| 15 | * License. |
| 16 | * |
| 17 | * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application |
| 18 | * |
| 19 | * The Initial Developer of the Original Code is |
| 20 | * Anthony Minessale II <anthm@freeswitch.org> |
| 21 | * Portions created by the Initial Developer are Copyright (C) |
| 22 | * the Initial Developer. All Rights Reserved. |
| 23 | * |
| 24 | * Contributor(s): |
| 25 | * |
| 26 | * Anthony Minessale II <anthm@freeswitch.org> |
| 27 | * Neal Horman <neal at wanlink dot com> |
| 28 | * Bret McDanel <trixter at 0xdecafbad dot com> |
| 29 | * Dale Thatcher <freeswitch at dalethatcher dot com> |
| 30 | * Chris Danielson <chris at maxpowersoft dot com> |
| 31 | * Rupa Schomaker <rupa@rupa.com> |
| 32 | * David Weekly <david@weekly.org> |
| 33 | * Joao Mesquita <jmesquita@gmail.com> |
| 34 | * Raymond Chandler <intralanman@freeswitch.org> |
| 35 | * Seven Du <dujinfang@gmail.com> |
| 36 | * Emmanuel Schmidbauer <e.schmidbauer@gmail.com> |
| 37 | * |
| 38 | * mod_conference.c -- Software Conference Bridge |
| 39 | * |
| 40 | */ |
| 41 | #include <switch.h> |
| 42 | |
| 43 | #ifdef OPENAL_POSITIONING |
| 44 | #define AL_ALEXT_PROTOTYPES |
| 45 | #include <AL/al.h> |
| 46 | #include <AL/alc.h> |
| 47 | #include <AL/alext.h> |
| 48 | #endif |
| 49 | |
| 50 | #define DEFAULT_AGC_LEVEL1100 1100 |
| 51 | #define CONFERENCE_UUID_VARIABLE"conference_uuid" "conference_uuid" |
| 52 | |
| 53 | SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load)switch_status_t mod_conference_load (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool); |
| 54 | SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_conference_shutdown)switch_status_t mod_conference_shutdown (void); |
| 55 | SWITCH_MODULE_DEFINITION(mod_conference, mod_conference_load, mod_conference_shutdown, NULL)static const char modname[] = "mod_conference" ; __attribute__ ((visibility("default"))) switch_loadable_module_function_table_t mod_conference_module_interface = { 5, mod_conference_load, mod_conference_shutdown , ((void*)0), SMODF_NONE }; |
| 56 | |
| 57 | typedef enum { |
| 58 | CONF_SILENT_REQ = (1 << 0), |
| 59 | CONF_SILENT_DONE = (1 << 1) |
| 60 | } conf_app_flag_t; |
| 61 | |
| 62 | static const char global_app_name[] = "conference"; |
| 63 | static char *global_cf_name = "conference.conf"; |
| 64 | static char *cf_pin_url_param_name = "X-ConfPin="; |
| 65 | static char *api_syntax; |
| 66 | static int EC = 0; |
| 67 | |
| 68 | /* Size to allocate for audio buffers */ |
| 69 | #define CONF_BUFFER_SIZE1024 * 128 1024 * 128 |
| 70 | #define CONF_EVENT_MAINT"conference::maintenance" "conference::maintenance" |
| 71 | #define CONF_EVENT_CDR"conference::cdr" "conference::cdr" |
| 72 | #define CONF_DEFAULT_LEADIN20 20 |
| 73 | |
| 74 | #define CONF_DBLOCK_SIZE1024 * 128 CONF_BUFFER_SIZE1024 * 128 |
| 75 | #define CONF_DBUFFER_SIZE1024 * 128 CONF_BUFFER_SIZE1024 * 128 |
| 76 | #define CONF_DBUFFER_MAX0 0 |
| 77 | #define CONF_CHAT_PROTO"conf" "conf" |
| 78 | |
| 79 | #ifndef MIN |
| 80 | #define MIN(a, b)((a)<(b)?(a):(b)) ((a)<(b)?(a):(b)) |
| 81 | #endif |
| 82 | |
| 83 | /* the rate at which the infinite impulse response filter on speaker score will decay. */ |
| 84 | #define SCORE_DECAY0.8 0.8 |
| 85 | /* the maximum value for the IIR score [keeps loud & longwinded people from getting overweighted] */ |
| 86 | #define SCORE_MAX_IIR25000 25000 |
| 87 | /* the minimum score for which you can be considered to be loud enough to now have the floor */ |
| 88 | #define SCORE_IIR_SPEAKING_MAX300 300 |
| 89 | /* the threshold below which you cede the floor to someone loud (see above value). */ |
| 90 | #define SCORE_IIR_SPEAKING_MIN100 100 |
| 91 | |
| 92 | |
| 93 | #define test_eflag(conference, flag)((conference)->eflags & flag) ((conference)->eflags & flag) |
| 94 | |
| 95 | typedef enum { |
| 96 | FILE_STOP_CURRENT, |
| 97 | FILE_STOP_ALL, |
| 98 | FILE_STOP_ASYNC |
| 99 | } file_stop_t; |
| 100 | |
| 101 | /* Global Values */ |
| 102 | static struct { |
| 103 | switch_memory_pool_t *conference_pool; |
| 104 | switch_mutex_t *conference_mutex; |
| 105 | switch_hash_t *conference_hash; |
| 106 | switch_mutex_t *id_mutex; |
| 107 | switch_mutex_t *hash_mutex; |
| 108 | switch_mutex_t *setup_mutex; |
| 109 | uint32_t id_pool; |
| 110 | int32_t running; |
| 111 | uint32_t threads; |
| 112 | switch_event_channel_id_t event_channel_id; |
| 113 | } globals; |
| 114 | |
| 115 | /* forward declaration for conference_obj and caller_control */ |
| 116 | struct conference_member; |
| 117 | typedef struct conference_member conference_member_t; |
| 118 | |
| 119 | |
| 120 | typedef struct conference_cdr_node_s { |
| 121 | switch_caller_profile_t *cp; |
| 122 | char *record_path; |
| 123 | switch_time_t join_time; |
| 124 | switch_time_t leave_time; |
| 125 | uint32_t flags; |
| 126 | uint32_t id; |
| 127 | conference_member_t *member; |
| 128 | switch_event_t *var_event; |
| 129 | struct conference_cdr_node_s *next; |
| 130 | } conference_cdr_node_t; |
| 131 | |
| 132 | typedef enum { |
| 133 | CDRR_LOCKED = 1, |
| 134 | CDRR_PIN, |
| 135 | CDRR_MAXMEMBERS |
| 136 | } cdr_reject_reason_t; |
| 137 | |
| 138 | typedef struct conference_cdr_reject_s { |
| 139 | switch_caller_profile_t *cp; |
| 140 | switch_time_t reject_time; |
| 141 | cdr_reject_reason_t reason; |
| 142 | struct conference_cdr_reject_s *next; |
| 143 | } conference_cdr_reject_t; |
| 144 | |
| 145 | typedef enum { |
| 146 | CDRE_NONE, |
| 147 | CDRE_AS_CONTENT, |
| 148 | CDRE_AS_FILE |
| 149 | } cdr_event_mode_t; |
| 150 | |
| 151 | |
| 152 | struct call_list { |
| 153 | char *string; |
| 154 | int iteration; |
| 155 | struct call_list *next; |
| 156 | }; |
| 157 | typedef struct call_list call_list_t; |
| 158 | |
| 159 | struct caller_control_actions; |
| 160 | |
| 161 | typedef struct caller_control_actions { |
| 162 | char *binded_dtmf; |
| 163 | char *data; |
| 164 | char *expanded_data; |
| 165 | } caller_control_action_t; |
| 166 | |
| 167 | typedef struct caller_control_menu_info { |
| 168 | switch_ivr_menu_t *stack; |
| 169 | char *name; |
| 170 | } caller_control_menu_info_t; |
| 171 | |
| 172 | typedef enum { |
| 173 | MFLAG_RUNNING = (1 << 0), |
| 174 | MFLAG_CAN_SPEAK = (1 << 1), |
| 175 | MFLAG_CAN_HEAR = (1 << 2), |
| 176 | MFLAG_KICKED = (1 << 3), |
| 177 | MFLAG_ITHREAD = (1 << 4), |
| 178 | MFLAG_NOCHANNEL = (1 << 5), |
| 179 | MFLAG_INTREE = (1 << 6), |
| 180 | MFLAG_WASTE_FLAG = (1 << 7), |
| 181 | MFLAG_FLUSH_BUFFER = (1 << 8), |
| 182 | MFLAG_ENDCONF = (1 << 9), |
| 183 | MFLAG_HAS_AUDIO = (1 << 10), |
| 184 | MFLAG_TALKING = (1 << 11), |
| 185 | MFLAG_RESTART = (1 << 12), |
| 186 | MFLAG_MINTWO = (1 << 13), |
| 187 | MFLAG_MUTE_DETECT = (1 << 14), |
| 188 | MFLAG_DIST_DTMF = (1 << 15), |
| 189 | MFLAG_MOD = (1 << 16), |
| 190 | MFLAG_INDICATE_MUTE = (1 << 17), |
| 191 | MFLAG_INDICATE_UNMUTE = (1 << 18), |
| 192 | MFLAG_NOMOH = (1 << 19), |
| 193 | MFLAG_VIDEO_BRIDGE = (1 << 20), |
| 194 | MFLAG_INDICATE_MUTE_DETECT = (1 << 21), |
| 195 | MFLAG_PAUSE_RECORDING = (1 << 22), |
| 196 | MFLAG_ACK_VIDEO = (1 << 23), |
| 197 | MFLAG_GHOST = (1 << 24), |
| 198 | MFLAG_JOIN_ONLY = (1 << 25), |
| 199 | MFLAG_POSITIONAL = (1 << 26), |
| 200 | MFLAG_NO_POSITIONAL = (1 << 27) |
| 201 | } member_flag_t; |
| 202 | |
| 203 | typedef enum { |
| 204 | CFLAG_RUNNING = (1 << 0), |
| 205 | CFLAG_DYNAMIC = (1 << 1), |
| 206 | CFLAG_ENFORCE_MIN = (1 << 2), |
| 207 | CFLAG_DESTRUCT = (1 << 3), |
| 208 | CFLAG_LOCKED = (1 << 4), |
| 209 | CFLAG_ANSWERED = (1 << 5), |
| 210 | CFLAG_BRIDGE_TO = (1 << 6), |
| 211 | CFLAG_WAIT_MOD = (1 << 7), |
| 212 | CFLAG_VID_FLOOR = (1 << 8), |
| 213 | CFLAG_WASTE_FLAG = (1 << 9), |
| 214 | CFLAG_OUTCALL = (1 << 10), |
| 215 | CFLAG_INHASH = (1 << 11), |
| 216 | CFLAG_EXIT_SOUND = (1 << 12), |
| 217 | CFLAG_ENTER_SOUND = (1 << 13), |
| 218 | CFLAG_VIDEO_BRIDGE = (1 << 14), |
| 219 | CFLAG_AUDIO_ALWAYS = (1 << 15), |
| 220 | CFLAG_ENDCONF_FORCED = (1 << 16), |
| 221 | CFLAG_RFC4579 = (1 << 17), |
| 222 | CFLAG_FLOOR_CHANGE = (1 << 18), |
| 223 | CFLAG_VID_FLOOR_LOCK = (1 << 19), |
| 224 | CFLAG_JSON_EVENTS = (1 << 20), |
| 225 | CFLAG_LIVEARRAY_SYNC = (1 << 21), |
| 226 | CFLAG_CONF_RESTART_AUTO_RECORD = (1 << 22), |
| 227 | CFLAG_POSITIONAL = (1 << 23) |
| 228 | } conf_flag_t; |
| 229 | |
| 230 | typedef enum { |
| 231 | RFLAG_CAN_SPEAK = (1 << 0), |
| 232 | RFLAG_CAN_HEAR = (1 << 1) |
| 233 | } relation_flag_t; |
| 234 | |
| 235 | typedef enum { |
| 236 | NODE_TYPE_FILE, |
| 237 | NODE_TYPE_SPEECH |
| 238 | } node_type_t; |
| 239 | |
| 240 | typedef enum { |
| 241 | NFLAG_NONE = (1 << 0), |
| 242 | NFLAG_PAUSE = (1 << 1) |
| 243 | } node_flag_t; |
| 244 | |
| 245 | typedef enum { |
| 246 | EFLAG_ADD_MEMBER = (1 << 0), |
| 247 | EFLAG_DEL_MEMBER = (1 << 1), |
| 248 | EFLAG_ENERGY_LEVEL = (1 << 2), |
| 249 | EFLAG_VOLUME_LEVEL = (1 << 3), |
| 250 | EFLAG_GAIN_LEVEL = (1 << 4), |
| 251 | EFLAG_DTMF = (1 << 5), |
| 252 | EFLAG_STOP_TALKING = (1 << 6), |
| 253 | EFLAG_START_TALKING = (1 << 7), |
| 254 | EFLAG_MUTE_MEMBER = (1 << 8), |
| 255 | EFLAG_UNMUTE_MEMBER = (1 << 9), |
| 256 | EFLAG_DEAF_MEMBER = (1 << 10), |
| 257 | EFLAG_UNDEAF_MEMBER = (1 << 11), |
| 258 | EFLAG_KICK_MEMBER = (1 << 12), |
| 259 | EFLAG_DTMF_MEMBER = (1 << 13), |
| 260 | EFLAG_ENERGY_LEVEL_MEMBER = (1 << 14), |
| 261 | EFLAG_VOLUME_IN_MEMBER = (1 << 15), |
| 262 | EFLAG_VOLUME_OUT_MEMBER = (1 << 16), |
| 263 | EFLAG_PLAY_FILE = (1 << 17), |
| 264 | EFLAG_PLAY_FILE_MEMBER = (1 << 18), |
| 265 | EFLAG_SPEAK_TEXT = (1 << 19), |
| 266 | EFLAG_SPEAK_TEXT_MEMBER = (1 << 20), |
| 267 | EFLAG_LOCK = (1 << 21), |
| 268 | EFLAG_UNLOCK = (1 << 22), |
| 269 | EFLAG_TRANSFER = (1 << 23), |
| 270 | EFLAG_BGDIAL_RESULT = (1 << 24), |
| 271 | EFLAG_FLOOR_CHANGE = (1 << 25), |
| 272 | EFLAG_MUTE_DETECT = (1 << 26), |
| 273 | EFLAG_RECORD = (1 << 27), |
| 274 | EFLAG_HUP_MEMBER = (1 << 28), |
| 275 | EFLAG_PLAY_FILE_DONE = (1 << 29), |
| 276 | EFLAG_SET_POSITION_MEMBER = (1 << 30) |
| 277 | } event_type_t; |
| 278 | |
| 279 | #ifdef OPENAL_POSITIONING |
| 280 | typedef struct al_handle_s { |
| 281 | ALCdevice *device; |
| 282 | ALCcontext *context; |
| 283 | ALuint source; |
| 284 | ALuint buffer_in[2]; |
| 285 | int setpos; |
| 286 | ALfloat pos_x; |
| 287 | ALfloat pos_y; |
| 288 | ALfloat pos_z; |
| 289 | } al_handle_t; |
| 290 | #else |
| 291 | typedef struct al_handle_s { |
| 292 | int unsupported; |
| 293 | } al_handle_t; |
| 294 | #endif |
| 295 | |
| 296 | typedef struct conference_file_node { |
| 297 | switch_file_handle_t fh; |
| 298 | switch_speech_handle_t *sh; |
| 299 | node_flag_t flags; |
| 300 | node_type_t type; |
| 301 | uint8_t done; |
| 302 | uint8_t async; |
| 303 | switch_memory_pool_t *pool; |
| 304 | uint32_t leadin; |
| 305 | struct conference_file_node *next; |
| 306 | char *file; |
| 307 | switch_bool_t mux; |
| 308 | uint32_t member_id; |
| 309 | al_handle_t *al; |
| 310 | } conference_file_node_t; |
| 311 | |
| 312 | typedef enum { |
| 313 | REC_ACTION_STOP = 1, |
| 314 | REC_ACTION_PAUSE, |
| 315 | REC_ACTION_RESUME |
| 316 | } recording_action_type_t; |
| 317 | |
| 318 | /* conference xml config sections */ |
| 319 | typedef struct conf_xml_cfg { |
| 320 | switch_xml_t profile; |
| 321 | switch_xml_t controls; |
| 322 | } conf_xml_cfg_t; |
| 323 | |
| 324 | struct vid_helper { |
| 325 | conference_member_t *member_a; |
| 326 | conference_member_t *member_b; |
| 327 | int up; |
| 328 | }; |
| 329 | |
| 330 | struct conference_obj; |
| 331 | |
| 332 | /* Record Node */ |
| 333 | typedef struct conference_record { |
| 334 | struct conference_obj *conference; |
| 335 | char *path; |
| 336 | switch_memory_pool_t *pool; |
| 337 | switch_bool_t autorec; |
| 338 | struct conference_record *next; |
| 339 | } conference_record_t; |
| 340 | |
| 341 | /* Conference Object */ |
| 342 | typedef struct conference_obj { |
| 343 | char *name; |
| 344 | char *la_name; |
| 345 | char *la_event_channel; |
| 346 | char *mod_event_channel; |
| 347 | char *desc; |
| 348 | char *timer_name; |
| 349 | char *tts_engine; |
| 350 | char *tts_voice; |
| 351 | char *enter_sound; |
| 352 | char *exit_sound; |
| 353 | char *alone_sound; |
| 354 | char *perpetual_sound; |
| 355 | char *moh_sound; |
| 356 | char *ack_sound; |
| 357 | char *nack_sound; |
| 358 | char *muted_sound; |
| 359 | char *mute_detect_sound; |
| 360 | char *unmuted_sound; |
| 361 | char *locked_sound; |
| 362 | char *is_locked_sound; |
| 363 | char *is_unlocked_sound; |
| 364 | char *kicked_sound; |
| 365 | char *join_only_sound; |
| 366 | char *caller_id_name; |
| 367 | char *caller_id_number; |
| 368 | char *sound_prefix; |
| 369 | char *special_announce; |
| 370 | char *auto_record; |
| 371 | char *record_filename; |
| 372 | char *outcall_templ; |
| 373 | uint32_t terminate_on_silence; |
| 374 | uint32_t max_members; |
| 375 | uint32_t doc_version; |
| 376 | char *maxmember_sound; |
| 377 | uint32_t announce_count; |
| 378 | char *pin; |
| 379 | char *mpin; |
| 380 | char *pin_sound; |
| 381 | char *bad_pin_sound; |
| 382 | char *profile_name; |
| 383 | char *domain; |
| 384 | char *chat_id; |
| 385 | char *caller_controls; |
| 386 | char *moderator_controls; |
| 387 | switch_live_array_t *la; |
| 388 | uint32_t flags; |
| 389 | member_flag_t mflags; |
| 390 | switch_call_cause_t bridge_hangup_cause; |
| 391 | switch_mutex_t *flag_mutex; |
| 392 | uint32_t rate; |
| 393 | uint32_t interval; |
| 394 | uint32_t channels; |
| 395 | switch_mutex_t *mutex; |
| 396 | conference_member_t *members; |
| 397 | conference_member_t *floor_holder; |
| 398 | conference_member_t *video_floor_holder; |
| 399 | switch_mutex_t *member_mutex; |
| 400 | conference_file_node_t *fnode; |
| 401 | conference_file_node_t *async_fnode; |
| 402 | switch_memory_pool_t *pool; |
| 403 | switch_thread_rwlock_t *rwlock; |
| 404 | uint32_t count; |
| 405 | int32_t energy_level; |
| 406 | uint8_t min; |
| 407 | switch_speech_handle_t lsh; |
| 408 | switch_speech_handle_t *sh; |
| 409 | switch_byte_t *not_talking_buf; |
| 410 | uint32_t not_talking_buf_len; |
| 411 | int pin_retries; |
| 412 | int broadcast_chat_messages; |
| 413 | int comfort_noise_level; |
| 414 | int auto_recording; |
| 415 | int record_count; |
| 416 | uint32_t min_recording_participants; |
| 417 | int video_running; |
| 418 | int ivr_dtmf_timeout; |
| 419 | int ivr_input_timeout; |
| 420 | uint32_t eflags; |
| 421 | uint32_t verbose_events; |
| 422 | int end_count; |
| 423 | uint32_t count_ghosts; |
| 424 | /* allow extra time after 'endconf' member leaves */ |
| 425 | switch_time_t endconf_time; |
| 426 | int endconf_grace_time; |
| 427 | |
| 428 | uint32_t relationship_total; |
| 429 | uint32_t score; |
| 430 | int mux_loop_count; |
| 431 | int member_loop_count; |
| 432 | int agc_level; |
| 433 | |
| 434 | uint32_t avg_score; |
| 435 | uint32_t avg_itt; |
| 436 | uint32_t avg_tally; |
| 437 | switch_time_t run_time; |
| 438 | char *uuid_str; |
| 439 | uint32_t originating; |
| 440 | switch_call_cause_t cancel_cause; |
| 441 | conference_cdr_node_t *cdr_nodes; |
| 442 | conference_cdr_reject_t *cdr_rejected; |
| 443 | switch_time_t start_time; |
| 444 | switch_time_t end_time; |
| 445 | char *log_dir; |
| 446 | cdr_event_mode_t cdr_event_mode; |
| 447 | struct vid_helper vh[2]; |
| 448 | struct vid_helper mh; |
| 449 | conference_record_t *rec_node_head; |
| 450 | int last_speech_channels; |
| 451 | } conference_obj_t; |
| 452 | |
| 453 | /* Relationship with another member */ |
| 454 | typedef struct conference_relationship { |
| 455 | uint32_t id; |
| 456 | uint32_t flags; |
| 457 | struct conference_relationship *next; |
| 458 | } conference_relationship_t; |
| 459 | |
| 460 | /* Conference Member Object */ |
| 461 | struct conference_member { |
| 462 | uint32_t id; |
| 463 | switch_core_session_t *session; |
| 464 | switch_channel_t *channel; |
| 465 | conference_obj_t *conference; |
| 466 | switch_memory_pool_t *pool; |
| 467 | switch_buffer_t *audio_buffer; |
| 468 | switch_buffer_t *mux_buffer; |
| 469 | switch_buffer_t *resample_buffer; |
| 470 | uint32_t flags; |
| 471 | uint32_t score; |
| 472 | uint32_t last_score; |
| 473 | uint32_t score_iir; |
| 474 | switch_mutex_t *flag_mutex; |
| 475 | switch_mutex_t *write_mutex; |
| 476 | switch_mutex_t *audio_in_mutex; |
| 477 | switch_mutex_t *audio_out_mutex; |
| 478 | switch_mutex_t *read_mutex; |
| 479 | switch_mutex_t *fnode_mutex; |
| 480 | switch_thread_rwlock_t *rwlock; |
| 481 | switch_codec_implementation_t read_impl; |
| 482 | switch_codec_implementation_t orig_read_impl; |
| 483 | switch_codec_t read_codec; |
| 484 | switch_codec_t write_codec; |
| 485 | char *rec_path; |
| 486 | switch_time_t rec_time; |
| 487 | conference_record_t *rec; |
| 488 | uint8_t *frame; |
| 489 | uint8_t *last_frame; |
| 490 | uint32_t frame_size; |
| 491 | uint8_t *mux_frame; |
| 492 | uint32_t read; |
| 493 | uint32_t vol_period; |
| 494 | int32_t energy_level; |
| 495 | int32_t agc_volume_in_level; |
| 496 | int32_t volume_in_level; |
| 497 | int32_t volume_out_level; |
| 498 | int32_t agc_concur; |
| 499 | int32_t nt_tally; |
| 500 | switch_time_t join_time; |
| 501 | switch_time_t last_talking; |
| 502 | uint32_t native_rate; |
| 503 | switch_audio_resampler_t *read_resampler; |
| 504 | int16_t *resample_out; |
| 505 | uint32_t resample_out_len; |
| 506 | conference_file_node_t *fnode; |
| 507 | conference_relationship_t *relationships; |
| 508 | switch_speech_handle_t lsh; |
| 509 | switch_speech_handle_t *sh; |
| 510 | uint32_t verbose_events; |
| 511 | uint32_t avg_score; |
| 512 | uint32_t avg_itt; |
| 513 | uint32_t avg_tally; |
| 514 | struct conference_member *next; |
| 515 | switch_ivr_dmachine_t *dmachine; |
| 516 | conference_cdr_node_t *cdr_node; |
| 517 | char *kicked_sound; |
| 518 | switch_queue_t *dtmf_queue; |
| 519 | switch_thread_t *input_thread; |
| 520 | cJSON *json; |
| 521 | cJSON *status_field; |
| 522 | uint8_t loop_loop; |
| 523 | al_handle_t *al; |
| 524 | int last_speech_channels; |
| 525 | }; |
| 526 | |
| 527 | typedef enum { |
| 528 | CONF_API_SUB_ARGS_SPLIT, |
| 529 | CONF_API_SUB_MEMBER_TARGET, |
| 530 | CONF_API_SUB_ARGS_AS_ONE |
| 531 | } conference_fntype_t; |
| 532 | |
| 533 | typedef void (*void_fn_t) (void); |
| 534 | |
| 535 | /* API command parser */ |
| 536 | typedef struct api_command { |
| 537 | char *pname; |
| 538 | void_fn_t pfnapicmd; |
| 539 | conference_fntype_t fntype; |
| 540 | char *pcommand; |
| 541 | char *psyntax; |
| 542 | } api_command_t; |
| 543 | |
| 544 | /* Function Prototypes */ |
| 545 | static int setup_media(conference_member_t *member, conference_obj_t *conference); |
| 546 | static uint32_t next_member_id(void); |
| 547 | static conference_relationship_t *member_get_relationship(conference_member_t *member, conference_member_t *other_member); |
| 548 | static conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id); |
| 549 | static conference_relationship_t *member_add_relationship(conference_member_t *member, uint32_t id); |
| 550 | static switch_status_t member_del_relationship(conference_member_t *member, uint32_t id); |
| 551 | static switch_status_t conference_add_member(conference_obj_t *conference, conference_member_t *member); |
| 552 | static switch_status_t conference_del_member(conference_obj_t *conference, conference_member_t *member); |
| 553 | static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *obj); |
| 554 | static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thread, void *obj); |
| 555 | static void conference_loop_output(conference_member_t *member); |
| 556 | static uint32_t conference_stop_file(conference_obj_t *conference, file_stop_t stop); |
| 557 | static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel, uint8_t async); |
| 558 | static void conference_send_all_dtmf(conference_member_t *member, conference_obj_t *conference, const char *dtmf); |
| 559 | static switch_status_t conference_say(conference_obj_t *conference, const char *text, uint32_t leadin); |
| 560 | static void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim); |
| 561 | static conference_obj_t *conference_find(char *name, char *domain); |
| 562 | static void member_bind_controls(conference_member_t *member, const char *controls); |
| 563 | static void conference_send_presence(conference_obj_t *conference); |
| 564 | |
| 565 | SWITCH_STANDARD_API(conf_api_main)static switch_status_t conf_api_main ( const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream); |
| 566 | |
| 567 | static switch_status_t conference_outcall(conference_obj_t *conference, |
| 568 | char *conference_name, |
| 569 | switch_core_session_t *session, |
| 570 | char *bridgeto, uint32_t timeout, |
| 571 | char *flags, |
| 572 | char *cid_name, |
| 573 | char *cid_num, |
| 574 | char *profile, |
| 575 | switch_call_cause_t *cause, |
| 576 | switch_call_cause_t *cancel_cause, switch_event_t *var_event); |
| 577 | static switch_status_t conference_outcall_bg(conference_obj_t *conference, |
| 578 | char *conference_name, |
| 579 | switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name, |
| 580 | const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause, switch_event_t **var_event); |
| 581 | SWITCH_STANDARD_APP(conference_function)static void conference_function (switch_core_session_t *session , const char *data); |
| 582 | static void launch_conference_thread(conference_obj_t *conference); |
| 583 | static void launch_conference_video_thread(conference_obj_t *conference); |
| 584 | static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *obj); |
| 585 | static switch_status_t conference_local_play_file(conference_obj_t *conference, switch_core_session_t *session, char *path, uint32_t leadin, void *buf, |
| 586 | uint32_t buflen); |
| 587 | static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin, switch_bool_t mux); |
| 588 | static switch_status_t conference_member_say(conference_member_t *member, char *text, uint32_t leadin); |
| 589 | static uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop); |
| 590 | static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_core_session_t *session, switch_memory_pool_t *pool); |
| 591 | static switch_status_t chat_send(switch_event_t *message_event); |
| 592 | |
| 593 | |
| 594 | static void launch_conference_record_thread(conference_obj_t *conference, char *path, switch_bool_t autorec); |
| 595 | static int launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b); |
| 596 | |
| 597 | typedef switch_status_t (*conf_api_args_cmd_t) (conference_obj_t *, switch_stream_handle_t *, int, char **); |
| 598 | typedef switch_status_t (*conf_api_member_cmd_t) (conference_member_t *, switch_stream_handle_t *, void *); |
| 599 | typedef switch_status_t (*conf_api_text_cmd_t) (conference_obj_t *, switch_stream_handle_t *, const char *); |
| 600 | |
| 601 | static void conference_member_itterator(conference_obj_t *conference, switch_stream_handle_t *stream, uint8_t non_mod, conf_api_member_cmd_t pfncallback, void *data); |
| 602 | static switch_status_t conf_api_sub_mute(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
| 603 | static switch_status_t conf_api_sub_tmute(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
| 604 | static switch_status_t conf_api_sub_unmute(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
| 605 | static switch_status_t conf_api_sub_deaf(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
| 606 | static switch_status_t conf_api_sub_undeaf(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
| 607 | static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event); |
| 608 | static switch_status_t conference_add_event_member_data(conference_member_t *member, switch_event_t *event); |
| 609 | static switch_status_t conf_api_sub_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
| 610 | static switch_status_t conf_api_sub_vid_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data); |
| 611 | static switch_status_t conf_api_sub_clear_vid_floor(conference_obj_t *conference, switch_stream_handle_t *stream, void *data); |
| 612 | |
| 613 | |
| 614 | #define lock_member(_member)switch_mutex_lock(_member->write_mutex); switch_mutex_lock (_member->read_mutex) switch_mutex_lock(_member->write_mutex); switch_mutex_lock(_member->read_mutex) |
| 615 | #define unlock_member(_member)switch_mutex_unlock(_member->read_mutex); switch_mutex_unlock (_member->write_mutex) switch_mutex_unlock(_member->read_mutex); switch_mutex_unlock(_member->write_mutex) |
| 616 | |
| 617 | //#define lock_member(_member) switch_mutex_lock(_member->write_mutex) |
| 618 | //#define unlock_member(_member) switch_mutex_unlock(_member->write_mutex) |
| 619 | |
| 620 | static al_handle_t *create_al(switch_memory_pool_t *pool) |
| 621 | { |
| 622 | al_handle_t *al; |
| 623 | |
| 624 | al = switch_core_alloc(pool, sizeof(al_handle_t))switch_core_perform_alloc(pool, sizeof(al_handle_t), "mod_conference.c" , (const char *)__func__, 624); |
| 625 | |
| 626 | return al; |
| 627 | } |
| 628 | |
| 629 | #ifndef OPENAL_POSITIONING |
| 630 | static void gen_arc(conference_obj_t *conference, switch_stream_handle_t *stream) |
| 631 | { |
| 632 | } |
| 633 | static void process_al(al_handle_t *al, void *data, switch_size_t datalen, int rate) |
| 634 | { |
| 635 | } |
| 636 | |
| 637 | #else |
| 638 | static void gen_arc(conference_obj_t *conference, switch_stream_handle_t *stream) |
| 639 | { |
| 640 | float offset; |
| 641 | float pos; |
| 642 | float radius; |
| 643 | float x, z; |
| 644 | float div = 3.14159f / 180; |
| 645 | conference_member_t *member; |
| 646 | uint32_t count = 0; |
| 647 | |
| 648 | if (!conference->count) { |
| 649 | return; |
| 650 | } |
| 651 | |
| 652 | switch_mutex_lock(conference->member_mutex); |
| 653 | for (member = conference->members; member; member = member->next) { |
| 654 | if (member->channel && switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) && !switch_test_flag(member, MFLAG_NO_POSITIONAL)((member)->flags & MFLAG_NO_POSITIONAL)) { |
| 655 | count++; |
| 656 | } |
| 657 | } |
| 658 | |
| 659 | if (count < 3) { |
| 660 | for (member = conference->members; member; member = member->next) { |
| 661 | if (member->channel && !switch_test_flag(member, MFLAG_NO_POSITIONAL)((member)->flags & MFLAG_NO_POSITIONAL) && member->al) { |
| 662 | member->al->pos_x = 0; |
| 663 | member->al->pos_y = 0; |
| 664 | member->al->pos_z = 0; |
| 665 | member->al->setpos = 1; |
| 666 | |
| 667 | if (stream) { |
| 668 | stream->write_function(stream, "Member %d (%s) 0.0:0.0:0.0\n", member->id, switch_channel_get_name(member->channel)); |
| 669 | } else { |
| 670 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 670, ((void*)0), SWITCH_LOG_DEBUG, "Member %d (%s) 0.0:0.0:0.0\n", |
| 671 | member->id, switch_channel_get_name(member->channel)); |
| 672 | } |
| 673 | } |
| 674 | } |
| 675 | |
| 676 | goto end; |
| 677 | } |
| 678 | |
| 679 | offset = 180 / (count - 1); |
| 680 | |
| 681 | radius = 1.0f; |
| 682 | |
| 683 | pos = -90.0f; |
| 684 | |
| 685 | for (member = conference->members; member; member = member->next) { |
| 686 | |
| 687 | if (!member->channel || switch_test_flag(member, MFLAG_NO_POSITIONAL)((member)->flags & MFLAG_NO_POSITIONAL) || !switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
| 688 | continue; |
| 689 | } |
| 690 | |
| 691 | if (!member->al) { |
| 692 | member->al = create_al(member->pool); |
| 693 | } |
| 694 | switch_set_flag(member, MFLAG_POSITIONAL)(member)->flags |= (MFLAG_POSITIONAL); |
| 695 | |
| 696 | if (pos == 0) { |
| 697 | x = 0; |
| 698 | z = radius; |
| 699 | } else if (pos == -90) { |
| 700 | z = 0; |
| 701 | x = radius * -1; |
| 702 | } else if (pos == 90) { |
| 703 | z = 0; |
| 704 | x = radius; |
| 705 | } else if (pos < 0) { |
| 706 | z = cos((90+pos) * div) * radius; |
| 707 | x = sin((90+pos) * div) * radius * -1.0f; |
| 708 | } else { |
| 709 | x = cos(pos * div) * radius; |
| 710 | z = sin(pos * div) * radius; |
| 711 | } |
| 712 | |
| 713 | member->al->pos_x = x; |
| 714 | member->al->pos_y = 0; |
| 715 | member->al->pos_z = z; |
| 716 | member->al->setpos = 1; |
| 717 | |
| 718 | if (stream) { |
| 719 | stream->write_function(stream, "Member %d (%s) %0.2f:0.0:%0.2f\n", member->id, switch_channel_get_name(member->channel), x, z); |
| 720 | } else { |
| 721 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 721, ((void*)0), SWITCH_LOG_DEBUG, "Member %d (%s) %0.2f:0.0:%0.2f\n", |
| 722 | member->id, switch_channel_get_name(member->channel), x, z); |
| 723 | } |
| 724 | |
| 725 | pos += offset; |
| 726 | } |
| 727 | |
| 728 | end: |
| 729 | |
| 730 | switch_mutex_unlock(conference->member_mutex); |
| 731 | |
| 732 | return; |
| 733 | |
| 734 | } |
| 735 | |
| 736 | |
| 737 | #define ALC_HRTF_SOFT 0x1992 |
| 738 | |
| 739 | static void process_al(al_handle_t *al, void *data, switch_size_t datalen, int rate) |
| 740 | { |
| 741 | |
| 742 | if (rate != 48000) { |
| 743 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 743, ((void*)0), SWITCH_LOG_ERROR, "Only 48khz is supported.\n"); |
| 744 | return; |
| 745 | } |
| 746 | |
| 747 | if (!al->device) { |
| 748 | ALCint contextAttr[] = { |
| 749 | ALC_FORMAT_CHANNELS_SOFT, ALC_STEREO_SOFT, |
| 750 | ALC_FORMAT_TYPE_SOFT, ALC_SHORT_SOFT, |
| 751 | ALC_FREQUENCY, rate, |
| 752 | ALC_HRTF_SOFT, AL_TRUE, |
| 753 | 0 |
| 754 | }; |
| 755 | |
| 756 | switch_mutex_lock(globals.setup_mutex); |
| 757 | if ((al->device = alcLoopbackOpenDeviceSOFT(NULL((void*)0)))) { |
| 758 | static const ALshort silence[16] = { 0 }; |
| 759 | float orient[6] = { /*fwd:*/ 0., 0., -1., /*up:*/ 0., 1., 0. }; |
| 760 | |
| 761 | al->context = alcCreateContext(al->device, contextAttr); |
| 762 | alcSetThreadContext(al->context); |
| 763 | |
| 764 | /* listener at origin, facing down -z (ears at 0.0m height) */ |
| 765 | alListener3f( AL_POSITION, 0. ,0, 0. ); |
| 766 | alListener3f( AL_VELOCITY, 0., 0., 0. ); |
| 767 | alListenerfv( AL_ORIENTATION, orient ); |
| 768 | |
| 769 | |
| 770 | alGenSources(1, &al->source); |
| 771 | alSourcef( al->source, AL_PITCH, 1.); |
| 772 | alSourcef( al->source, AL_GAIN, 1.); |
| 773 | alGenBuffers(2, al->buffer_in); |
| 774 | |
| 775 | alBufferData(al->buffer_in[0], AL_FORMAT_MONO16, data, datalen, rate); |
| 776 | //alBufferData(al->buffer_in[0], AL_FORMAT_MONO16, NULL, 0, rate); |
| 777 | alBufferData(al->buffer_in[1], AL_FORMAT_MONO16, silence, sizeof(silence), rate); |
| 778 | alSourceQueueBuffers(al->source, 2, al->buffer_in); |
| 779 | alSourcePlay(al->source); |
| 780 | } |
| 781 | switch_mutex_unlock(globals.setup_mutex); |
| 782 | } |
| 783 | |
| 784 | if (al->device) { |
| 785 | ALint processed = 0, state = 0; |
| 786 | |
| 787 | //alcSetThreadContext(al->context); |
| 788 | alGetSourcei(al->source, AL_SOURCE_STATE, &state); |
| 789 | alGetSourcei(al->source, AL_BUFFERS_PROCESSED, &processed); |
| 790 | |
| 791 | if (al->setpos) { |
| 792 | al->setpos = 0; |
| 793 | alSource3f(al->source, AL_POSITION, al->pos_x, al->pos_y, al->pos_z); |
| 794 | //alSource3f(al->source, AL_VELOCITY, .01, 0., 0.); |
| 795 | } |
| 796 | |
| 797 | if (processed > 0) { |
| 798 | ALuint bufid; |
| 799 | alSourceUnqueueBuffers(al->source, 1, &bufid); |
| 800 | alBufferData(bufid, AL_FORMAT_MONO16, data, datalen, rate); |
| 801 | alSourceQueueBuffers(al->source, 1, &bufid); |
| 802 | } |
| 803 | |
| 804 | if (state != AL_PLAYING) { |
| 805 | alSourcePlay(al->source); |
| 806 | } |
| 807 | |
| 808 | alcRenderSamplesSOFT(al->device, data, datalen / 2); |
| 809 | } |
| 810 | } |
| 811 | #endif |
| 812 | |
| 813 | static void conference_cdr_del(conference_member_t *member) |
| 814 | { |
| 815 | if (member->channel) { |
| 816 | switch_channel_get_variables(member->channel, &member->cdr_node->var_event); |
| 817 | } |
| 818 | member->cdr_node->leave_time = switch_epoch_time_now(NULL((void*)0)); |
| 819 | member->cdr_node->flags = member->flags; |
| 820 | member->cdr_node->member = NULL((void*)0); |
| 821 | } |
| 822 | |
| 823 | static void conference_cdr_add(conference_member_t *member) |
| 824 | { |
| 825 | conference_cdr_node_t *np; |
| 826 | switch_caller_profile_t *cp; |
| 827 | switch_channel_t *channel; |
| 828 | |
| 829 | np = switch_core_alloc(member->conference->pool, sizeof(*np))switch_core_perform_alloc(member->conference->pool, sizeof (*np), "mod_conference.c", (const char *)__func__, 829); |
| 830 | |
| 831 | np->next = member->conference->cdr_nodes; |
| 832 | member->conference->cdr_nodes = member->cdr_node = np; |
| 833 | member->cdr_node->join_time = switch_epoch_time_now(NULL((void*)0)); |
| 834 | member->cdr_node->member = member; |
| 835 | |
| 836 | if (!member->session) { |
| 837 | member->cdr_node->record_path = switch_core_strdup(member->conference->pool, member->rec_path)switch_core_perform_strdup(member->conference->pool, member ->rec_path, "mod_conference.c", (const char *)__func__, 837 ); |
| 838 | return; |
| 839 | } |
| 840 | |
| 841 | channel = switch_core_session_get_channel(member->session); |
| 842 | |
| 843 | if (!(cp = switch_channel_get_caller_profile(channel))) { |
| 844 | return; |
| 845 | } |
| 846 | |
| 847 | member->cdr_node->cp = switch_caller_profile_dup(member->conference->pool, cp); |
| 848 | |
| 849 | member->cdr_node->id = member->id; |
| 850 | |
| 851 | |
| 852 | |
| 853 | } |
| 854 | |
| 855 | static void conference_cdr_rejected(conference_obj_t *conference, switch_channel_t *channel, cdr_reject_reason_t reason) |
| 856 | { |
| 857 | conference_cdr_reject_t *rp; |
| 858 | switch_caller_profile_t *cp; |
| 859 | |
| 860 | rp = switch_core_alloc(conference->pool, sizeof(*rp))switch_core_perform_alloc(conference->pool, sizeof(*rp), "mod_conference.c" , (const char *)__func__, 860); |
| 861 | |
| 862 | rp->next = conference->cdr_rejected; |
| 863 | conference->cdr_rejected = rp; |
| 864 | rp->reason = reason; |
| 865 | rp->reject_time = switch_epoch_time_now(NULL((void*)0)); |
| 866 | |
| 867 | if (!(cp = switch_channel_get_caller_profile(channel))) { |
| 868 | return; |
| 869 | } |
| 870 | |
| 871 | rp->cp = switch_caller_profile_dup(conference->pool, cp); |
| 872 | } |
| 873 | |
| 874 | static const char *audio_flow(conference_member_t *member) |
| 875 | { |
| 876 | const char *flow = "sendrecv"; |
| 877 | |
| 878 | if (!switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
| 879 | flow = "recvonly"; |
| 880 | } |
| 881 | |
| 882 | if (member->channel && switch_channel_test_flag(member->channel, CF_HOLD)) { |
| 883 | flow = switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) ? "sendonly" : "inactive"; |
| 884 | } |
| 885 | |
| 886 | return flow; |
| 887 | } |
| 888 | |
| 889 | static char *conference_rfc4579_render(conference_obj_t *conference, switch_event_t *event, switch_event_t *revent) |
| 890 | { |
| 891 | switch_xml_t xml, x_tag, x_tag1, x_tag2, x_tag3, x_tag4; |
| 892 | char tmp[30]; |
| 893 | const char *domain; const char *name; |
| 894 | char *dup_domain = NULL((void*)0); |
| 895 | char *uri; |
| 896 | int off = 0, off1 = 0, off2 = 0, off3 = 0, off4 = 0; |
| 897 | conference_cdr_node_t *np; |
| 898 | char *tmpp = tmp; |
| 899 | char *xml_text = NULL((void*)0); |
| 900 | |
| 901 | if (!(xml = switch_xml_new("conference-info"))) { |
| 902 | abort(); |
| 903 | } |
| 904 | |
| 905 | switch_mutex_lock(conference->mutex); |
| 906 | switch_snprintf(tmp, sizeof(tmp), "%u", conference->doc_version); |
| 907 | conference->doc_version++; |
| 908 | switch_mutex_unlock(conference->mutex); |
| 909 | |
| 910 | if (!event || !(name = switch_event_get_header(event, "conference-name")switch_event_get_header_idx(event, "conference-name", -1))) { |
| 911 | if (!(name = conference->name)) { |
| 912 | name = "conference"; |
| 913 | } |
| 914 | } |
| 915 | |
| 916 | if (!event || !(domain = switch_event_get_header(event, "conference-domain")switch_event_get_header_idx(event, "conference-domain", -1))) { |
| 917 | if (!(domain = conference->domain)) { |
| 918 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
| 919 | if (!(domain = dup_domain)) { |
| 920 | domain = "cluecon.com"; |
| 921 | } |
| 922 | } |
| 923 | } |
| 924 | |
| 925 | switch_xml_set_attr_d(xml, "version", tmpp)switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), (__extension__ (__builtin_constant_p ("version") && ( (size_t)(const void *)(("version") + 1) - (size_t)(const void *)("version") == 1) ? (((const char *) ("version"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("version") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "version", __len); __retval; })) : __strdup ("version" ))), (__extension__ (__builtin_constant_p ((tmpp ? tmpp : "") ) && ((size_t)(const void *)(((tmpp ? tmpp : "")) + 1 ) - (size_t)(const void *)((tmpp ? tmpp : "")) == 1) ? (((const char *) ((tmpp ? tmpp : "")))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((tmpp ? tmpp : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (tmpp ? tmpp : ""), __len); __retval; })) : __strdup ((tmpp ? tmpp : ""))))); |
| 926 | |
| 927 | switch_xml_set_attr_d(xml, "state", "full")switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), (__extension__ (__builtin_constant_p ("state") && (( size_t)(const void *)(("state") + 1) - (size_t)(const void *) ("state") == 1) ? (((const char *) ("state"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("state") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "state", __len); __retval; })) : __strdup ("state"))), (__extension__ (__builtin_constant_p (("full" ? "full" : "")) && (( size_t)(const void *)((("full" ? "full" : "")) + 1) - (size_t )(const void *)(("full" ? "full" : "")) == 1) ? (((const char *) (("full" ? "full" : "")))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("full" ? "full" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("full" ? "full" : ""), __len); __retval; })) : __strdup (("full" ? "full" : ""))))); |
| 928 | switch_xml_set_attr_d(xml, "xmlns", "urn:ietf:params:xml:ns:conference-info")switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), (__extension__ (__builtin_constant_p ("xmlns") && (( size_t)(const void *)(("xmlns") + 1) - (size_t)(const void *) ("xmlns") == 1) ? (((const char *) ("xmlns"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("xmlns") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "xmlns", __len); __retval; })) : __strdup ("xmlns"))), (__extension__ (__builtin_constant_p (("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")) && ((size_t)(const void *)((("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")) + 1) - (size_t )(const void *)(("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")) == 1) ? (((const char *) (("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : ""), __len); __retval ; })) : __strdup (("urn:ietf:params:xml:ns:conference-info" ? "urn:ietf:params:xml:ns:conference-info" : ""))))); |
| 929 | |
| 930 | |
| 931 | uri = switch_mprintf("sip:%s@%s", name, domain); |
| 932 | switch_xml_set_attr_d(xml, "entity", uri)switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), (__extension__ (__builtin_constant_p ("entity") && ( (size_t)(const void *)(("entity") + 1) - (size_t)(const void * )("entity") == 1) ? (((const char *) ("entity"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("entity") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "entity", __len); __retval; })) : __strdup ("entity"))), (__extension__ (__builtin_constant_p ((uri ? uri : "")) && ((size_t )(const void *)(((uri ? uri : "")) + 1) - (size_t)(const void *)((uri ? uri : "")) == 1) ? (((const char *) ((uri ? uri : "" )))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ( { size_t __len = strlen ((uri ? uri : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (uri ? uri : ""), __len); __retval ; })) : __strdup ((uri ? uri : ""))))); |
| 933 | |
| 934 | if (!(x_tag = switch_xml_add_child_d(xml, "conference-description", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ ( __builtin_constant_p ("conference-description") && (( size_t)(const void *)(("conference-description") + 1) - (size_t )(const void *)("conference-description") == 1) ? (((const char *) ("conference-description"))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference-description" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "conference-description" , __len); __retval; })) : __strdup ("conference-description") )), off++), SWITCH_XML_NAMEM))) { |
| 935 | abort(); |
| 936 | } |
| 937 | |
| 938 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "display-text", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("display-text") && ((size_t)( const void *)(("display-text") + 1) - (size_t)(const void *)( "display-text") == 1) ? (((const char *) ("display-text"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("display-text") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "display-text", __len); __retval; })) : __strdup ("display-text"))), off1++), SWITCH_XML_NAMEM))) { |
| 939 | abort(); |
| 940 | } |
| 941 | switch_xml_set_txt_d(x_tag1, conference->desc ? conference->desc : "FreeSWITCH Conference")switch_xml_set_flag(switch_xml_set_txt(x_tag1, (__extension__ (__builtin_constant_p (conference->desc ? conference-> desc : "FreeSWITCH Conference") && ((size_t)(const void *)((conference->desc ? conference->desc : "FreeSWITCH Conference" ) + 1) - (size_t)(const void *)(conference->desc ? conference ->desc : "FreeSWITCH Conference") == 1) ? (((const char *) (conference->desc ? conference->desc : "FreeSWITCH Conference" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (conference->desc ? conference-> desc : "FreeSWITCH Conference") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, conference->desc ? conference->desc : "FreeSWITCH Conference", __len); __retval; })) : __strdup ( conference->desc ? conference->desc : "FreeSWITCH Conference" )))), SWITCH_XML_TXTM); |
| 942 | |
| 943 | |
| 944 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "conf-uris", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("conf-uris") && ((size_t)(const void *)(("conf-uris") + 1) - (size_t)(const void *)("conf-uris" ) == 1) ? (((const char *) ("conf-uris"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "conf-uris") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "conf-uris", __len); __retval; })) : __strdup ("conf-uris") )), off1++), SWITCH_XML_NAMEM))) { |
| 945 | abort(); |
| 946 | } |
| 947 | |
| 948 | if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "entry", off2++)switch_xml_set_flag(switch_xml_add_child(x_tag1, (__extension__ (__builtin_constant_p ("entry") && ((size_t)(const void *)(("entry") + 1) - (size_t)(const void *)("entry") == 1) ? ( ((const char *) ("entry"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("entry") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "entry", __len); __retval ; })) : __strdup ("entry"))), off2++), SWITCH_XML_NAMEM))) { |
| 949 | abort(); |
| 950 | } |
| 951 | |
| 952 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "uri", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("uri") && ((size_t)(const void *)(("uri") + 1) - (size_t)(const void *)("uri") == 1) ? (((const char *) ("uri"))[0] == '\0' ? (char *) calloc ((size_t) 1, ( size_t) 1) : ({ size_t __len = strlen ("uri") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "uri", __len); __retval; })) : __strdup ("uri"))), off3++), SWITCH_XML_NAMEM))) { |
| 953 | abort(); |
| 954 | } |
| 955 | switch_xml_set_txt_d(x_tag3, uri)switch_xml_set_flag(switch_xml_set_txt(x_tag3, (__extension__ (__builtin_constant_p (uri) && ((size_t)(const void * )((uri) + 1) - (size_t)(const void *)(uri) == 1) ? (((const char *) (uri))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (uri) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, uri, __len); __retval; })) : __strdup ( uri)))), SWITCH_XML_TXTM); |
| 956 | |
| 957 | |
| 958 | |
| 959 | if (!(x_tag = switch_xml_add_child_d(xml, "conference-state", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ ( __builtin_constant_p ("conference-state") && ((size_t )(const void *)(("conference-state") + 1) - (size_t)(const void *)("conference-state") == 1) ? (((const char *) ("conference-state" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference-state") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "conference-state", __len); __retval ; })) : __strdup ("conference-state"))), off++), SWITCH_XML_NAMEM ))) { |
| 960 | abort(); |
| 961 | } |
| 962 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "user-count", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("user-count") && ((size_t)(const void *)(("user-count") + 1) - (size_t)(const void *)("user-count" ) == 1) ? (((const char *) ("user-count"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("user-count") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "user-count", __len); __retval; })) : __strdup ("user-count" ))), off1++), SWITCH_XML_NAMEM))) { |
| 963 | abort(); |
| 964 | } |
| 965 | switch_snprintf(tmp, sizeof(tmp), "%u", conference->count); |
| 966 | switch_xml_set_txt_d(x_tag1, tmpp)switch_xml_set_flag(switch_xml_set_txt(x_tag1, (__extension__ (__builtin_constant_p (tmpp) && ((size_t)(const void *)((tmpp) + 1) - (size_t)(const void *)(tmpp) == 1) ? (((const char *) (tmpp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (tmpp) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, tmpp, __len); __retval; })) : __strdup (tmpp)))), SWITCH_XML_TXTM); |
| 967 | |
| 968 | #if 0 |
| 969 | if (conference->count == 0) { |
| 970 | switch_event_add_header(revent, SWITCH_STACK_BOTTOM, "notfound", "true"); |
| 971 | } |
| 972 | #endif |
| 973 | |
| 974 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "active", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("active") && ((size_t)(const void *)(("active") + 1) - (size_t)(const void *)("active") == 1) ? (((const char *) ("active"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("active") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "active", __len ); __retval; })) : __strdup ("active"))), off1++), SWITCH_XML_NAMEM ))) { |
| 975 | abort(); |
| 976 | } |
| 977 | switch_xml_set_txt_d(x_tag1, "true")switch_xml_set_flag(switch_xml_set_txt(x_tag1, (__extension__ (__builtin_constant_p ("true") && ((size_t)(const void *)(("true") + 1) - (size_t)(const void *)("true") == 1) ? (( (const char *) ("true"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("true") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "true", __len); __retval ; })) : __strdup ("true")))), SWITCH_XML_TXTM); |
| 978 | |
| 979 | off1 = off2 = off3 = off4 = 0; |
| 980 | |
| 981 | if (!(x_tag = switch_xml_add_child_d(xml, "users", off++)switch_xml_set_flag(switch_xml_add_child(xml, (__extension__ ( __builtin_constant_p ("users") && ((size_t)(const void *)(("users") + 1) - (size_t)(const void *)("users") == 1) ? ( ((const char *) ("users"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("users") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "users", __len); __retval ; })) : __strdup ("users"))), off++), SWITCH_XML_NAMEM))) { |
| 982 | abort(); |
| 983 | } |
| 984 | |
| 985 | switch_mutex_lock(conference->member_mutex); |
| 986 | |
| 987 | for (np = conference->cdr_nodes; np; np = np->next) { |
| 988 | char *user_uri = NULL((void*)0); |
| 989 | switch_channel_t *channel = NULL((void*)0); |
| 990 | |
| 991 | if (!np->cp || (np->member && !np->member->session) || np->leave_time) { /* for now we'll remove participants when the leave */ |
| 992 | continue; |
| 993 | } |
| 994 | |
| 995 | if (np->member && np->member->session) { |
| 996 | channel = switch_core_session_get_channel(np->member->session); |
| 997 | } |
| 998 | |
| 999 | if (!(x_tag1 = switch_xml_add_child_d(x_tag, "user", off1++)switch_xml_set_flag(switch_xml_add_child(x_tag, (__extension__ (__builtin_constant_p ("user") && ((size_t)(const void *)(("user") + 1) - (size_t)(const void *)("user") == 1) ? (( (const char *) ("user"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("user") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "user", __len); __retval ; })) : __strdup ("user"))), off1++), SWITCH_XML_NAMEM))) { |
| 1000 | abort(); |
| 1001 | } |
| 1002 | |
| 1003 | if (channel) { |
| 1004 | const char *uri = switch_channel_get_variable_dup(channel, "conference_invite_uri", SWITCH_FALSE, -1); |
| 1005 | |
| 1006 | if (uri) { |
| 1007 | user_uri = strdup(uri)(__extension__ (__builtin_constant_p (uri) && ((size_t )(const void *)((uri) + 1) - (size_t)(const void *)(uri) == 1 ) ? (((const char *) (uri))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (uri) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, uri, __len); __retval ; })) : __strdup (uri))); |
| 1008 | } |
| 1009 | } |
| 1010 | |
| 1011 | if (!user_uri) { |
| 1012 | user_uri = switch_mprintf("sip:%s@%s", np->cp->caller_id_number, domain); |
| 1013 | } |
| 1014 | |
| 1015 | |
| 1016 | switch_xml_set_attr_d(x_tag1, "state", "full")switch_xml_set_attr(switch_xml_set_flag(x_tag1, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("state") && ( (size_t)(const void *)(("state") + 1) - (size_t)(const void * )("state") == 1) ? (((const char *) ("state"))[0] == '\0' ? ( char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("state") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "state", __len); __retval; })) : __strdup ("state"))), (__extension__ (__builtin_constant_p (("full" ? "full" : "")) && (( size_t)(const void *)((("full" ? "full" : "")) + 1) - (size_t )(const void *)(("full" ? "full" : "")) == 1) ? (((const char *) (("full" ? "full" : "")))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("full" ? "full" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("full" ? "full" : ""), __len); __retval; })) : __strdup (("full" ? "full" : ""))))); |
| 1017 | switch_xml_set_attr_d(x_tag1, "entity", user_uri)switch_xml_set_attr(switch_xml_set_flag(x_tag1, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("entity") && ((size_t)(const void *)(("entity") + 1) - (size_t)(const void *)("entity") == 1) ? (((const char *) ("entity"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("entity") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "entity", __len); __retval; })) : __strdup ("entity"))), (__extension__ (__builtin_constant_p ((user_uri ? user_uri : "")) && ((size_t)(const void *)(((user_uri ? user_uri : "")) + 1) - ( size_t)(const void *)((user_uri ? user_uri : "")) == 1) ? ((( const char *) ((user_uri ? user_uri : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((user_uri ? user_uri : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (user_uri ? user_uri : ""), __len); __retval; })) : __strdup ((user_uri ? user_uri : ""))))); |
| 1018 | |
| 1019 | if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "display-text", off2++)switch_xml_set_flag(switch_xml_add_child(x_tag1, (__extension__ (__builtin_constant_p ("display-text") && ((size_t)( const void *)(("display-text") + 1) - (size_t)(const void *)( "display-text") == 1) ? (((const char *) ("display-text"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("display-text") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "display-text", __len); __retval; })) : __strdup ("display-text"))), off2++), SWITCH_XML_NAMEM))) { |
| 1020 | abort(); |
| 1021 | } |
| 1022 | switch_xml_set_txt_d(x_tag2, np->cp->caller_id_name)switch_xml_set_flag(switch_xml_set_txt(x_tag2, (__extension__ (__builtin_constant_p (np->cp->caller_id_name) && ((size_t)(const void *)((np->cp->caller_id_name) + 1) - (size_t)(const void *)(np->cp->caller_id_name) == 1) ? (((const char *) (np->cp->caller_id_name))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (np->cp->caller_id_name) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, np->cp->caller_id_name, __len ); __retval; })) : __strdup (np->cp->caller_id_name)))) , SWITCH_XML_TXTM); |
| 1023 | |
| 1024 | |
| 1025 | if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "endpoint", off2++)switch_xml_set_flag(switch_xml_add_child(x_tag1, (__extension__ (__builtin_constant_p ("endpoint") && ((size_t)(const void *)(("endpoint") + 1) - (size_t)(const void *)("endpoint" ) == 1) ? (((const char *) ("endpoint"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "endpoint") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "endpoint", __len); __retval; })) : __strdup ("endpoint"))) , off2++), SWITCH_XML_NAMEM))) { |
| 1026 | abort(); |
| 1027 | } |
| 1028 | switch_xml_set_attr_d(x_tag2, "entity", user_uri)switch_xml_set_attr(switch_xml_set_flag(x_tag2, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("entity") && ((size_t)(const void *)(("entity") + 1) - (size_t)(const void *)("entity") == 1) ? (((const char *) ("entity"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("entity") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "entity", __len); __retval; })) : __strdup ("entity"))), (__extension__ (__builtin_constant_p ((user_uri ? user_uri : "")) && ((size_t)(const void *)(((user_uri ? user_uri : "")) + 1) - ( size_t)(const void *)((user_uri ? user_uri : "")) == 1) ? ((( const char *) ((user_uri ? user_uri : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((user_uri ? user_uri : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (user_uri ? user_uri : ""), __len); __retval; })) : __strdup ((user_uri ? user_uri : ""))))); |
| 1029 | |
| 1030 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "display-text", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("display-text") && ((size_t)( const void *)(("display-text") + 1) - (size_t)(const void *)( "display-text") == 1) ? (((const char *) ("display-text"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("display-text") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "display-text", __len); __retval; })) : __strdup ("display-text"))), off3++), SWITCH_XML_NAMEM))) { |
| 1031 | abort(); |
| 1032 | } |
| 1033 | switch_xml_set_txt_d(x_tag3, np->cp->caller_id_name)switch_xml_set_flag(switch_xml_set_txt(x_tag3, (__extension__ (__builtin_constant_p (np->cp->caller_id_name) && ((size_t)(const void *)((np->cp->caller_id_name) + 1) - (size_t)(const void *)(np->cp->caller_id_name) == 1) ? (((const char *) (np->cp->caller_id_name))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (np->cp->caller_id_name) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, np->cp->caller_id_name, __len ); __retval; })) : __strdup (np->cp->caller_id_name)))) , SWITCH_XML_TXTM); |
| 1034 | |
| 1035 | |
| 1036 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "status", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("status") && ((size_t)(const void *)(("status") + 1) - (size_t)(const void *)("status") == 1) ? (((const char *) ("status"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("status") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "status", __len ); __retval; })) : __strdup ("status"))), off3++), SWITCH_XML_NAMEM ))) { |
| 1037 | abort(); |
| 1038 | } |
| 1039 | switch_xml_set_txt_d(x_tag3, np->leave_time ? "disconnected" : "connected")switch_xml_set_flag(switch_xml_set_txt(x_tag3, (__extension__ (__builtin_constant_p (np->leave_time ? "disconnected" : "connected" ) && ((size_t)(const void *)((np->leave_time ? "disconnected" : "connected") + 1) - (size_t)(const void *)(np->leave_time ? "disconnected" : "connected") == 1) ? (((const char *) (np ->leave_time ? "disconnected" : "connected"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (np->leave_time ? "disconnected" : "connected") + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, np->leave_time ? "disconnected" : "connected", __len); __retval; })) : __strdup (np->leave_time ? "disconnected" : "connected")))), SWITCH_XML_TXTM ); |
| 1040 | |
| 1041 | |
| 1042 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "joining-info", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("joining-info") && ((size_t)( const void *)(("joining-info") + 1) - (size_t)(const void *)( "joining-info") == 1) ? (((const char *) ("joining-info"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("joining-info") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "joining-info", __len); __retval; })) : __strdup ("joining-info"))), off3++), SWITCH_XML_NAMEM))) { |
| 1043 | abort(); |
| 1044 | } |
| 1045 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "when", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("when") && ((size_t)(const void *)(("when") + 1) - (size_t)(const void *)("when") == 1) ? (( (const char *) ("when"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("when") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "when", __len); __retval ; })) : __strdup ("when"))), off4++), SWITCH_XML_NAMEM))) { |
| 1046 | abort(); |
| 1047 | } else { |
| 1048 | switch_time_exp_t tm; |
| 1049 | switch_size_t retsize; |
| 1050 | const char *fmt = "%Y-%m-%dT%H:%M:%S%z"; |
| 1051 | char *p; |
| 1052 | |
| 1053 | switch_time_exp_lt(&tm, (switch_time_t) conference->start_time * 1000000); |
| 1054 | switch_strftime_nocheck(tmp, &retsize, sizeof(tmp), fmt, &tm); |
| 1055 | p = end_of_p(tmpp)(*tmpp == '\0' ? tmpp : tmpp + strlen(tmpp) - 1) -1; |
| 1056 | snprintf(p, 4, ":00"); |
| 1057 | |
| 1058 | |
| 1059 | switch_xml_set_txt_d(x_tag4, tmpp)switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (tmpp) && ((size_t)(const void *)((tmpp) + 1) - (size_t)(const void *)(tmpp) == 1) ? (((const char *) (tmpp))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (tmpp) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, tmpp, __len); __retval; })) : __strdup (tmpp)))), SWITCH_XML_TXTM); |
| 1060 | } |
| 1061 | |
| 1062 | |
| 1063 | |
| 1064 | |
| 1065 | /** ok so this is in the rfc but not the xsd |
| 1066 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "joining-method", off3++))) { |
| 1067 | abort(); |
| 1068 | } |
| 1069 | switch_xml_set_txt_d(x_tag3, np->cp->direction == SWITCH_CALL_DIRECTION_INBOUND ? "dialed-in" : "dialed-out"); |
| 1070 | */ |
| 1071 | |
| 1072 | if (np->member) { |
| 1073 | const char *var; |
| 1074 | //char buf[1024]; |
| 1075 | |
| 1076 | //switch_snprintf(buf, sizeof(buf), "conf_%s_%s_%s", conference->name, conference->domain, np->cp->caller_id_number); |
| 1077 | //switch_channel_set_variable(channel, "conference_call_key", buf); |
| 1078 | |
| 1079 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "media", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("media") && ((size_t)(const void *)(("media") + 1) - (size_t)(const void *)("media") == 1) ? ( ((const char *) ("media"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("media") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "media", __len); __retval ; })) : __strdup ("media"))), off3++), SWITCH_XML_NAMEM))) { |
| 1080 | abort(); |
| 1081 | } |
| 1082 | |
| 1083 | snprintf(tmp, sizeof(tmp), "%ua", np->member->id); |
| 1084 | switch_xml_set_attr_d(x_tag3, "id", tmpp)switch_xml_set_attr(switch_xml_set_flag(x_tag3, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("id") && ((size_t )(const void *)(("id") + 1) - (size_t)(const void *)("id") == 1) ? (((const char *) ("id"))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("id") + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, "id", __len) ; __retval; })) : __strdup ("id"))), (__extension__ (__builtin_constant_p ((tmpp ? tmpp : "")) && ((size_t)(const void *)(((tmpp ? tmpp : "")) + 1) - (size_t)(const void *)((tmpp ? tmpp : "" )) == 1) ? (((const char *) ((tmpp ? tmpp : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((tmpp ? tmpp : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (tmpp ? tmpp : ""), __len); __retval; })) : __strdup ((tmpp ? tmpp : ""))))); |
| 1085 | |
| 1086 | |
| 1087 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "type", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("type") && ((size_t)(const void *)(("type") + 1) - (size_t)(const void *)("type") == 1) ? (( (const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "type", __len); __retval ; })) : __strdup ("type"))), off4++), SWITCH_XML_NAMEM))) { |
| 1088 | abort(); |
| 1089 | } |
| 1090 | switch_xml_set_txt_d(x_tag4, "audio")switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p ("audio") && ((size_t)(const void *)(("audio") + 1) - (size_t)(const void *)("audio") == 1) ? ( ((const char *) ("audio"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("audio") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "audio", __len); __retval ; })) : __strdup ("audio")))), SWITCH_XML_TXTM); |
| 1091 | |
| 1092 | if ((var = switch_channel_get_variable(channel, "rtp_use_ssrc")switch_channel_get_variable_dup(channel, "rtp_use_ssrc", SWITCH_TRUE , -1))) { |
| 1093 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "src-id", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("src-id") && ((size_t)(const void *)(("src-id") + 1) - (size_t)(const void *)("src-id") == 1) ? (((const char *) ("src-id"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("src-id") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "src-id", __len ); __retval; })) : __strdup ("src-id"))), off4++), SWITCH_XML_NAMEM ))) { |
| 1094 | abort(); |
| 1095 | } |
| 1096 | switch_xml_set_txt_d(x_tag4, var)switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (var) && ((size_t)(const void * )((var) + 1) - (size_t)(const void *)(var) == 1) ? (((const char *) (var))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (var) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, var, __len); __retval; })) : __strdup ( var)))), SWITCH_XML_TXTM); |
| 1097 | } |
| 1098 | |
| 1099 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "status", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("status") && ((size_t)(const void *)(("status") + 1) - (size_t)(const void *)("status") == 1) ? (((const char *) ("status"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("status") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "status", __len ); __retval; })) : __strdup ("status"))), off4++), SWITCH_XML_NAMEM ))) { |
| 1100 | abort(); |
| 1101 | } |
| 1102 | switch_xml_set_txt_d(x_tag4, audio_flow(np->member))switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (audio_flow(np->member)) && ((size_t)(const void *)((audio_flow(np->member)) + 1) - ( size_t)(const void *)(audio_flow(np->member)) == 1) ? (((const char *) (audio_flow(np->member)))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (audio_flow (np->member)) + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , audio_flow(np->member), __len); __retval; })) : __strdup (audio_flow(np->member))))), SWITCH_XML_TXTM); |
| 1103 | |
| 1104 | |
| 1105 | if (switch_channel_test_flag(channel, CF_VIDEO)) { |
| 1106 | off4 = 0; |
| 1107 | |
| 1108 | if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "media", off3++)switch_xml_set_flag(switch_xml_add_child(x_tag2, (__extension__ (__builtin_constant_p ("media") && ((size_t)(const void *)(("media") + 1) - (size_t)(const void *)("media") == 1) ? ( ((const char *) ("media"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("media") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "media", __len); __retval ; })) : __strdup ("media"))), off3++), SWITCH_XML_NAMEM))) { |
| 1109 | abort(); |
| 1110 | } |
| 1111 | |
| 1112 | snprintf(tmp, sizeof(tmp), "%uv", np->member->id); |
| 1113 | switch_xml_set_attr_d(x_tag3, "id", tmpp)switch_xml_set_attr(switch_xml_set_flag(x_tag3, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("id") && ((size_t )(const void *)(("id") + 1) - (size_t)(const void *)("id") == 1) ? (((const char *) ("id"))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("id") + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, "id", __len) ; __retval; })) : __strdup ("id"))), (__extension__ (__builtin_constant_p ((tmpp ? tmpp : "")) && ((size_t)(const void *)(((tmpp ? tmpp : "")) + 1) - (size_t)(const void *)((tmpp ? tmpp : "" )) == 1) ? (((const char *) ((tmpp ? tmpp : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((tmpp ? tmpp : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (tmpp ? tmpp : ""), __len); __retval; })) : __strdup ((tmpp ? tmpp : ""))))); |
| 1114 | |
| 1115 | |
| 1116 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "type", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("type") && ((size_t)(const void *)(("type") + 1) - (size_t)(const void *)("type") == 1) ? (( (const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "type", __len); __retval ; })) : __strdup ("type"))), off4++), SWITCH_XML_NAMEM))) { |
| 1117 | abort(); |
| 1118 | } |
| 1119 | switch_xml_set_txt_d(x_tag4, "video")switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p ("video") && ((size_t)(const void *)(("video") + 1) - (size_t)(const void *)("video") == 1) ? ( ((const char *) ("video"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("video") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "video", __len); __retval ; })) : __strdup ("video")))), SWITCH_XML_TXTM); |
| 1120 | |
| 1121 | if ((var = switch_channel_get_variable(channel, "rtp_use_video_ssrc")switch_channel_get_variable_dup(channel, "rtp_use_video_ssrc" , SWITCH_TRUE, -1))) { |
| 1122 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "src-id", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("src-id") && ((size_t)(const void *)(("src-id") + 1) - (size_t)(const void *)("src-id") == 1) ? (((const char *) ("src-id"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("src-id") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "src-id", __len ); __retval; })) : __strdup ("src-id"))), off4++), SWITCH_XML_NAMEM ))) { |
| 1123 | abort(); |
| 1124 | } |
| 1125 | switch_xml_set_txt_d(x_tag4, var)switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (var) && ((size_t)(const void * )((var) + 1) - (size_t)(const void *)(var) == 1) ? (((const char *) (var))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (var) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, var, __len); __retval; })) : __strdup ( var)))), SWITCH_XML_TXTM); |
| 1126 | } |
| 1127 | |
| 1128 | if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "status", off4++)switch_xml_set_flag(switch_xml_add_child(x_tag3, (__extension__ (__builtin_constant_p ("status") && ((size_t)(const void *)(("status") + 1) - (size_t)(const void *)("status") == 1) ? (((const char *) ("status"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("status") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "status", __len ); __retval; })) : __strdup ("status"))), off4++), SWITCH_XML_NAMEM ))) { |
| 1129 | abort(); |
| 1130 | } |
| 1131 | switch_xml_set_txt_d(x_tag4, switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv")switch_xml_set_flag(switch_xml_set_txt(x_tag4, (__extension__ (__builtin_constant_p (switch_channel_test_flag(channel, CF_HOLD ) ? "sendonly" : "sendrecv") && ((size_t)(const void * )((switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv" ) + 1) - (size_t)(const void *)(switch_channel_test_flag(channel , CF_HOLD) ? "sendonly" : "sendrecv") == 1) ? (((const char * ) (switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (switch_channel_test_flag(channel, CF_HOLD ) ? "sendonly" : "sendrecv") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv", __len); __retval; })) : __strdup (switch_channel_test_flag (channel, CF_HOLD) ? "sendonly" : "sendrecv")))), SWITCH_XML_TXTM ); |
| 1132 | |
| 1133 | } |
| 1134 | } |
| 1135 | |
| 1136 | switch_safe_free(user_uri)if (user_uri) {free(user_uri);user_uri=((void*)0);}; |
| 1137 | } |
| 1138 | |
| 1139 | switch_mutex_unlock(conference->member_mutex); |
| 1140 | |
| 1141 | off1 = off2 = off3 = off4 = 0; |
| 1142 | |
| 1143 | xml_text = switch_xml_toxml(xml, SWITCH_TRUE); |
| 1144 | switch_xml_free(xml); |
| 1145 | |
| 1146 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
| 1147 | switch_safe_free(uri)if (uri) {free(uri);uri=((void*)0);}; |
| 1148 | |
| 1149 | return xml_text; |
| 1150 | } |
| 1151 | |
| 1152 | static void conference_cdr_render(conference_obj_t *conference) |
| 1153 | { |
| 1154 | switch_xml_t cdr, x_ptr, x_member, x_members, x_conference, x_cp, x_flags, x_tag, x_rejected, x_attempt; |
| 1155 | conference_cdr_node_t *np; |
| 1156 | conference_cdr_reject_t *rp; |
| 1157 | int cdr_off = 0, conf_off = 0; |
| 1158 | char str[512]; |
| 1159 | char *path = NULL((void*)0), *xml_text; |
| 1160 | int fd; |
| 1161 | |
| 1162 | if (zstr(conference->log_dir)_zstr(conference->log_dir) && (conference->cdr_event_mode == CDRE_NONE)) return; |
| 1163 | |
| 1164 | if (!conference->cdr_nodes && !conference->cdr_rejected) return; |
| 1165 | |
| 1166 | if (!(cdr = switch_xml_new("cdr"))) { |
| 1167 | abort(); |
| 1168 | } |
| 1169 | |
| 1170 | if (!(x_conference = switch_xml_add_child_d(cdr, "conference", cdr_off++)switch_xml_set_flag(switch_xml_add_child(cdr, (__extension__ ( __builtin_constant_p ("conference") && ((size_t)(const void *)(("conference") + 1) - (size_t)(const void *)("conference" ) == 1) ? (((const char *) ("conference"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "conference", __len); __retval; })) : __strdup ("conference" ))), cdr_off++), SWITCH_XML_NAMEM))) { |
| 1171 | abort(); |
| 1172 | } |
| 1173 | |
| 1174 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "name", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("name") && ((size_t)(const void *)(("name") + 1) - (size_t)(const void *)("name") == 1) ? (( (const char *) ("name"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("name") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "name", __len); __retval ; })) : __strdup ("name"))), conf_off++), SWITCH_XML_NAMEM))) { |
| 1175 | abort(); |
| 1176 | } |
| 1177 | switch_xml_set_txt_d(x_ptr, conference->name)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (conference->name) && ((size_t )(const void *)((conference->name) + 1) - (size_t)(const void *)(conference->name) == 1) ? (((const char *) (conference ->name))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (conference->name) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, conference->name , __len); __retval; })) : __strdup (conference->name)))), SWITCH_XML_TXTM ); |
| 1178 | |
| 1179 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "hostname", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("hostname") && ((size_t)(const void *)(("hostname") + 1) - (size_t)(const void *)("hostname" ) == 1) ? (((const char *) ("hostname"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "hostname") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "hostname", __len); __retval; })) : __strdup ("hostname"))) , conf_off++), SWITCH_XML_NAMEM))) { |
| 1180 | abort(); |
| 1181 | } |
| 1182 | switch_xml_set_txt_d(x_ptr, switch_core_get_hostname())switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (switch_core_get_hostname()) && ( (size_t)(const void *)((switch_core_get_hostname()) + 1) - (size_t )(const void *)(switch_core_get_hostname()) == 1) ? (((const char *) (switch_core_get_hostname()))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (switch_core_get_hostname ()) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, switch_core_get_hostname (), __len); __retval; })) : __strdup (switch_core_get_hostname ())))), SWITCH_XML_TXTM); |
| 1183 | |
| 1184 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "rate", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("rate") && ((size_t)(const void *)(("rate") + 1) - (size_t)(const void *)("rate") == 1) ? (( (const char *) ("rate"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("rate") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "rate", __len); __retval ; })) : __strdup ("rate"))), conf_off++), SWITCH_XML_NAMEM))) { |
| 1185 | abort(); |
| 1186 | } |
| 1187 | switch_snprintf(str, sizeof(str), "%d", conference->rate); |
| 1188 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
| 1189 | |
| 1190 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "interval", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("interval") && ((size_t)(const void *)(("interval") + 1) - (size_t)(const void *)("interval" ) == 1) ? (((const char *) ("interval"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "interval") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "interval", __len); __retval; })) : __strdup ("interval"))) , conf_off++), SWITCH_XML_NAMEM))) { |
| 1191 | abort(); |
| 1192 | } |
| 1193 | switch_snprintf(str, sizeof(str), "%d", conference->interval); |
| 1194 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
| 1195 | |
| 1196 | |
| 1197 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "start_time", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("start_time") && ((size_t)(const void *)(("start_time") + 1) - (size_t)(const void *)("start_time" ) == 1) ? (((const char *) ("start_time"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("start_time") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "start_time", __len); __retval; })) : __strdup ("start_time" ))), conf_off++), SWITCH_XML_NAMEM))) { |
| 1198 | abort(); |
| 1199 | } |
| 1200 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
| 1201 | switch_snprintf(str, sizeof(str), "%ld", (long)conference->start_time); |
| 1202 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
| 1203 | |
| 1204 | |
| 1205 | if (!(x_ptr = switch_xml_add_child_d(x_conference, "end_time", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("end_time") && ((size_t)(const void *)(("end_time") + 1) - (size_t)(const void *)("end_time" ) == 1) ? (((const char *) ("end_time"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "end_time") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "end_time", __len); __retval; })) : __strdup ("end_time"))) , conf_off++), SWITCH_XML_NAMEM))) { |
| 1206 | abort(); |
| 1207 | } |
| 1208 | switch_xml_set_attr_d(x_ptr, "endconf_forced", switch_test_flag(conference, CFLAG_ENDCONF_FORCED) ? "true" : "false")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("endconf_forced") && ((size_t)(const void *)(("endconf_forced") + 1) - (size_t)(const void *)("endconf_forced") == 1) ? (((const char *) ("endconf_forced" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("endconf_forced") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "endconf_forced", __len); __retval ; })) : __strdup ("endconf_forced"))), (__extension__ (__builtin_constant_p ((((conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : "")) && ((size_t)(const void * )(((((conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : "")) + 1) - (size_t)(const void *)(((( conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" : "")) == 1) ? (((const char *) ((((conference)-> flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference )->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" : "" )))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ( { size_t __len = strlen ((((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : ""), __len); __retval; })) : __strdup ( (((conference)->flags & CFLAG_ENDCONF_FORCED) ? "true" : "false" ? ((conference)->flags & CFLAG_ENDCONF_FORCED ) ? "true" : "false" : ""))))); |
| 1209 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
| 1210 | switch_snprintf(str, sizeof(str), "%ld", (long)conference->end_time); |
| 1211 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
| 1212 | |
| 1213 | |
| 1214 | |
| 1215 | if (!(x_members = switch_xml_add_child_d(x_conference, "members", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("members") && ((size_t)(const void *)(("members") + 1) - (size_t)(const void *)("members") == 1) ? (((const char *) ("members"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("members" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "members" , __len); __retval; })) : __strdup ("members"))), conf_off++) , SWITCH_XML_NAMEM))) { |
| 1216 | abort(); |
| 1217 | } |
| 1218 | |
| 1219 | for (np = conference->cdr_nodes; np; np = np->next) { |
| 1220 | int member_off = 0; |
| 1221 | int flag_off = 0; |
| 1222 | |
| 1223 | |
| 1224 | if (!(x_member = switch_xml_add_child_d(x_members, "member", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_members, (__extension__ (__builtin_constant_p ("member") && ((size_t)(const void *)(("member") + 1) - (size_t)(const void *)("member") == 1) ? (((const char *) ("member"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("member") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "member", __len ); __retval; })) : __strdup ("member"))), conf_off++), SWITCH_XML_NAMEM ))) { |
| 1225 | abort(); |
| 1226 | } |
| 1227 | |
| 1228 | switch_xml_set_attr_d(x_member, "type", np->cp ? "caller" : "recording_node")switch_xml_set_attr(switch_xml_set_flag(x_member, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p ((np->cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : "")) && ( (size_t)(const void *)(((np->cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : "")) + 1) - (size_t )(const void *)((np->cp ? "caller" : "recording_node" ? np ->cp ? "caller" : "recording_node" : "")) == 1) ? (((const char *) ((np->cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((np-> cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : "")) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (np-> cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : ""), __len); __retval; })) : __strdup ((np->cp ? "caller" : "recording_node" ? np->cp ? "caller" : "recording_node" : ""))))); |
| 1229 | |
| 1230 | if (!(x_ptr = switch_xml_add_child_d(x_member, "join_time", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("join_time") && ((size_t)(const void *)(("join_time") + 1) - (size_t)(const void *)("join_time" ) == 1) ? (((const char *) ("join_time"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "join_time") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "join_time", __len); __retval; })) : __strdup ("join_time") )), member_off++), SWITCH_XML_NAMEM))) { |
| 1231 | abort(); |
| 1232 | } |
| 1233 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
| 1234 | switch_snprintf(str, sizeof(str), "%ld", (long) np->join_time); |
| 1235 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
| 1236 | |
| 1237 | |
| 1238 | if (!(x_ptr = switch_xml_add_child_d(x_member, "leave_time", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("leave_time") && ((size_t)(const void *)(("leave_time") + 1) - (size_t)(const void *)("leave_time" ) == 1) ? (((const char *) ("leave_time"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("leave_time") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "leave_time", __len); __retval; })) : __strdup ("leave_time" ))), member_off++), SWITCH_XML_NAMEM))) { |
| 1239 | abort(); |
| 1240 | } |
| 1241 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
| 1242 | switch_snprintf(str, sizeof(str), "%ld", (long) np->leave_time); |
| 1243 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
| 1244 | |
| 1245 | if (np->cp) { |
| 1246 | x_flags = switch_xml_add_child_d(x_member, "flags", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("flags") && ((size_t)(const void *)(("flags") + 1) - (size_t)(const void *)("flags") == 1) ? ( ((const char *) ("flags"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("flags") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "flags", __len); __retval ; })) : __strdup ("flags"))), member_off++), SWITCH_XML_NAMEM ); |
| 1247 | switch_assert(x_flags)((x_flags) ? (void) (0) : __assert_fail ("x_flags", "mod_conference.c" , 1247, __PRETTY_FUNCTION__)); |
| 1248 | |
| 1249 | x_tag = switch_xml_add_child_d(x_flags, "is_moderator", flag_off++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("is_moderator") && ((size_t)( const void *)(("is_moderator") + 1) - (size_t)(const void *)( "is_moderator") == 1) ? (((const char *) ("is_moderator"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("is_moderator") + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "is_moderator", __len); __retval; })) : __strdup ("is_moderator"))), flag_off++), SWITCH_XML_NAMEM); |
| 1250 | switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_MOD) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((np)->flags & MFLAG_MOD) ? "true" : "false") && ((size_t)(const void *)((((np)->flags & MFLAG_MOD) ? "true" : "false") + 1) - (size_t)(const void *)(((np)->flags & MFLAG_MOD) ? "true" : "false") == 1 ) ? (((const char *) (((np)->flags & MFLAG_MOD) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t ) 1) : ({ size_t __len = strlen (((np)->flags & MFLAG_MOD ) ? "true" : "false") + 1; char *__retval = (char *) malloc ( __len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((np)->flags & MFLAG_MOD) ? "true" : "false" , __len); __retval; })) : __strdup (((np)->flags & MFLAG_MOD ) ? "true" : "false")))), SWITCH_XML_TXTM); |
| 1251 | |
| 1252 | x_tag = switch_xml_add_child_d(x_flags, "end_conference", flag_off++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("end_conference") && ((size_t )(const void *)(("end_conference") + 1) - (size_t)(const void *)("end_conference") == 1) ? (((const char *) ("end_conference" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("end_conference") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "end_conference", __len); __retval ; })) : __strdup ("end_conference"))), flag_off++), SWITCH_XML_NAMEM ); |
| 1253 | switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_ENDCONF) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((np)->flags & MFLAG_ENDCONF) ? "true" : "false") && ((size_t)(const void *)((((np)->flags & MFLAG_ENDCONF) ? "true" : "false") + 1) - (size_t)(const void *)(((np)->flags & MFLAG_ENDCONF) ? "true" : "false" ) == 1) ? (((const char *) (((np)->flags & MFLAG_ENDCONF ) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((np)->flags & MFLAG_ENDCONF) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((np)->flags & MFLAG_ENDCONF) ? "true" : "false", __len); __retval; })) : __strdup (((np)->flags & MFLAG_ENDCONF) ? "true" : "false")))), SWITCH_XML_TXTM ); |
| 1254 | |
| 1255 | x_tag = switch_xml_add_child_d(x_flags, "was_kicked", flag_off++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("was_kicked") && ((size_t)(const void *)(("was_kicked") + 1) - (size_t)(const void *)("was_kicked" ) == 1) ? (((const char *) ("was_kicked"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("was_kicked") + 1; char *__retval = (char *) malloc (__len) ; if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "was_kicked", __len); __retval; })) : __strdup ("was_kicked" ))), flag_off++), SWITCH_XML_NAMEM); |
| 1256 | switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_KICKED) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((np)->flags & MFLAG_KICKED) ? "true" : "false") && ((size_t)(const void *)((((np)->flags & MFLAG_KICKED) ? "true" : "false") + 1) - (size_t)(const void *)(((np)->flags & MFLAG_KICKED) ? "true" : "false" ) == 1) ? (((const char *) (((np)->flags & MFLAG_KICKED ) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((np)->flags & MFLAG_KICKED) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((np)->flags & MFLAG_KICKED) ? "true" : "false", __len); __retval; })) : __strdup (((np)->flags & MFLAG_KICKED) ? "true" : "false")))), SWITCH_XML_TXTM); |
| 1257 | |
| 1258 | x_tag = switch_xml_add_child_d(x_flags, "is_ghost", flag_off++)switch_xml_set_flag(switch_xml_add_child(x_flags, (__extension__ (__builtin_constant_p ("is_ghost") && ((size_t)(const void *)(("is_ghost") + 1) - (size_t)(const void *)("is_ghost" ) == 1) ? (((const char *) ("is_ghost"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "is_ghost") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "is_ghost", __len); __retval; })) : __strdup ("is_ghost"))) , flag_off++), SWITCH_XML_NAMEM); |
| 1259 | switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_GHOST) ? "true" : "false")switch_xml_set_flag(switch_xml_set_txt(x_tag, (__extension__ ( __builtin_constant_p (((np)->flags & MFLAG_GHOST) ? "true" : "false") && ((size_t)(const void *)((((np)->flags & MFLAG_GHOST) ? "true" : "false") + 1) - (size_t)(const void *)(((np)->flags & MFLAG_GHOST) ? "true" : "false" ) == 1) ? (((const char *) (((np)->flags & MFLAG_GHOST ) ? "true" : "false"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (((np)->flags & MFLAG_GHOST) ? "true" : "false") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ((np)->flags & MFLAG_GHOST) ? "true" : "false", __len); __retval; })) : __strdup (((np)->flags & MFLAG_GHOST) ? "true" : "false")))), SWITCH_XML_TXTM); |
| 1260 | |
| 1261 | if (!(x_cp = switch_xml_add_child_d(x_member, "caller_profile", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("caller_profile") && ((size_t )(const void *)(("caller_profile") + 1) - (size_t)(const void *)("caller_profile") == 1) ? (((const char *) ("caller_profile" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("caller_profile") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "caller_profile", __len); __retval ; })) : __strdup ("caller_profile"))), member_off++), SWITCH_XML_NAMEM ))) { |
| 1262 | abort(); |
| 1263 | } |
| 1264 | switch_ivr_set_xml_profile_data(x_cp, np->cp, 0); |
| 1265 | } |
| 1266 | |
| 1267 | if (!zstr(np->record_path)_zstr(np->record_path)) { |
| 1268 | if (!(x_ptr = switch_xml_add_child_d(x_member, "record_path", member_off++)switch_xml_set_flag(switch_xml_add_child(x_member, (__extension__ (__builtin_constant_p ("record_path") && ((size_t)(const void *)(("record_path") + 1) - (size_t)(const void *)("record_path" ) == 1) ? (((const char *) ("record_path"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("record_path") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "record_path", __len); __retval; })) : __strdup ("record_path" ))), member_off++), SWITCH_XML_NAMEM))) { |
| 1269 | abort(); |
| 1270 | } |
| 1271 | switch_xml_set_txt_d(x_ptr, np->record_path)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (np->record_path) && ((size_t )(const void *)((np->record_path) + 1) - (size_t)(const void *)(np->record_path) == 1) ? (((const char *) (np->record_path ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (np->record_path) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, np->record_path, __len); __retval ; })) : __strdup (np->record_path)))), SWITCH_XML_TXTM); |
| 1272 | } |
| 1273 | |
| 1274 | |
| 1275 | } |
| 1276 | |
| 1277 | if (!(x_rejected = switch_xml_add_child_d(x_conference, "rejected", conf_off++)switch_xml_set_flag(switch_xml_add_child(x_conference, (__extension__ (__builtin_constant_p ("rejected") && ((size_t)(const void *)(("rejected") + 1) - (size_t)(const void *)("rejected" ) == 1) ? (((const char *) ("rejected"))[0] == '\0' ? (char * ) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( "rejected") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "rejected", __len); __retval; })) : __strdup ("rejected"))) , conf_off++), SWITCH_XML_NAMEM))) { |
| 1278 | abort(); |
| 1279 | } |
| 1280 | |
| 1281 | for (rp = conference->cdr_rejected; rp; rp = rp->next) { |
| 1282 | int attempt_off = 0; |
| 1283 | int tag_off = 0; |
| 1284 | |
| 1285 | if (!(x_attempt = switch_xml_add_child_d(x_rejected, "attempt", attempt_off++)switch_xml_set_flag(switch_xml_add_child(x_rejected, (__extension__ (__builtin_constant_p ("attempt") && ((size_t)(const void *)(("attempt") + 1) - (size_t)(const void *)("attempt") == 1) ? (((const char *) ("attempt"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("attempt" ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "attempt" , __len); __retval; })) : __strdup ("attempt"))), attempt_off ++), SWITCH_XML_NAMEM))) { |
| 1286 | abort(); |
| 1287 | } |
| 1288 | |
| 1289 | if (!(x_ptr = switch_xml_add_child_d(x_attempt, "reason", tag_off++)switch_xml_set_flag(switch_xml_add_child(x_attempt, (__extension__ (__builtin_constant_p ("reason") && ((size_t)(const void *)(("reason") + 1) - (size_t)(const void *)("reason") == 1) ? (((const char *) ("reason"))[0] == '\0' ? (char *) calloc (( size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("reason") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "reason", __len ); __retval; })) : __strdup ("reason"))), tag_off++), SWITCH_XML_NAMEM ))) { |
| 1290 | abort(); |
| 1291 | } |
| 1292 | if (rp->reason == CDRR_LOCKED) { |
| 1293 | switch_xml_set_txt_d(x_ptr, "conference_locked")switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p ("conference_locked") && ((size_t )(const void *)(("conference_locked") + 1) - (size_t)(const void *)("conference_locked") == 1) ? (((const char *) ("conference_locked" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("conference_locked") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "conference_locked", __len); __retval ; })) : __strdup ("conference_locked")))), SWITCH_XML_TXTM); |
| 1294 | } else if (rp->reason == CDRR_MAXMEMBERS) { |
| 1295 | switch_xml_set_txt_d(x_ptr, "max_members_reached")switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p ("max_members_reached") && ((size_t )(const void *)(("max_members_reached") + 1) - (size_t)(const void *)("max_members_reached") == 1) ? (((const char *) ("max_members_reached" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("max_members_reached") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "max_members_reached", __len); __retval ; })) : __strdup ("max_members_reached")))), SWITCH_XML_TXTM); |
| 1296 | } else if (rp->reason == CDRR_PIN) { |
| 1297 | switch_xml_set_txt_d(x_ptr, "invalid_pin")switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p ("invalid_pin") && ((size_t)(const void *)(("invalid_pin") + 1) - (size_t)(const void *)("invalid_pin" ) == 1) ? (((const char *) ("invalid_pin"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("invalid_pin") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "invalid_pin", __len); __retval; })) : __strdup ("invalid_pin" )))), SWITCH_XML_TXTM); |
| 1298 | } |
| 1299 | |
| 1300 | if (!(x_ptr = switch_xml_add_child_d(x_attempt, "reject_time", tag_off++)switch_xml_set_flag(switch_xml_add_child(x_attempt, (__extension__ (__builtin_constant_p ("reject_time") && ((size_t)(const void *)(("reject_time") + 1) - (size_t)(const void *)("reject_time" ) == 1) ? (((const char *) ("reject_time"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("reject_time") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "reject_time", __len); __retval; })) : __strdup ("reject_time" ))), tag_off++), SWITCH_XML_NAMEM))) { |
| 1301 | abort(); |
| 1302 | } |
| 1303 | switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch")switch_xml_set_attr(switch_xml_set_flag(x_ptr, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("type") && ( (size_t)(const void *)(("type") + 1) - (size_t)(const void *) ("type") == 1) ? (((const char *) ("type"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("type") + 1; char *__retval = (char *) malloc (__len); if ( __retval != ((void*)0)) __retval = (char *) memcpy (__retval, "type", __len); __retval; })) : __strdup ("type"))), (__extension__ (__builtin_constant_p (("UNIX-epoch" ? "UNIX-epoch" : "")) && ((size_t)(const void *)((("UNIX-epoch" ? "UNIX-epoch" : "")) + 1) - (size_t)(const void *)(("UNIX-epoch" ? "UNIX-epoch" : "")) == 1) ? (((const char *) (("UNIX-epoch" ? "UNIX-epoch" : "")))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (("UNIX-epoch" ? "UNIX-epoch" : "") ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, ("UNIX-epoch" ? "UNIX-epoch" : ""), __len); __retval; })) : __strdup (("UNIX-epoch" ? "UNIX-epoch" : ""))))); |
| 1304 | switch_snprintf(str, sizeof(str), "%ld", (long) rp->reject_time); |
| 1305 | switch_xml_set_txt_d(x_ptr, str)switch_xml_set_flag(switch_xml_set_txt(x_ptr, (__extension__ ( __builtin_constant_p (str) && ((size_t)(const void *) ((str) + 1) - (size_t)(const void *)(str) == 1) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, str, __len); __retval; })) : __strdup ( str)))), SWITCH_XML_TXTM); |
| 1306 | |
| 1307 | if (rp->cp) { |
| 1308 | if (!(x_cp = switch_xml_add_child_d(x_attempt, "caller_profile", attempt_off++)switch_xml_set_flag(switch_xml_add_child(x_attempt, (__extension__ (__builtin_constant_p ("caller_profile") && ((size_t )(const void *)(("caller_profile") + 1) - (size_t)(const void *)("caller_profile") == 1) ? (((const char *) ("caller_profile" ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("caller_profile") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, "caller_profile", __len); __retval ; })) : __strdup ("caller_profile"))), attempt_off++), SWITCH_XML_NAMEM ))) { |
| 1309 | abort(); |
| 1310 | } |
| 1311 | switch_ivr_set_xml_profile_data(x_cp, rp->cp, 0); |
| 1312 | } |
| 1313 | } |
| 1314 | |
| 1315 | xml_text = switch_xml_toxml(cdr, SWITCH_TRUE); |
| 1316 | |
| 1317 | |
| 1318 | if (!zstr(conference->log_dir)_zstr(conference->log_dir)) { |
| 1319 | path = switch_mprintf("%s%s%s.cdr.xml", conference->log_dir, SWITCH_PATH_SEPARATOR"/", conference->uuid_str); |
| 1320 | |
| 1321 | |
| 1322 | |
| 1323 | #ifdef _MSC_VER |
| 1324 | if ((fd = open(path, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, S_IRUSR0400 | S_IWUSR0200)) > -1) { |
| 1325 | #else |
| 1326 | if ((fd = open(path, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, S_IRUSR0400 | S_IWUSR0200 | S_IRGRP(0400 >> 3) | S_IWGRP(0200 >> 3) | S_IROTH((0400 >> 3) >> 3) | S_IWOTH((0200 >> 3) >> 3))) > -1) { |
| 1327 | #endif |
| 1328 | int wrote; |
| 1329 | wrote = write(fd, xml_text, (unsigned) strlen(xml_text)); |
| 1330 | wrote++; |
| 1331 | close(fd); |
| 1332 | fd = -1; |
| 1333 | } else { |
| 1334 | char ebuf[512] = { 0 }; |
| 1335 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 1335, ((void*)0), SWITCH_LOG_ERROR, "Error writing [%s][%s]\n", |
| 1336 | path, switch_strerror_r(errno(*__errno_location ()), ebuf, sizeof(ebuf))); |
| 1337 | } |
| 1338 | |
| 1339 | if (conference->cdr_event_mode != CDRE_NONE) { |
| 1340 | switch_event_t *event; |
| 1341 | |
| 1342 | if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_CDR)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 1342, &event, SWITCH_EVENT_CUSTOM , "conference::cdr") == SWITCH_STATUS_SUCCESS) |
| 1343 | // if (switch_event_create(&event, SWITCH_EVENT_CDR) == SWITCH_STATUS_SUCCESS) |
| 1344 | { |
| 1345 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Source", CONF_EVENT_CDR"conference::cdr"); |
| 1346 | if (conference->cdr_event_mode == CDRE_AS_CONTENT) { |
| 1347 | switch_event_set_body(event, xml_text); |
| 1348 | } else { |
| 1349 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Path", path); |
| 1350 | } |
| 1351 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 1351, &event, ((void*)0)); |
| 1352 | } else { |
| 1353 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 1353, ((void*)0), SWITCH_LOG_ERROR, "Could not create CDR event"); |
| 1354 | } |
| 1355 | } |
| 1356 | } |
| 1357 | |
| 1358 | switch_safe_free(path)if (path) {free(path);path=((void*)0);}; |
| 1359 | switch_safe_free(xml_text)if (xml_text) {free(xml_text);xml_text=((void*)0);}; |
| 1360 | switch_xml_free(cdr); |
| 1361 | } |
| 1362 | |
| 1363 | static cJSON *conference_json_render(conference_obj_t *conference, cJSON *req) |
| 1364 | { |
| 1365 | char tmp[30]; |
| 1366 | const char *domain; const char *name; |
| 1367 | char *dup_domain = NULL((void*)0); |
| 1368 | char *uri; |
| 1369 | conference_cdr_node_t *np; |
| 1370 | char *tmpp = tmp; |
| 1371 | cJSON *json = cJSON_CreateObject(), *jusers = NULL((void*)0), *jold_users = NULL((void*)0), *juser = NULL((void*)0), *jvars = NULL((void*)0); |
| 1372 | |
| 1373 | switch_assert(json)((json) ? (void) (0) : __assert_fail ("json", "mod_conference.c" , 1373, __PRETTY_FUNCTION__)); |
| 1374 | |
| 1375 | switch_mutex_lock(conference->mutex); |
| 1376 | switch_snprintf(tmp, sizeof(tmp), "%u", conference->doc_version); |
| 1377 | conference->doc_version++; |
| 1378 | switch_mutex_unlock(conference->mutex); |
| 1379 | |
| 1380 | if (!(name = conference->name)) { |
| 1381 | name = "conference"; |
| 1382 | } |
| 1383 | |
| 1384 | if (!(domain = conference->domain)) { |
| 1385 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
| 1386 | if (!(domain = dup_domain)) { |
| 1387 | domain = "cluecon.com"; |
| 1388 | } |
| 1389 | } |
| 1390 | |
| 1391 | |
| 1392 | uri = switch_mprintf("%s@%s", name, domain); |
| 1393 | json_add_child_string(json, "entity", uri); |
| 1394 | json_add_child_string(json, "conferenceDescription", conference->desc ? conference->desc : "FreeSWITCH Conference"); |
| 1395 | json_add_child_string(json, "conferenceState", "active"); |
| 1396 | switch_snprintf(tmp, sizeof(tmp), "%u", conference->count); |
| 1397 | json_add_child_string(json, "userCount", tmp); |
| 1398 | |
| 1399 | jusers = json_add_child_array(json, "users"); |
| 1400 | jold_users = json_add_child_array(json, "oldUsers"); |
| 1401 | |
| 1402 | switch_mutex_lock(conference->member_mutex); |
| 1403 | |
| 1404 | for (np = conference->cdr_nodes; np; np = np->next) { |
| 1405 | char *user_uri = NULL((void*)0); |
| 1406 | switch_channel_t *channel = NULL((void*)0); |
| 1407 | switch_time_exp_t tm; |
| 1408 | switch_size_t retsize; |
| 1409 | const char *fmt = "%Y-%m-%dT%H:%M:%S%z"; |
| 1410 | char *p; |
| 1411 | |
| 1412 | if (np->record_path || !np->cp) { |
| 1413 | continue; |
| 1414 | } |
| 1415 | |
| 1416 | //if (!np->cp || (np->member && !np->member->session) || np->leave_time) { /* for now we'll remove participants when they leave */ |
| 1417 | //continue; |
| 1418 | //} |
| 1419 | |
| 1420 | if (np->member && np->member->session) { |
| 1421 | channel = switch_core_session_get_channel(np->member->session); |
| 1422 | } |
| 1423 | |
| 1424 | juser = cJSON_CreateObject(); |
| 1425 | |
| 1426 | if (channel) { |
| 1427 | const char *uri = switch_channel_get_variable_dup(channel, "conference_invite_uri", SWITCH_FALSE, -1); |
| 1428 | |
| 1429 | if (uri) { |
| 1430 | user_uri = strdup(uri)(__extension__ (__builtin_constant_p (uri) && ((size_t )(const void *)((uri) + 1) - (size_t)(const void *)(uri) == 1 ) ? (((const char *) (uri))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (uri) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, uri, __len); __retval ; })) : __strdup (uri))); |
| 1431 | } |
| 1432 | } |
| 1433 | |
| 1434 | if (np->cp) { |
| 1435 | |
| 1436 | if (!user_uri) { |
| 1437 | user_uri = switch_mprintf("%s@%s", np->cp->caller_id_number, domain); |
| 1438 | } |
| 1439 | |
| 1440 | json_add_child_string(juser, "entity", user_uri); |
| 1441 | json_add_child_string(juser, "displayText", np->cp->caller_id_name); |
| 1442 | } |
| 1443 | |
| 1444 | //if (np->record_path) { |
| 1445 | //json_add_child_string(juser, "recordingPATH", np->record_path); |
| 1446 | //} |
| 1447 | |
| 1448 | json_add_child_string(juser, "status", np->leave_time ? "disconnected" : "connected"); |
| 1449 | |
| 1450 | switch_time_exp_lt(&tm, (switch_time_t) conference->start_time * 1000000); |
| 1451 | switch_strftime_nocheck(tmp, &retsize, sizeof(tmp), fmt, &tm); |
| 1452 | p = end_of_p(tmpp)(*tmpp == '\0' ? tmpp : tmpp + strlen(tmpp) - 1) -1; |
| 1453 | snprintf(p, 4, ":00"); |
| 1454 | |
| 1455 | json_add_child_string(juser, "joinTime", tmpp); |
| 1456 | |
| 1457 | snprintf(tmp, sizeof(tmp), "%u", np->id); |
| 1458 | json_add_child_string(juser, "memberId", tmp); |
| 1459 | |
| 1460 | jvars = cJSON_CreateObject(); |
| 1461 | |
| 1462 | if (!np->member && np->var_event) { |
| 1463 | switch_json_add_presence_data_cols(np->var_event, jvars, "PD-"); |
| 1464 | } else if (np->member) { |
| 1465 | const char *var; |
| 1466 | const char *prefix = NULL((void*)0); |
| 1467 | switch_event_t *var_event = NULL((void*)0); |
| 1468 | switch_event_header_t *hp; |
| 1469 | int all = 0; |
| 1470 | |
| 1471 | switch_channel_get_variables(channel, &var_event); |
| 1472 | |
| 1473 | if ((prefix = switch_event_get_header(var_event, "json_conf_var_prefix")switch_event_get_header_idx(var_event, "json_conf_var_prefix" , -1))) { |
| 1474 | all = strcasecmp(prefix, "__all__"); |
| 1475 | } else { |
| 1476 | prefix = "json_"; |
| 1477 | } |
| 1478 | |
| 1479 | for(hp = var_event->headers; hp; hp = hp->next) { |
| 1480 | if (all || !strncasecmp(hp->name, prefix, strlen(prefix))) { |
| 1481 | json_add_child_string(jvars, hp->name, hp->value); |
| 1482 | } |
| 1483 | } |
| 1484 | |
| 1485 | switch_json_add_presence_data_cols(var_event, jvars, "PD-"); |
| 1486 | |
| 1487 | switch_event_destroy(&var_event); |
| 1488 | |
| 1489 | if ((var = switch_channel_get_variable(channel, "rtp_use_ssrc")switch_channel_get_variable_dup(channel, "rtp_use_ssrc", SWITCH_TRUE , -1))) { |
| 1490 | json_add_child_string(juser, "rtpAudioSSRC", var); |
| 1491 | } |
| 1492 | |
| 1493 | json_add_child_string(juser, "rtpAudioDirection", audio_flow(np->member)); |
| 1494 | |
| 1495 | |
| 1496 | if (switch_channel_test_flag(channel, CF_VIDEO)) { |
| 1497 | if ((var = switch_channel_get_variable(channel, "rtp_use_video_ssrc")switch_channel_get_variable_dup(channel, "rtp_use_video_ssrc" , SWITCH_TRUE, -1))) { |
| 1498 | json_add_child_string(juser, "rtpVideoSSRC", var); |
| 1499 | } |
| 1500 | |
| 1501 | json_add_child_string(juser, "rtpVideoDirection", switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv"); |
| 1502 | } |
| 1503 | } |
| 1504 | |
| 1505 | if (jvars) { |
| 1506 | json_add_child_obj(juser, "variables", jvars); |
| 1507 | } |
| 1508 | |
| 1509 | cJSON_AddItemToArray(np->leave_time ? jold_users : jusers, juser); |
| 1510 | |
| 1511 | switch_safe_free(user_uri)if (user_uri) {free(user_uri);user_uri=((void*)0);}; |
| 1512 | } |
| 1513 | |
| 1514 | switch_mutex_unlock(conference->member_mutex); |
| 1515 | |
| 1516 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
| 1517 | switch_safe_free(uri)if (uri) {free(uri);uri=((void*)0);}; |
| 1518 | |
| 1519 | return json; |
| 1520 | } |
| 1521 | |
| 1522 | static void conference_mod_event_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id) |
| 1523 | { |
| 1524 | cJSON *data; |
| 1525 | const char *action = NULL((void*)0); |
| 1526 | char *value = NULL((void*)0); |
| 1527 | cJSON *jid = 0; |
| 1528 | char *conf_name = strdup(event_channel + 15)(__extension__ (__builtin_constant_p (event_channel + 15) && ((size_t)(const void *)((event_channel + 15) + 1) - (size_t) (const void *)(event_channel + 15) == 1) ? (((const char *) ( event_channel + 15))[0] == '\0' ? (char *) calloc ((size_t) 1 , (size_t) 1) : ({ size_t __len = strlen (event_channel + 15) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, event_channel + 15, __len); __retval; })) : __strdup (event_channel + 15)) ); |
| 1529 | int cid = 0; |
| 1530 | char *p; |
| 1531 | switch_stream_handle_t stream = { 0 }; |
| 1532 | char *exec = NULL((void*)0); |
| 1533 | cJSON *msg, *jdata, *jvalue; |
| 1534 | char *argv[10] = {0}; |
| 1535 | int argc = 0; |
| 1536 | |
| 1537 | if (conf_name && (p = strchr(conf_name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conf_name) && ('@') == '\0' ? (char *) __rawmemchr ( conf_name, '@') : __builtin_strchr (conf_name, '@'))))) { |
| 1538 | *p = '\0'; |
| 1539 | } |
| 1540 | |
| 1541 | if ((data = cJSON_GetObjectItem(json, "data"))) { |
| 1542 | action = cJSON_GetObjectCstr(data, "command"); |
| 1543 | if ((jid = cJSON_GetObjectItem(data, "id"))) { |
| 1544 | cid = jid->valueint; |
| 1545 | } |
| 1546 | |
| 1547 | if ((jvalue = cJSON_GetObjectItem(data, "value"))) { |
| 1548 | |
| 1549 | if (jvalue->type == cJSON_Array5) { |
| 1550 | int i; |
| 1551 | argc = cJSON_GetArraySize(jvalue); |
| 1552 | if (argc > 10) argc = 10; |
| 1553 | |
| 1554 | for (i = 0; i < argc; i++) { |
| 1555 | cJSON *str = cJSON_GetArrayItem(jvalue, i); |
| 1556 | if (str->type == cJSON_String4) { |
| 1557 | argv[i] = str->valuestring; |
| 1558 | } |
| 1559 | } |
| 1560 | } else if (jvalue->type == cJSON_String4) { |
| 1561 | value = jvalue->valuestring; |
| 1562 | argv[argc++] = value; |
| 1563 | } |
| 1564 | } |
| 1565 | } |
| 1566 | |
| 1567 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 1567, ((void*)0), SWITCH_LOG_ALERT, "conf %s CMD %s [%s] %d\n", conf_name, key, action, cid); |
| 1568 | |
| 1569 | if (zstr(action)_zstr(action)) { |
| 1570 | goto end; |
| 1571 | } |
| 1572 | |
| 1573 | SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc( 1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data" , "mod_conference.c", 1573, __PRETTY_FUNCTION__)); memset(stream .data, 0, 1024); stream.end = stream.data; stream.data_size = 1024; stream.write_function = switch_console_stream_write; stream .raw_write_function = switch_console_stream_raw_write; stream .alloc_len = 1024; stream.alloc_chunk = 1024; |
| 1574 | |
| 1575 | if (!strcasecmp(action, "kick") || !strcasecmp(action, "mute") || !strcasecmp(action, "unmute") || !strcasecmp(action, "tmute")) { |
| 1576 | exec = switch_mprintf("%s %s %d", conf_name, action, cid); |
| 1577 | } else if (!strcasecmp(action, "volume_in") || !strcasecmp(action, "volume_out")) { |
| 1578 | exec = switch_mprintf("%s %s %d %s", conf_name, action, cid, argv[0]); |
| 1579 | } else if (!strcasecmp(action, "play") || !strcasecmp(action, "stop")) { |
| 1580 | exec = switch_mprintf("%s %s %s", conf_name, action, argv[0]); |
| 1581 | } else if (!strcasecmp(action, "recording")) { |
| 1582 | if (!argv[1]) { |
| 1583 | argv[1] = "all"; |
| 1584 | } |
| 1585 | exec = switch_mprintf("%s %s %s %s", conf_name, action, argv[0], argv[1]); |
| 1586 | |
| 1587 | } else if (!strcasecmp(action, "transfer") && cid) { |
| 1588 | conference_member_t *member; |
| 1589 | conference_obj_t *conference; |
| 1590 | |
| 1591 | exec = switch_mprintf("%s %s %s", argv[0], switch_str_nil(argv[1])(argv[1] ? argv[1] : ""), switch_str_nil(argv[2])(argv[2] ? argv[2] : "")); |
| 1592 | stream.write_function(&stream, "+OK Call transferred to %s", argv[0]); |
| 1593 | |
| 1594 | if ((conference = conference_find(conf_name, NULL((void*)0)))) { |
| 1595 | if ((member = conference_member_get(conference, cid))) { |
| 1596 | switch_ivr_session_transfer(member->session, argv[0], argv[1], argv[2]); |
| 1597 | switch_thread_rwlock_unlock(member->rwlock); |
| 1598 | } |
| 1599 | switch_thread_rwlock_unlock(conference->rwlock); |
| 1600 | } |
| 1601 | goto end; |
| 1602 | } |
| 1603 | |
| 1604 | if (exec) { |
| 1605 | conf_api_main(exec, NULL((void*)0), &stream); |
| 1606 | } |
| 1607 | |
| 1608 | end: |
| 1609 | |
| 1610 | msg = cJSON_CreateObject(); |
| 1611 | jdata = json_add_child_obj(msg, "data", NULL((void*)0)); |
| 1612 | |
| 1613 | cJSON_AddItemToObject(msg, "eventChannel", cJSON_CreateString(event_channel)); |
| 1614 | cJSON_AddItemToObject(jdata, "action", cJSON_CreateString("response")); |
| 1615 | |
| 1616 | if (exec) { |
| 1617 | cJSON_AddItemToObject(jdata, "conf-command", cJSON_CreateString(exec)); |
| 1618 | cJSON_AddItemToObject(jdata, "response", cJSON_CreateString((char *)stream.data)); |
| 1619 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 1619, ((void*)0), SWITCH_LOG_ALERT,"RES [%s][%s]\n", exec, (char *)stream.data); |
| 1620 | } else { |
| 1621 | cJSON_AddItemToObject(jdata, "error", cJSON_CreateString("Invalid Command")); |
| 1622 | } |
| 1623 | |
| 1624 | switch_event_channel_broadcast(event_channel, &msg, __FILE__"mod_conference.c", globals.event_channel_id); |
| 1625 | |
| 1626 | |
| 1627 | switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);}; |
| 1628 | switch_safe_free(exec)if (exec) {free(exec);exec=((void*)0);}; |
| 1629 | |
| 1630 | switch_safe_free(conf_name)if (conf_name) {free(conf_name);conf_name=((void*)0);}; |
| 1631 | |
| 1632 | } |
| 1633 | |
| 1634 | static void conference_la_event_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id) |
| 1635 | { |
| 1636 | switch_live_array_parse_json(json, globals.event_channel_id); |
| 1637 | } |
| 1638 | |
| 1639 | static void conference_event_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id) |
| 1640 | { |
| 1641 | char *domain = NULL((void*)0), *name = NULL((void*)0); |
| 1642 | conference_obj_t *conference = NULL((void*)0); |
| 1643 | cJSON *data, *reply = NULL((void*)0), *conf_desc = NULL((void*)0); |
| 1644 | const char *action = NULL((void*)0); |
| 1645 | char *dup = NULL((void*)0); |
| 1646 | |
| 1647 | if ((data = cJSON_GetObjectItem(json, "data"))) { |
| 1648 | action = cJSON_GetObjectCstr(data, "action"); |
| 1649 | } |
| 1650 | |
| 1651 | if (!action) action = ""; |
| 1652 | |
| 1653 | reply = cJSON_Duplicate(json, 1); |
| 1654 | cJSON_DeleteItemFromObject(reply, "data"); |
| 1655 | |
| 1656 | if ((name = strchr(event_channel, '.')(__extension__ (__builtin_constant_p ('.') && !__builtin_constant_p (event_channel) && ('.') == '\0' ? (char *) __rawmemchr (event_channel, '.') : __builtin_strchr (event_channel, '.') )))) { |
| 1657 | dup = strdup(name + 1)(__extension__ (__builtin_constant_p (name + 1) && (( size_t)(const void *)((name + 1) + 1) - (size_t)(const void * )(name + 1) == 1) ? (((const char *) (name + 1))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (name + 1) + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , name + 1, __len); __retval; })) : __strdup (name + 1))); |
| 1658 | switch_assert(dup)((dup) ? (void) (0) : __assert_fail ("dup", "mod_conference.c" , 1658, __PRETTY_FUNCTION__)); |
| 1659 | name = dup; |
| 1660 | |
| 1661 | if ((domain = strchr(name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (name) && ('@') == '\0' ? (char *) __rawmemchr (name , '@') : __builtin_strchr (name, '@'))))) { |
| 1662 | *domain++ = '\0'; |
| 1663 | } |
| 1664 | } |
| 1665 | |
| 1666 | if (!strcasecmp(action, "bootstrap")) { |
| 1667 | if (!zstr(name)_zstr(name) && (conference = conference_find(name, domain))) { |
| 1668 | conf_desc = conference_json_render(conference, json); |
| 1669 | } else { |
| 1670 | conf_desc = cJSON_CreateObject(); |
| 1671 | json_add_child_string(conf_desc, "conferenceDescription", "FreeSWITCH Conference"); |
| 1672 | json_add_child_string(conf_desc, "conferenceState", "inactive"); |
| 1673 | json_add_child_array(conf_desc, "users"); |
| 1674 | json_add_child_array(conf_desc, "oldUsers"); |
| 1675 | } |
| 1676 | } else { |
| 1677 | conf_desc = cJSON_CreateObject(); |
| 1678 | json_add_child_string(conf_desc, "error", "Invalid action"); |
| 1679 | } |
| 1680 | |
| 1681 | json_add_child_string(conf_desc, "action", "conferenceDescription"); |
| 1682 | |
| 1683 | cJSON_AddItemToObject(reply, "data", conf_desc); |
| 1684 | |
| 1685 | switch_safe_free(dup)if (dup) {free(dup);dup=((void*)0);}; |
| 1686 | |
| 1687 | switch_event_channel_broadcast(event_channel, &reply, modname, globals.event_channel_id); |
| 1688 | } |
| 1689 | |
| 1690 | |
| 1691 | static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event) |
| 1692 | { |
| 1693 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
| 1694 | |
| 1695 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Name", conference->name); |
| 1696 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Size", "%u", conference->count); |
| 1697 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Ghosts", "%u", conference->count_ghosts); |
| 1698 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Profile-Name", conference->profile_name); |
| 1699 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Unique-ID", conference->uuid_str); |
| 1700 | |
| 1701 | return status; |
| 1702 | } |
| 1703 | |
| 1704 | static switch_status_t conference_add_event_member_data(conference_member_t *member, switch_event_t *event) |
| 1705 | { |
| 1706 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
| 1707 | |
| 1708 | if (!member) |
| 1709 | return status; |
| 1710 | |
| 1711 | if (member->conference) { |
| 1712 | status = conference_add_event_data(member->conference, event); |
| 1713 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Floor", "%s", (member == member->conference->floor_holder) ? "true" : "false" ); |
| 1714 | } |
| 1715 | |
| 1716 | if (member->session) { |
| 1717 | switch_channel_t *channel = switch_core_session_get_channel(member->session); |
| 1718 | |
| 1719 | if (member->verbose_events) { |
| 1720 | switch_channel_event_set_data(channel, event); |
| 1721 | } else { |
| 1722 | switch_channel_event_set_basic_data(channel, event); |
| 1723 | } |
| 1724 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Video", "%s", |
| 1725 | switch_channel_test_flag(switch_core_session_get_channel(member->session), CF_VIDEO) ? "true" : "false" ); |
| 1726 | |
| 1727 | } |
| 1728 | |
| 1729 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Hear", "%s", switch_test_flag(member, MFLAG_CAN_HEAR)((member)->flags & MFLAG_CAN_HEAR) ? "true" : "false" ); |
| 1730 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Speak", "%s", switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK) ? "true" : "false" ); |
| 1731 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Talking", "%s", switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING) ? "true" : "false" ); |
| 1732 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Mute-Detect", "%s", switch_test_flag(member, MFLAG_MUTE_DETECT)((member)->flags & MFLAG_MUTE_DETECT) ? "true" : "false" ); |
| 1733 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id); |
| 1734 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Type", "%s", switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD) ? "moderator" : "member"); |
| 1735 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Ghost", "%s", switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST) ? "true" : "false"); |
| 1736 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Energy-Level", "%d", member->energy_level); |
| 1737 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Current-Energy", "%d", member->score); |
| 1738 | |
| 1739 | return status; |
| 1740 | } |
| 1741 | |
| 1742 | /* Return a Distinct ID # */ |
| 1743 | static uint32_t next_member_id(void) |
| 1744 | { |
| 1745 | uint32_t id; |
| 1746 | |
| 1747 | switch_mutex_lock(globals.id_mutex); |
| 1748 | id = ++globals.id_pool; |
| 1749 | switch_mutex_unlock(globals.id_mutex); |
| 1750 | |
| 1751 | return id; |
| 1752 | } |
| 1753 | |
| 1754 | /* if other_member has a relationship with member, produce it */ |
| 1755 | static conference_relationship_t *member_get_relationship(conference_member_t *member, conference_member_t *other_member) |
| 1756 | { |
| 1757 | conference_relationship_t *rel = NULL((void*)0), *global = NULL((void*)0); |
| 1758 | |
| 1759 | if (member == NULL((void*)0) || other_member == NULL((void*)0) || member->relationships == NULL((void*)0)) |
| 1760 | return NULL((void*)0); |
| 1761 | |
| 1762 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
| 1763 | lock_member(other_member)switch_mutex_lock(other_member->write_mutex); switch_mutex_lock (other_member->read_mutex); |
| 1764 | |
| 1765 | for (rel = member->relationships; rel; rel = rel->next) { |
| 1766 | if (rel->id == other_member->id) { |
| 1767 | break; |
| 1768 | } |
| 1769 | |
| 1770 | /* 0 matches everyone. (We will still test the others because a real match carries more clout) */ |
| 1771 | if (rel->id == 0) { |
| 1772 | global = rel; |
| 1773 | } |
| 1774 | } |
| 1775 | |
| 1776 | unlock_member(other_member)switch_mutex_unlock(other_member->read_mutex); switch_mutex_unlock (other_member->write_mutex); |
| 1777 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
| 1778 | |
| 1779 | return rel ? rel : global; |
| 1780 | } |
| 1781 | |
| 1782 | /* traverse the conference member list for the specified member id and return it's pointer */ |
| 1783 | static conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id) |
| 1784 | { |
| 1785 | conference_member_t *member = NULL((void*)0); |
| 1786 | |
| 1787 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 1787, __PRETTY_FUNCTION__)); |
| 1788 | if (!id) { |
| 1789 | return NULL((void*)0); |
| 1790 | } |
| 1791 | |
| 1792 | switch_mutex_lock(conference->member_mutex); |
| 1793 | for (member = conference->members; member; member = member->next) { |
| 1794 | |
| 1795 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
| 1796 | continue; |
| 1797 | } |
| 1798 | |
| 1799 | if (member->id == id) { |
| 1800 | break; |
| 1801 | } |
| 1802 | } |
| 1803 | |
| 1804 | if (member) { |
| 1805 | if (!switch_test_flag(member, MFLAG_INTREE)((member)->flags & MFLAG_INTREE) || |
| 1806 | switch_test_flag(member, MFLAG_KICKED)((member)->flags & MFLAG_KICKED) || |
| 1807 | (member->session && !switch_channel_up(switch_core_session_get_channel(member->session))(switch_channel_check_signal(switch_core_session_get_channel( member->session), SWITCH_TRUE) || switch_channel_get_state (switch_core_session_get_channel(member->session)) < CS_HANGUP ))) { |
| 1808 | |
| 1809 | /* member is kicked or hanging up so forget it */ |
| 1810 | member = NULL((void*)0); |
| 1811 | } |
| 1812 | } |
| 1813 | |
| 1814 | if (member) { |
| 1815 | if (switch_thread_rwlock_tryrdlock(member->rwlock) != SWITCH_STATUS_SUCCESS) { |
| 1816 | /* if you cant readlock it's way to late to do anything */ |
| 1817 | member = NULL((void*)0); |
| 1818 | } |
| 1819 | } |
| 1820 | |
| 1821 | switch_mutex_unlock(conference->member_mutex); |
| 1822 | |
| 1823 | return member; |
| 1824 | } |
| 1825 | |
| 1826 | /* stop the specified recording */ |
| 1827 | static switch_status_t conference_record_stop(conference_obj_t *conference, switch_stream_handle_t *stream, char *path) |
| 1828 | { |
| 1829 | conference_member_t *member = NULL((void*)0); |
| 1830 | int count = 0; |
| 1831 | |
| 1832 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 1832, __PRETTY_FUNCTION__)); |
| 1833 | switch_mutex_lock(conference->member_mutex); |
| 1834 | for (member = conference->members; member; member = member->next) { |
| 1835 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (path) && __builtin_constant_p (member->rec_path) && (__s1_len = __builtin_strlen (path), __s2_len = __builtin_strlen (member->rec_path), (!((size_t)(const void *)((path) + 1) - (size_t)(const void *)(path) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((member->rec_path) + 1) - (size_t )(const void *)(member->rec_path) == 1) || __s2_len >= 4 )) ? __builtin_strcmp (path, member->rec_path) : (__builtin_constant_p (path) && ((size_t)(const void *)((path) + 1) - (size_t )(const void *)(path) == 1) && (__s1_len = __builtin_strlen (path), __s1_len < 4) ? (__builtin_constant_p (member-> rec_path) && ((size_t)(const void *)((member->rec_path ) + 1) - (size_t)(const void *)(member->rec_path) == 1) ? __builtin_strcmp (path, member->rec_path) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (member-> rec_path); int __result = (((const unsigned char *) (const char *) (path))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( path))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( path))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (path ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( member->rec_path) && ((size_t)(const void *)((member ->rec_path) + 1) - (size_t)(const void *)(member->rec_path ) == 1) && (__s2_len = __builtin_strlen (member->rec_path ), __s2_len < 4) ? (__builtin_constant_p (path) && ((size_t)(const void *)((path) + 1) - (size_t)(const void *) (path) == 1) ? __builtin_strcmp (path, member->rec_path) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (path); int __result = (((const unsigned char *) (const char *) (member->rec_path))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = ( ((const unsigned char *) (const char *) (member->rec_path) )[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (member ->rec_path))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (member->rec_path))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (path, member->rec_path)))); }))) { |
| 1836 | if (!switch_test_flag(conference, CFLAG_CONF_RESTART_AUTO_RECORD)((conference)->flags & CFLAG_CONF_RESTART_AUTO_RECORD) && member->rec && member->rec->autorec) { |
| 1837 | stream->write_function(stream, "Stopped AUTO recording file %s (Auto Recording Now Disabled)\n", member->rec_path); |
| 1838 | conference->auto_record = 0; |
| 1839 | } else { |
| 1840 | stream->write_function(stream, "Stopped recording file %s\n", member->rec_path); |
| 1841 | } |
| 1842 | |
| 1843 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
| 1844 | count++; |
| 1845 | |
| 1846 | } |
| 1847 | } |
| 1848 | |
| 1849 | conference->record_count -= count; |
| 1850 | |
| 1851 | switch_mutex_unlock(conference->member_mutex); |
| 1852 | return count; |
| 1853 | } |
| 1854 | /* stop/pause/resume the specified recording */ |
| 1855 | static switch_status_t conference_record_action(conference_obj_t *conference, char *path, recording_action_type_t action) |
| 1856 | { |
| 1857 | conference_member_t *member = NULL((void*)0); |
| 1858 | int count = 0; |
| 1859 | //switch_file_handle_t *fh = NULL; |
| 1860 | |
| 1861 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 1861, __PRETTY_FUNCTION__)); |
| 1862 | switch_mutex_lock(conference->member_mutex); |
| 1863 | for (member = conference->members; member; member = member->next) |
| 1864 | { |
| 1865 | if (switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (path) && __builtin_constant_p (member->rec_path) && (__s1_len = __builtin_strlen (path), __s2_len = __builtin_strlen (member->rec_path), (!((size_t)(const void *)((path) + 1) - (size_t)(const void *)(path) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((member->rec_path) + 1) - (size_t )(const void *)(member->rec_path) == 1) || __s2_len >= 4 )) ? __builtin_strcmp (path, member->rec_path) : (__builtin_constant_p (path) && ((size_t)(const void *)((path) + 1) - (size_t )(const void *)(path) == 1) && (__s1_len = __builtin_strlen (path), __s1_len < 4) ? (__builtin_constant_p (member-> rec_path) && ((size_t)(const void *)((member->rec_path ) + 1) - (size_t)(const void *)(member->rec_path) == 1) ? __builtin_strcmp (path, member->rec_path) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (member-> rec_path); int __result = (((const unsigned char *) (const char *) (path))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( path))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( path))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (path ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( member->rec_path) && ((size_t)(const void *)((member ->rec_path) + 1) - (size_t)(const void *)(member->rec_path ) == 1) && (__s2_len = __builtin_strlen (member->rec_path ), __s2_len < 4) ? (__builtin_constant_p (path) && ((size_t)(const void *)((path) + 1) - (size_t)(const void *) (path) == 1) ? __builtin_strcmp (path, member->rec_path) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (path); int __result = (((const unsigned char *) (const char *) (member->rec_path))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = ( ((const unsigned char *) (const char *) (member->rec_path) )[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (member ->rec_path))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (member->rec_path))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (path, member->rec_path)))); }))) |
| 1866 | { |
| 1867 | //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Action: %d\n", action); |
| 1868 | switch (action) |
| 1869 | { |
| 1870 | case REC_ACTION_STOP: |
| 1871 | switch_clear_flag_locked(member, MFLAG_RUNNING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_RUNNING); switch_mutex_unlock(member->flag_mutex) ;; |
| 1872 | count++; |
| 1873 | break; |
| 1874 | case REC_ACTION_PAUSE: |
| 1875 | switch_set_flag_locked(member, MFLAG_PAUSE_RECORDING)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 1875 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_PAUSE_RECORDING);switch_mutex_unlock (member->flag_mutex);; |
| 1876 | count = 1; |
| 1877 | break; |
| 1878 | case REC_ACTION_RESUME: |
| 1879 | switch_clear_flag_locked(member, MFLAG_PAUSE_RECORDING)switch_mutex_lock(member->flag_mutex); (member)->flags &= ~(MFLAG_PAUSE_RECORDING); switch_mutex_unlock(member->flag_mutex );; |
| 1880 | count = 1; |
| 1881 | break; |
| 1882 | } |
| 1883 | } |
| 1884 | } |
| 1885 | switch_mutex_unlock(conference->member_mutex); |
| 1886 | return count; |
| 1887 | } |
| 1888 | |
| 1889 | |
| 1890 | /* Add a custom relationship to a member */ |
| 1891 | static conference_relationship_t *member_add_relationship(conference_member_t *member, uint32_t id) |
| 1892 | { |
| 1893 | conference_relationship_t *rel = NULL((void*)0); |
| 1894 | |
| 1895 | if (member == NULL((void*)0) || id == 0 || !(rel = switch_core_alloc(member->pool, sizeof(*rel))switch_core_perform_alloc(member->pool, sizeof(*rel), "mod_conference.c" , (const char *)__func__, 1895))) |
| 1896 | return NULL((void*)0); |
| 1897 | |
| 1898 | rel->id = id; |
| 1899 | |
| 1900 | |
| 1901 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
| 1902 | switch_mutex_lock(member->conference->member_mutex); |
| 1903 | member->conference->relationship_total++; |
| 1904 | switch_mutex_unlock(member->conference->member_mutex); |
| 1905 | rel->next = member->relationships; |
| 1906 | member->relationships = rel; |
| 1907 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
| 1908 | |
| 1909 | return rel; |
| 1910 | } |
| 1911 | |
| 1912 | /* Remove a custom relationship from a member */ |
| 1913 | static switch_status_t member_del_relationship(conference_member_t *member, uint32_t id) |
| 1914 | { |
| 1915 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 1916 | conference_relationship_t *rel, *last = NULL((void*)0); |
| 1917 | |
| 1918 | if (member == NULL((void*)0) || id == 0) |
| 1919 | return status; |
| 1920 | |
| 1921 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
| 1922 | for (rel = member->relationships; rel; rel = rel->next) { |
| 1923 | if (rel->id == id) { |
| 1924 | /* we just forget about rel here cos it was allocated by the member's pool |
| 1925 | it will be freed when the member is */ |
| 1926 | status = SWITCH_STATUS_SUCCESS; |
| 1927 | if (last) { |
| 1928 | last->next = rel->next; |
| 1929 | } else { |
| 1930 | member->relationships = rel->next; |
| 1931 | } |
| 1932 | |
| 1933 | switch_mutex_lock(member->conference->member_mutex); |
| 1934 | member->conference->relationship_total--; |
| 1935 | switch_mutex_unlock(member->conference->member_mutex); |
| 1936 | |
| 1937 | } |
| 1938 | last = rel; |
| 1939 | } |
| 1940 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
| 1941 | |
| 1942 | return status; |
| 1943 | } |
| 1944 | |
| 1945 | static void send_json_event(conference_obj_t *conference) |
| 1946 | { |
| 1947 | cJSON *event, *conf_desc = NULL((void*)0); |
| 1948 | char *name = NULL((void*)0), *domain = NULL((void*)0), *dup_domain = NULL((void*)0); |
| 1949 | char *event_channel = NULL((void*)0); |
| 1950 | |
| 1951 | if (!switch_test_flag(conference, CFLAG_JSON_EVENTS)((conference)->flags & CFLAG_JSON_EVENTS)) { |
| 1952 | return; |
| 1953 | } |
| 1954 | |
| 1955 | conf_desc = conference_json_render(conference, NULL((void*)0)); |
| 1956 | |
| 1957 | if (!(name = conference->name)) { |
| 1958 | name = "conference"; |
| 1959 | } |
| 1960 | |
| 1961 | if (!(domain = conference->domain)) { |
| 1962 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
| 1963 | if (!(domain = dup_domain)) { |
| 1964 | domain = "cluecon.com"; |
| 1965 | } |
| 1966 | } |
| 1967 | |
| 1968 | event_channel = switch_mprintf("conference.%q@%q", name, domain); |
| 1969 | |
| 1970 | event = cJSON_CreateObject(); |
| 1971 | |
| 1972 | json_add_child_string(event, "eventChannel", event_channel); |
| 1973 | cJSON_AddItemToObject(event, "data", conf_desc); |
| 1974 | |
| 1975 | switch_event_channel_broadcast(event_channel, &event, modname, globals.event_channel_id); |
| 1976 | |
| 1977 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
| 1978 | switch_safe_free(event_channel)if (event_channel) {free(event_channel);event_channel=((void* )0);}; |
| 1979 | } |
| 1980 | |
| 1981 | static void send_rfc_event(conference_obj_t *conference) |
| 1982 | { |
| 1983 | switch_event_t *event; |
| 1984 | char *body; |
| 1985 | char *name = NULL((void*)0), *domain = NULL((void*)0), *dup_domain = NULL((void*)0); |
| 1986 | |
| 1987 | if (!switch_test_flag(conference, CFLAG_RFC4579)((conference)->flags & CFLAG_RFC4579)) { |
| 1988 | return; |
| 1989 | } |
| 1990 | |
| 1991 | if (!(name = conference->name)) { |
| 1992 | name = "conference"; |
| 1993 | } |
| 1994 | |
| 1995 | if (!(domain = conference->domain)) { |
| 1996 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
| 1997 | if (!(domain = dup_domain)) { |
| 1998 | domain = "cluecon.com"; |
| 1999 | } |
| 2000 | } |
| 2001 | |
| 2002 | |
| 2003 | if (switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2003, &event, SWITCH_EVENT_CONFERENCE_DATA , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
| 2004 | event->flags |= EF_UNIQ_HEADERS; |
| 2005 | |
| 2006 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-name", name); |
| 2007 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-domain", domain); |
| 2008 | |
| 2009 | body = conference_rfc4579_render(conference, NULL((void*)0), event); |
| 2010 | switch_event_add_body(event, "%s", body); |
| 2011 | free(body); |
| 2012 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2012, &event, ((void*)0)); |
| 2013 | } |
| 2014 | |
| 2015 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
| 2016 | |
| 2017 | } |
| 2018 | |
| 2019 | |
| 2020 | |
| 2021 | static void send_conference_notify(conference_obj_t *conference, const char *status, const char *call_id, switch_bool_t final) |
| 2022 | { |
| 2023 | switch_event_t *event; |
| 2024 | char *name = NULL((void*)0), *domain = NULL((void*)0), *dup_domain = NULL((void*)0); |
| 2025 | |
| 2026 | if (!switch_test_flag(conference, CFLAG_RFC4579)((conference)->flags & CFLAG_RFC4579)) { |
| 2027 | return; |
| 2028 | } |
| 2029 | |
| 2030 | if (!(name = conference->name)) { |
| 2031 | name = "conference"; |
| 2032 | } |
| 2033 | |
| 2034 | if (!(domain = conference->domain)) { |
| 2035 | dup_domain = switch_core_get_domain(SWITCH_TRUE); |
| 2036 | if (!(domain = dup_domain)) { |
| 2037 | domain = "cluecon.com"; |
| 2038 | } |
| 2039 | } |
| 2040 | |
| 2041 | |
| 2042 | if (switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2042, &event, SWITCH_EVENT_CONFERENCE_DATA , ((void*)0)) == SWITCH_STATUS_SUCCESS) { |
| 2043 | event->flags |= EF_UNIQ_HEADERS; |
| 2044 | |
| 2045 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-name", name); |
| 2046 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-domain", domain); |
| 2047 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-event", "refer"); |
| 2048 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", call_id); |
| 2049 | |
| 2050 | if (final) { |
| 2051 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "final", "true"); |
| 2052 | } |
| 2053 | |
| 2054 | |
| 2055 | switch_event_add_body(event, "%s", status); |
| 2056 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2056, &event, ((void*)0)); |
| 2057 | } |
| 2058 | |
| 2059 | switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);}; |
| 2060 | |
| 2061 | } |
| 2062 | |
| 2063 | static void member_update_status_field(conference_member_t *member) |
| 2064 | { |
| 2065 | char *str, *vstr = "", display[128] = ""; |
| 2066 | |
| 2067 | if (!member->conference->la || !member->json || !member->status_field) { |
| 2068 | return; |
| 2069 | } |
| 2070 | |
| 2071 | switch_live_array_lock(member->conference->la); |
| 2072 | |
| 2073 | if (!switch_test_flag(member, MFLAG_CAN_SPEAK)((member)->flags & MFLAG_CAN_SPEAK)) { |
| 2074 | str = "MUTE"; |
| 2075 | } else if (switch_channel_test_flag(member->channel, CF_HOLD)) { |
| 2076 | str = "HOLD"; |
| 2077 | } else if (member == member->conference->floor_holder) { |
| 2078 | if (switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING)) { |
| 2079 | str = "TALKING (FLOOR)"; |
| 2080 | } else { |
| 2081 | str = "FLOOR"; |
| 2082 | } |
| 2083 | } else if (switch_test_flag(member, MFLAG_TALKING)((member)->flags & MFLAG_TALKING)) { |
| 2084 | str = "TALKING"; |
| 2085 | } else { |
| 2086 | str = "ACTIVE"; |
| 2087 | } |
| 2088 | |
| 2089 | if (switch_channel_test_flag(member->channel, CF_VIDEO)) { |
| 2090 | vstr = " VIDEO"; |
| 2091 | if (member == member->conference->video_floor_holder) { |
| 2092 | vstr = " VIDEO (FLOOR)"; |
| 2093 | } |
| 2094 | } |
| 2095 | |
| 2096 | switch_snprintf(display, sizeof(display), "%s%s", str, vstr); |
| 2097 | |
| 2098 | |
| 2099 | free(member->status_field->valuestring); |
| 2100 | member->status_field->valuestring = strdup(display)(__extension__ (__builtin_constant_p (display) && ((size_t )(const void *)((display) + 1) - (size_t)(const void *)(display ) == 1) ? (((const char *) (display))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (display ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, display , __len); __retval; })) : __strdup (display))); |
| 2101 | |
| 2102 | switch_live_array_add(member->conference->la, switch_core_session_get_uuid(member->session), -1, &member->json, SWITCH_FALSE); |
| 2103 | switch_live_array_unlock(member->conference->la); |
| 2104 | } |
| 2105 | |
| 2106 | static void adv_la(conference_obj_t *conference, conference_member_t *member, switch_bool_t join) |
| 2107 | { |
| 2108 | if (conference && conference->la && member->session) { |
| 2109 | cJSON *msg, *data; |
| 2110 | const char *uuid = switch_core_session_get_uuid(member->session); |
| 2111 | const char *cookie = switch_channel_get_variable(member->channel, "event_channel_cookie")switch_channel_get_variable_dup(member->channel, "event_channel_cookie" , SWITCH_TRUE, -1); |
| 2112 | const char *event_channel = cookie ? cookie : uuid; |
| 2113 | |
| 2114 | msg = cJSON_CreateObject(); |
| 2115 | data = json_add_child_obj(msg, "pvtData", NULL((void*)0)); |
| 2116 | |
| 2117 | cJSON_AddItemToObject(msg, "eventChannel", cJSON_CreateString(event_channel)); |
| 2118 | cJSON_AddItemToObject(msg, "eventType", cJSON_CreateString("channelPvtData")); |
| 2119 | |
| 2120 | cJSON_AddItemToObject(data, "action", cJSON_CreateString(join ? "conference-liveArray-join" : "conference-liveArray-part")); |
| 2121 | cJSON_AddItemToObject(data, "laChannel", cJSON_CreateString(conference->la_event_channel)); |
| 2122 | cJSON_AddItemToObject(data, "laName", cJSON_CreateString(conference->la_name)); |
| 2123 | cJSON_AddItemToObject(data, "role", cJSON_CreateString(switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD) ? "moderator" : "participant")); |
| 2124 | cJSON_AddItemToObject(data, "chatID", cJSON_CreateString(conference->chat_id)); |
| 2125 | if (switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD)) { |
| 2126 | cJSON_AddItemToObject(data, "modChannel", cJSON_CreateString(conference->mod_event_channel)); |
| 2127 | } |
| 2128 | |
| 2129 | switch_event_channel_broadcast(event_channel, &msg, modname, globals.event_channel_id); |
| 2130 | |
| 2131 | if (cookie) { |
| 2132 | switch_event_channel_permission_modify(cookie, conference->la_event_channel, join); |
| 2133 | switch_event_channel_permission_modify(cookie, conference->mod_event_channel, join); |
| 2134 | } |
| 2135 | } |
| 2136 | } |
| 2137 | |
| 2138 | #ifndef OPENAL_POSITIONING |
| 2139 | static switch_status_t parse_position(al_handle_t *al, const char *data) |
| 2140 | { |
| 2141 | return SWITCH_STATUS_FALSE; |
| 2142 | } |
| 2143 | |
| 2144 | #else |
| 2145 | static switch_status_t parse_position(al_handle_t *al, const char *data) |
| 2146 | { |
| 2147 | char *args[3]; |
| 2148 | int num; |
| 2149 | char *dup; |
| 2150 | |
| 2151 | |
| 2152 | dup = strdup((char *)data)(__extension__ (__builtin_constant_p ((char *)data) && ((size_t)(const void *)(((char *)data) + 1) - (size_t)(const void *)((char *)data) == 1) ? (((const char *) ((char *)data ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((char *)data) + 1; char *__retval = ( char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (char *)data, __len); __retval; } )) : __strdup ((char *)data))); |
| 2153 | switch_assert(dup)((dup) ? (void) (0) : __assert_fail ("dup", "mod_conference.c" , 2153, __PRETTY_FUNCTION__)); |
| 2154 | |
| 2155 | if ((num = switch_split(dup, ':', args)switch_separate_string(dup, ':', args, (sizeof(args) / sizeof (args[0])))) != 3) { |
| 2156 | return SWITCH_STATUS_FALSE; |
| 2157 | } |
| 2158 | |
| 2159 | al->pos_x = atof(args[0]); |
| 2160 | al->pos_y = atof(args[1]); |
| 2161 | al->pos_z = atof(args[2]); |
| 2162 | al->setpos = 1; |
| 2163 | |
| 2164 | switch_safe_free(dup)if (dup) {free(dup);dup=((void*)0);}; |
| 2165 | |
| 2166 | return SWITCH_STATUS_SUCCESS; |
| 2167 | } |
| 2168 | #endif |
| 2169 | |
| 2170 | #ifndef OPENAL_POSITIONING |
| 2171 | static switch_status_t member_parse_position(conference_member_t *member, const char *data) |
| 2172 | { |
| 2173 | return SWITCH_STATUS_FALSE; |
| 2174 | } |
| 2175 | #else |
| 2176 | static switch_status_t member_parse_position(conference_member_t *member, const char *data) |
| 2177 | { |
| 2178 | switch_status_t status; |
| 2179 | |
| 2180 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
| 2181 | status = parse_position(member->al, data); |
| 2182 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
| 2183 | |
| 2184 | return status; |
| 2185 | |
| 2186 | } |
| 2187 | #endif |
| 2188 | |
| 2189 | /* Gain exclusive access and add the member to the list */ |
| 2190 | static switch_status_t conference_add_member(conference_obj_t *conference, conference_member_t *member) |
| 2191 | { |
| 2192 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 2193 | switch_event_t *event; |
| 2194 | char msg[512]; /* conference count announcement */ |
| 2195 | call_list_t *call_list = NULL((void*)0); |
| 2196 | switch_channel_t *channel; |
| 2197 | const char *controls = NULL((void*)0), *position = NULL((void*)0); |
| 2198 | |
| 2199 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 2199, __PRETTY_FUNCTION__)); |
| 2200 | switch_assert(member != NULL)((member != ((void*)0)) ? (void) (0) : __assert_fail ("member != ((void*)0)" , "mod_conference.c", 2200, __PRETTY_FUNCTION__)); |
| 2201 | |
| 2202 | switch_mutex_lock(conference->mutex); |
| 2203 | switch_mutex_lock(member->audio_in_mutex); |
| 2204 | switch_mutex_lock(member->audio_out_mutex); |
| 2205 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
| 2206 | switch_mutex_lock(conference->member_mutex); |
| 2207 | |
| 2208 | |
| 2209 | member->join_time = switch_epoch_time_now(NULL((void*)0)); |
| 2210 | member->conference = conference; |
| 2211 | member->next = conference->members; |
| 2212 | member->energy_level = conference->energy_level; |
| 2213 | member->score_iir = 0; |
| 2214 | member->verbose_events = conference->verbose_events; |
| 2215 | switch_queue_create(&member->dtmf_queue, 100, member->pool); |
| 2216 | conference->members = member; |
| 2217 | switch_set_flag_locked(member, MFLAG_INTREE)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 2217 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_INTREE);switch_mutex_unlock(member ->flag_mutex);; |
| 2218 | switch_mutex_unlock(conference->member_mutex); |
| 2219 | conference_cdr_add(member); |
| 2220 | |
| 2221 | |
| 2222 | if (!switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
| 2223 | if (switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST)) { |
| 2224 | conference->count_ghosts++; |
| 2225 | } else { |
| 2226 | conference->count++; |
| 2227 | } |
| 2228 | |
| 2229 | if (switch_test_flag(member, MFLAG_ENDCONF)((member)->flags & MFLAG_ENDCONF)) { |
| 2230 | if (conference->end_count++) { |
| 2231 | conference->endconf_time = 0; |
| 2232 | } |
| 2233 | } |
| 2234 | |
| 2235 | conference_send_presence(conference); |
| 2236 | |
| 2237 | channel = switch_core_session_get_channel(member->session); |
| 2238 | |
| 2239 | if (switch_channel_test_flag(channel, CF_VIDEO)) { |
| 2240 | switch_set_flag_locked(member, MFLAG_ACK_VIDEO)((member->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("member->flag_mutex != ((void*)0)", "mod_conference.c", 2240 , __PRETTY_FUNCTION__));switch_mutex_lock(member->flag_mutex );(member)->flags |= (MFLAG_ACK_VIDEO);switch_mutex_unlock (member->flag_mutex);; |
| 2241 | } |
| 2242 | |
| 2243 | switch_channel_set_variable_printf(channel, "conference_member_id", "%d", member->id); |
| 2244 | switch_channel_set_variable_printf(channel, "conference_moderator", "%s", switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD) ? "true" : "false"); |
| 2245 | switch_channel_set_variable_printf(channel, "conference_ghost", "%s", switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST) ? "true" : "false"); |
| 2246 | switch_channel_set_variable(channel, "conference_recording", conference->record_filename)switch_channel_set_variable_var_check(channel, "conference_recording" , conference->record_filename, SWITCH_TRUE); |
| 2247 | switch_channel_set_variable(channel, CONFERENCE_UUID_VARIABLE, conference->uuid_str)switch_channel_set_variable_var_check(channel, "conference_uuid" , conference->uuid_str, SWITCH_TRUE); |
| 2248 | |
| 2249 | if (switch_channel_test_flag(channel, CF_VIDEO)) { |
| 2250 | if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE)) { |
| 2251 | switch_channel_set_flag(channel, CF_VIDEO_ECHO)switch_channel_set_flag_value(channel, CF_VIDEO_ECHO, 1); |
| 2252 | switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE); |
| 2253 | } else { |
| 2254 | switch_channel_clear_flag(channel, CF_VIDEO_ECHO); |
| 2255 | } |
| 2256 | /* Tell the channel to request a fresh vid frame */ |
| 2257 | switch_core_session_refresh_video(member->session); |
| 2258 | |
| 2259 | if (conference->video_floor_holder) { |
| 2260 | switch_mutex_lock(conference->mutex); |
| 2261 | if (conference->video_floor_holder) { |
| 2262 | switch_core_session_refresh_video(conference->video_floor_holder->session); |
| 2263 | } |
| 2264 | switch_mutex_unlock(conference->mutex); |
| 2265 | } |
| 2266 | } |
| 2267 | |
| 2268 | if (!switch_channel_get_variable(channel, "conference_call_key")switch_channel_get_variable_dup(channel, "conference_call_key" , SWITCH_TRUE, -1)) { |
| 2269 | char *key = switch_core_session_sprintf(member->session, "conf_%s_%s_%s", |
| 2270 | conference->name, conference->domain, switch_channel_get_variable(channel, "caller_id_number")switch_channel_get_variable_dup(channel, "caller_id_number", SWITCH_TRUE , -1)); |
| 2271 | switch_channel_set_variable(channel, "conference_call_key", key)switch_channel_set_variable_var_check(channel, "conference_call_key" , key, SWITCH_TRUE); |
| 2272 | } |
| 2273 | |
| 2274 | |
| 2275 | if (switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD) && switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD)) { |
| 2276 | switch_clear_flag(conference, CFLAG_WAIT_MOD)(conference)->flags &= ~(CFLAG_WAIT_MOD); |
| 2277 | } |
| 2278 | |
| 2279 | if (conference->count > 1) { |
| 2280 | if ((conference->moh_sound && !switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) || |
| 2281 | (switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD) && !switch_true(switch_channel_get_variable(channel, "conference_permanent_wait_mod_moh")switch_channel_get_variable_dup(channel, "conference_permanent_wait_mod_moh" , SWITCH_TRUE, -1)))) { |
| 2282 | /* stop MoH if any */ |
| 2283 | conference_stop_file(conference, FILE_STOP_ASYNC); |
| 2284 | } |
| 2285 | |
| 2286 | if (!switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ) && !zstr(conference->enter_sound)_zstr(conference->enter_sound)) { |
| 2287 | const char * enter_sound = switch_channel_get_variable(channel, "conference_enter_sound")switch_channel_get_variable_dup(channel, "conference_enter_sound" , SWITCH_TRUE, -1); |
| 2288 | if (switch_test_flag(conference, CFLAG_ENTER_SOUND)((conference)->flags & CFLAG_ENTER_SOUND)) { |
| 2289 | if (!zstr(enter_sound)_zstr(enter_sound)) { |
| 2290 | conference_play_file(conference, (char *)enter_sound, CONF_DEFAULT_LEADIN20, |
| 2291 | switch_core_session_get_channel(member->session), 0); |
| 2292 | } else { |
| 2293 | conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN20, switch_core_session_get_channel(member->session), 0); |
| 2294 | } |
| 2295 | } |
| 2296 | } |
| 2297 | } |
| 2298 | |
| 2299 | |
| 2300 | call_list = (call_list_t *) switch_channel_get_private(channel, "_conference_autocall_list_"); |
| 2301 | |
| 2302 | if (call_list) { |
| 2303 | char saymsg[1024]; |
| 2304 | switch_snprintf(saymsg, sizeof(saymsg), "Auto Calling %d parties", call_list->iteration); |
| 2305 | conference_member_say(member, saymsg, 0); |
| 2306 | } else { |
| 2307 | |
| 2308 | if (!switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ)) { |
| 2309 | /* announce the total number of members in the conference */ |
| 2310 | if (conference->count >= conference->announce_count && conference->announce_count > 1) { |
| 2311 | switch_snprintf(msg, sizeof(msg), "There are %d callers", conference->count); |
| 2312 | conference_member_say(member, msg, CONF_DEFAULT_LEADIN20); |
| 2313 | } else if (conference->count == 1 && !conference->perpetual_sound && !switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) { |
| 2314 | /* as long as its not a bridge_to conference, announce if person is alone */ |
| 2315 | if (!switch_test_flag(conference, CFLAG_BRIDGE_TO)((conference)->flags & CFLAG_BRIDGE_TO)) { |
| 2316 | if (conference->alone_sound && !switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST)) { |
| 2317 | conference_stop_file(conference, FILE_STOP_ASYNC); |
| 2318 | conference_play_file(conference, conference->alone_sound, CONF_DEFAULT_LEADIN20, |
| 2319 | switch_core_session_get_channel(member->session), 0); |
| 2320 | } else { |
| 2321 | switch_snprintf(msg, sizeof(msg), "You are currently the only person in this conference."); |
| 2322 | conference_member_say(member, msg, CONF_DEFAULT_LEADIN20); |
| 2323 | } |
| 2324 | } |
| 2325 | } |
| 2326 | } |
| 2327 | } |
| 2328 | |
| 2329 | if (conference->min && conference->count >= conference->min) { |
| 2330 | switch_set_flag(conference, CFLAG_ENFORCE_MIN)(conference)->flags |= (CFLAG_ENFORCE_MIN); |
| 2331 | } |
| 2332 | |
| 2333 | if (!switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ) && |
| 2334 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2334, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
| 2335 | conference_add_event_member_data(member, event); |
| 2336 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "add-member"); |
| 2337 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2337, &event, ((void*)0)); |
| 2338 | } |
| 2339 | |
| 2340 | switch_channel_clear_app_flag_key("conf_silent", channel, CONF_SILENT_REQ); |
| 2341 | switch_channel_set_app_flag_key("conf_silent", channel, CONF_SILENT_DONE); |
| 2342 | |
| 2343 | |
| 2344 | if ((position = switch_channel_get_variable(channel, "conference_position")switch_channel_get_variable_dup(channel, "conference_position" , SWITCH_TRUE, -1))) { |
| 2345 | |
| 2346 | if (conference->channels == 2) { |
| 2347 | if (switch_test_flag(member, MFLAG_NO_POSITIONAL)((member)->flags & MFLAG_NO_POSITIONAL)) { |
| 2348 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2348, ((void*)0), SWITCH_LOG_WARNING, |
| 2349 | "%s has positional audio blocked.\n", switch_channel_get_name(channel)); |
| 2350 | } else { |
| 2351 | if (member_parse_position(member, position) != SWITCH_STATUS_SUCCESS) { |
| 2352 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2352, ((void*)0), SWITCH_LOG_WARNING, "%s invalid position data\n", switch_channel_get_name(channel)); |
| 2353 | } else { |
| 2354 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2354, ((void*)0), SWITCH_LOG_INFO, "%s position data set\n", switch_channel_get_name(channel)); |
| 2355 | } |
| 2356 | |
| 2357 | switch_set_flag(member, MFLAG_POSITIONAL)(member)->flags |= (MFLAG_POSITIONAL); |
| 2358 | member->al = create_al(member->pool); |
| 2359 | } |
| 2360 | } else { |
| 2361 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2361, ((void*)0), SWITCH_LOG_WARNING, "%s cannot set position data on mono conference.\n", switch_channel_get_name(channel)); |
| 2362 | } |
| 2363 | } |
| 2364 | |
| 2365 | |
| 2366 | |
| 2367 | controls = switch_channel_get_variable(channel, "conference_controls")switch_channel_get_variable_dup(channel, "conference_controls" , SWITCH_TRUE, -1); |
| 2368 | |
| 2369 | if (zstr(controls)_zstr(controls)) { |
| 2370 | if (!switch_test_flag(member, MFLAG_MOD)((member)->flags & MFLAG_MOD) || !conference->moderator_controls) { |
| 2371 | controls = conference->caller_controls; |
| 2372 | } else { |
| 2373 | controls = conference->moderator_controls; |
| 2374 | } |
| 2375 | } |
| 2376 | |
| 2377 | if (zstr(controls)_zstr(controls)) { |
| 2378 | controls = "default"; |
| 2379 | } |
| 2380 | |
| 2381 | if (strcasecmp(controls, "none")) { |
| 2382 | switch_ivr_dmachine_create(&member->dmachine, "mod_conference", NULL((void*)0), |
| 2383 | conference->ivr_dtmf_timeout, conference->ivr_input_timeout, NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
| 2384 | member_bind_controls(member, controls); |
| 2385 | } |
| 2386 | |
| 2387 | } |
| 2388 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
| 2389 | switch_mutex_unlock(member->audio_out_mutex); |
| 2390 | switch_mutex_unlock(member->audio_in_mutex); |
| 2391 | |
| 2392 | if (conference->la && member->channel) { |
| 2393 | member->json = cJSON_CreateArray(); |
| 2394 | cJSON_AddItemToArray(member->json, cJSON_CreateStringPrintf("%0.4d", member->id)); |
| 2395 | cJSON_AddItemToArray(member->json, cJSON_CreateString(switch_channel_get_variable(member->channel, "caller_id_number")switch_channel_get_variable_dup(member->channel, "caller_id_number" , SWITCH_TRUE, -1))); |
| 2396 | cJSON_AddItemToArray(member->json, cJSON_CreateString(switch_channel_get_variable(member->channel, "caller_id_name")switch_channel_get_variable_dup(member->channel, "caller_id_name" , SWITCH_TRUE, -1))); |
| 2397 | |
| 2398 | cJSON_AddItemToArray(member->json, cJSON_CreateStringPrintf("%s@%s", |
| 2399 | switch_channel_get_variable(member->channel, "original_read_codec")switch_channel_get_variable_dup(member->channel, "original_read_codec" , SWITCH_TRUE, -1), |
| 2400 | switch_channel_get_variable(member->channel, "original_read_rate")switch_channel_get_variable_dup(member->channel, "original_read_rate" , SWITCH_TRUE, -1) |
| 2401 | )); |
| 2402 | |
| 2403 | |
| 2404 | |
| 2405 | |
| 2406 | member->status_field = cJSON_CreateString(""); |
| 2407 | cJSON_AddItemToArray(member->json, member->status_field); |
| 2408 | |
| 2409 | cJSON_AddItemToArray(member->json, cJSON_CreateNull()); |
| 2410 | |
| 2411 | member_update_status_field(member); |
| 2412 | //switch_live_array_add_alias(conference->la, switch_core_session_get_uuid(member->session), "conference"); |
| 2413 | adv_la(conference, member, SWITCH_TRUE); |
| 2414 | switch_live_array_add(conference->la, switch_core_session_get_uuid(member->session), -1, &member->json, SWITCH_FALSE); |
| 2415 | |
| 2416 | } |
| 2417 | |
| 2418 | |
| 2419 | if (switch_test_flag(conference, CFLAG_POSITIONAL)((conference)->flags & CFLAG_POSITIONAL)) { |
| 2420 | gen_arc(conference, NULL((void*)0)); |
| 2421 | } |
| 2422 | |
| 2423 | |
| 2424 | send_rfc_event(conference); |
| 2425 | send_json_event(conference); |
| 2426 | |
| 2427 | switch_mutex_unlock(conference->mutex); |
| 2428 | status = SWITCH_STATUS_SUCCESS; |
| 2429 | |
| 2430 | |
| 2431 | |
| 2432 | |
| 2433 | return status; |
| 2434 | } |
| 2435 | |
| 2436 | static void conference_set_video_floor_holder(conference_obj_t *conference, conference_member_t *member, switch_bool_t force) |
| 2437 | { |
| 2438 | switch_event_t *event; |
| 2439 | conference_member_t *old_member = NULL((void*)0), *imember = NULL((void*)0); |
| 2440 | int old_id = 0; |
| 2441 | |
| 2442 | if (!member) { |
| 2443 | switch_clear_flag(conference, CFLAG_VID_FLOOR_LOCK)(conference)->flags &= ~(CFLAG_VID_FLOOR_LOCK); |
| 2444 | } |
| 2445 | |
| 2446 | if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE) || (!force && switch_test_flag(conference, CFLAG_VID_FLOOR_LOCK)((conference)->flags & CFLAG_VID_FLOOR_LOCK))) { |
| 2447 | return; |
| 2448 | } |
| 2449 | |
| 2450 | if (conference->video_floor_holder) { |
| 2451 | if (conference->video_floor_holder == member) { |
| 2452 | return; |
| 2453 | } else { |
| 2454 | old_member = conference->video_floor_holder; |
| 2455 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2455, ((void*)0), SWITCH_LOG_DEBUG1, "Dropping video floor %s\n", |
| 2456 | switch_channel_get_name(old_member->channel)); |
| 2457 | } |
| 2458 | } |
| 2459 | |
| 2460 | |
| 2461 | switch_mutex_lock(conference->mutex); |
| 2462 | if (!member) { |
| 2463 | for (imember = conference->members; imember; imember = imember->next) { |
| 2464 | if (imember != conference->video_floor_holder && imember->channel && switch_channel_test_flag(imember->channel, CF_VIDEO)) { |
| 2465 | member = imember; |
| 2466 | break; |
| 2467 | } |
| 2468 | } |
| 2469 | } |
| 2470 | |
| 2471 | if (member) { |
| 2472 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2472, ((void*)0), SWITCH_LOG_DEBUG1, "Adding video floor %s\n", |
| 2473 | switch_channel_get_name(member->channel)); |
| 2474 | //switch_channel_set_flag(member->channel, CF_VIDEO_PASSIVE); |
| 2475 | switch_core_session_refresh_video(member->session); |
| 2476 | conference->video_floor_holder = member; |
| 2477 | member_update_status_field(member); |
| 2478 | } else { |
| 2479 | conference->video_floor_holder = NULL((void*)0); |
| 2480 | } |
| 2481 | |
| 2482 | if (old_member) { |
| 2483 | old_id = old_member->id; |
| 2484 | member_update_status_field(old_member); |
| 2485 | //switch_channel_clear_flag(old_member->channel, CF_VIDEO_PASSIVE); |
| 2486 | } |
| 2487 | |
| 2488 | for (imember = conference->members; imember; imember = imember->next) { |
| 2489 | if (!imember->channel || !switch_channel_test_flag(imember->channel, CF_VIDEO)) { |
| 2490 | continue; |
| 2491 | } |
| 2492 | switch_channel_clear_flag(imember->channel, CF_VIDEO_ECHO); |
| 2493 | |
| 2494 | if (imember == conference->video_floor_holder) { |
| 2495 | switch_channel_set_flag(imember->channel, CF_VIDEO_PASSIVE)switch_channel_set_flag_value(imember->channel, CF_VIDEO_PASSIVE , 1); |
| 2496 | } else { |
| 2497 | switch_channel_clear_flag(imember->channel, CF_VIDEO_PASSIVE); |
| 2498 | } |
| 2499 | |
| 2500 | switch_channel_set_flag(imember->channel, CF_VIDEO_BREAK)switch_channel_set_flag_value(imember->channel, CF_VIDEO_BREAK , 1); |
| 2501 | switch_core_session_kill_channel(imember->session, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(imember->session, "mod_conference.c", (const char *)__func__, 2501, SWITCH_SIG_BREAK ); |
| 2502 | switch_core_session_refresh_video(imember->session); |
| 2503 | } |
| 2504 | |
| 2505 | switch_set_flag(conference, CFLAG_FLOOR_CHANGE)(conference)->flags |= (CFLAG_FLOOR_CHANGE); |
| 2506 | switch_mutex_unlock(conference->mutex); |
| 2507 | |
| 2508 | if (test_eflag(conference, EFLAG_FLOOR_CHANGE)((conference)->eflags & EFLAG_FLOOR_CHANGE)) { |
| 2509 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2509, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance"); |
| 2510 | conference_add_event_data(conference, event); |
| 2511 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "video-floor-change"); |
| 2512 | if (old_id) { |
| 2513 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-ID", "%d", old_id); |
| 2514 | } else { |
| 2515 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-ID", "none"); |
| 2516 | } |
| 2517 | if (conference->video_floor_holder) { |
| 2518 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", conference->video_floor_holder->id); |
| 2519 | } else { |
| 2520 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "New-ID", "none"); |
| 2521 | } |
| 2522 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2522, &event, ((void*)0)); |
| 2523 | } |
| 2524 | |
| 2525 | } |
| 2526 | |
| 2527 | static void conference_set_floor_holder(conference_obj_t *conference, conference_member_t *member) |
| 2528 | { |
| 2529 | switch_event_t *event; |
| 2530 | conference_member_t *old_member = NULL((void*)0); |
| 2531 | int old_id = 0; |
| 2532 | |
| 2533 | if (!switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE) && |
| 2534 | ((conference->video_floor_holder && !member && !switch_test_flag(conference, CFLAG_VID_FLOOR_LOCK)((conference)->flags & CFLAG_VID_FLOOR_LOCK)) || |
| 2535 | (member && member->channel && switch_channel_test_flag(member->channel, CF_VIDEO)))) { |
| 2536 | conference_set_video_floor_holder(conference, member, SWITCH_FALSE); |
| 2537 | } |
| 2538 | |
| 2539 | if (conference->floor_holder) { |
| 2540 | if (conference->floor_holder == member) { |
| 2541 | return; |
| 2542 | } else { |
| 2543 | old_member = conference->floor_holder; |
| 2544 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2544, ((void*)0), SWITCH_LOG_DEBUG1, "Dropping floor %s\n", |
| 2545 | switch_channel_get_name(old_member->channel)); |
| 2546 | |
| 2547 | } |
| 2548 | } |
| 2549 | |
| 2550 | switch_mutex_lock(conference->mutex); |
| 2551 | if (member) { |
| 2552 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2552, ((void*)0), SWITCH_LOG_DEBUG1, "Adding floor %s\n", |
| 2553 | switch_channel_get_name(member->channel)); |
| 2554 | |
| 2555 | conference->floor_holder = member; |
| 2556 | member_update_status_field(member); |
| 2557 | } else { |
| 2558 | conference->floor_holder = NULL((void*)0); |
| 2559 | } |
| 2560 | |
| 2561 | |
| 2562 | if (old_member) { |
| 2563 | old_id = old_member->id; |
| 2564 | member_update_status_field(old_member); |
| 2565 | } |
| 2566 | |
| 2567 | switch_set_flag(conference, CFLAG_FLOOR_CHANGE)(conference)->flags |= (CFLAG_FLOOR_CHANGE); |
| 2568 | switch_mutex_unlock(conference->mutex); |
| 2569 | |
| 2570 | if (test_eflag(conference, EFLAG_FLOOR_CHANGE)((conference)->eflags & EFLAG_FLOOR_CHANGE)) { |
| 2571 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2571, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance"); |
| 2572 | conference_add_event_data(conference, event); |
| 2573 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "floor-change"); |
| 2574 | if (old_id) { |
| 2575 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-ID", "%d", old_id); |
| 2576 | } else { |
| 2577 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-ID", "none"); |
| 2578 | } |
| 2579 | |
| 2580 | if (conference->floor_holder) { |
| 2581 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", conference->floor_holder->id); |
| 2582 | } else { |
| 2583 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "New-ID", "none"); |
| 2584 | } |
| 2585 | |
| 2586 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2586, &event, ((void*)0)); |
| 2587 | } |
| 2588 | |
| 2589 | } |
| 2590 | |
| 2591 | #ifdef OPENAL_POSITIONING |
| 2592 | static void close_al(al_handle_t *al) |
| 2593 | { |
| 2594 | if (!al) return; |
| 2595 | |
| 2596 | switch_mutex_lock(globals.setup_mutex); |
| 2597 | if (al->source) { |
| 2598 | alDeleteSources(1, &al->source); |
| 2599 | al->source = 0; |
| 2600 | } |
| 2601 | |
| 2602 | if (al->buffer_in[0]) { |
| 2603 | alDeleteBuffers(2, al->buffer_in); |
| 2604 | al->buffer_in[0] = 0; |
| 2605 | al->buffer_in[1] = 0; |
| 2606 | } |
| 2607 | |
| 2608 | if (al->context) { |
| 2609 | alcDestroyContext(al->context); |
| 2610 | al->context = 0; |
| 2611 | } |
| 2612 | |
| 2613 | if (al->device) { |
| 2614 | alcCloseDevice(al->device); |
| 2615 | al->device = NULL((void*)0); |
| 2616 | } |
| 2617 | switch_mutex_unlock(globals.setup_mutex); |
| 2618 | } |
| 2619 | #endif |
| 2620 | |
| 2621 | static switch_status_t conference_file_close(conference_obj_t *conference, conference_file_node_t *node) |
| 2622 | { |
| 2623 | switch_event_t *event; |
| 2624 | conference_member_t *member = NULL((void*)0); |
| 2625 | |
| 2626 | if (test_eflag(conference, EFLAG_PLAY_FILE_DONE)((conference)->eflags & EFLAG_PLAY_FILE_DONE) && |
| 2627 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2627, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
| 2628 | |
| 2629 | conference_add_event_data(conference, event); |
| 2630 | |
| 2631 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "seconds", "%ld", (long) node->fh.samples_in / node->fh.native_rate); |
| 2632 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "milliseconds", "%ld", (long) node->fh.samples_in / (node->fh.native_rate / 1000)); |
| 2633 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "samples", "%ld", (long) node->fh.samples_in); |
| 2634 | |
| 2635 | if (node->fh.params) { |
| 2636 | switch_event_merge(event, node->fh.params); |
| 2637 | } |
| 2638 | |
| 2639 | if (node->member_id) { |
| 2640 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member-done"); |
| 2641 | |
| 2642 | if ((member = conference_member_get(conference, node->member_id))) { |
| 2643 | conference_add_event_member_data(member, event); |
| 2644 | switch_thread_rwlock_unlock(member->rwlock); |
| 2645 | } |
| 2646 | |
| 2647 | } else { |
| 2648 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-done"); |
| 2649 | } |
| 2650 | |
| 2651 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", node->file); |
| 2652 | |
| 2653 | if (node->async) { |
| 2654 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", "true"); |
| 2655 | } |
| 2656 | |
| 2657 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2657, &event, ((void*)0)); |
| 2658 | } |
| 2659 | |
| 2660 | #ifdef OPENAL_POSITIONING |
| 2661 | if (node->al && node->al->device) { |
| 2662 | close_al(node->al); |
| 2663 | } |
| 2664 | #endif |
| 2665 | |
| 2666 | return switch_core_file_close(&node->fh); |
| 2667 | } |
| 2668 | |
| 2669 | /* Gain exclusive access and remove the member from the list */ |
| 2670 | static switch_status_t conference_del_member(conference_obj_t *conference, conference_member_t *member) |
| 2671 | { |
| 2672 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 2673 | conference_member_t *imember, *last = NULL((void*)0); |
| 2674 | switch_event_t *event; |
| 2675 | conference_file_node_t *member_fnode; |
| 2676 | switch_speech_handle_t *member_sh; |
| 2677 | const char *exit_sound = NULL((void*)0); |
| 2678 | |
| 2679 | switch_assert(conference != NULL)((conference != ((void*)0)) ? (void) (0) : __assert_fail ("conference != ((void*)0)" , "mod_conference.c", 2679, __PRETTY_FUNCTION__)); |
| 2680 | switch_assert(member != NULL)((member != ((void*)0)) ? (void) (0) : __assert_fail ("member != ((void*)0)" , "mod_conference.c", 2680, __PRETTY_FUNCTION__)); |
| 2681 | |
| 2682 | switch_thread_rwlock_wrlock(member->rwlock); |
| 2683 | |
| 2684 | if (member->session && (exit_sound = switch_channel_get_variable(switch_core_session_get_channel(member->session), "conference_exit_sound")switch_channel_get_variable_dup(switch_core_session_get_channel (member->session), "conference_exit_sound", SWITCH_TRUE, - 1))) { |
| 2685 | conference_play_file(conference, (char *)exit_sound, CONF_DEFAULT_LEADIN20, |
| 2686 | switch_core_session_get_channel(member->session), 0); |
| 2687 | } |
| 2688 | |
| 2689 | |
| 2690 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
| 2691 | |
| 2692 | |
| 2693 | conference_cdr_del(member); |
| 2694 | |
| 2695 | #ifdef OPENAL_POSITIONING |
| 2696 | if (member->al && member->al->device) { |
| 2697 | close_al(member->al); |
| 2698 | } |
| 2699 | #endif |
| 2700 | |
| 2701 | member_fnode = member->fnode; |
| 2702 | member_sh = member->sh; |
| 2703 | member->fnode = NULL((void*)0); |
| 2704 | member->sh = NULL((void*)0); |
| 2705 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
| 2706 | |
| 2707 | if (member->dmachine) { |
| 2708 | switch_ivr_dmachine_destroy(&member->dmachine); |
| 2709 | } |
| 2710 | |
| 2711 | switch_mutex_lock(conference->mutex); |
| 2712 | switch_mutex_lock(conference->member_mutex); |
| 2713 | switch_mutex_lock(member->audio_in_mutex); |
| 2714 | switch_mutex_lock(member->audio_out_mutex); |
| 2715 | lock_member(member)switch_mutex_lock(member->write_mutex); switch_mutex_lock( member->read_mutex); |
| 2716 | switch_clear_flag(member, MFLAG_INTREE)(member)->flags &= ~(MFLAG_INTREE); |
| 2717 | |
| 2718 | for (imember = conference->members; imember; imember = imember->next) { |
| 2719 | if (imember == member) { |
| 2720 | if (last) { |
| 2721 | last->next = imember->next; |
| 2722 | } else { |
| 2723 | conference->members = imember->next; |
| 2724 | } |
| 2725 | break; |
| 2726 | } |
| 2727 | last = imember; |
| 2728 | } |
| 2729 | |
| 2730 | switch_thread_rwlock_unlock(member->rwlock); |
| 2731 | |
| 2732 | /* Close Unused Handles */ |
| 2733 | if (member_fnode) { |
| 2734 | conference_file_node_t *fnode, *cur; |
| 2735 | switch_memory_pool_t *pool; |
| 2736 | |
| 2737 | fnode = member_fnode; |
| 2738 | while (fnode) { |
| 2739 | cur = fnode; |
| 2740 | fnode = fnode->next; |
| 2741 | |
| 2742 | if (cur->type != NODE_TYPE_SPEECH) { |
| 2743 | conference_file_close(conference, cur); |
| 2744 | } |
| 2745 | |
| 2746 | pool = cur->pool; |
| 2747 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_conference.c" , (const char *)__func__, 2747); |
| 2748 | } |
| 2749 | } |
| 2750 | |
| 2751 | if (member_sh) { |
| 2752 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; |
| 2753 | switch_core_speech_close(&member->lsh, &flags); |
| 2754 | } |
| 2755 | |
| 2756 | if (member == member->conference->floor_holder) { |
| 2757 | conference_set_floor_holder(member->conference, NULL((void*)0)); |
| 2758 | } |
| 2759 | |
| 2760 | |
| 2761 | if (member == member->conference->video_floor_holder) { |
| 2762 | conference_set_video_floor_holder(member->conference, NULL((void*)0), SWITCH_TRUE); |
| 2763 | } |
| 2764 | |
| 2765 | member->conference = NULL((void*)0); |
| 2766 | |
| 2767 | if (!switch_test_flag(member, MFLAG_NOCHANNEL)((member)->flags & MFLAG_NOCHANNEL)) { |
| 2768 | switch_channel_t *channel = switch_core_session_get_channel(member->session); |
| 2769 | if (switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST)) { |
| 2770 | conference->count_ghosts--; |
| 2771 | } else { |
| 2772 | conference->count--; |
| 2773 | } |
| 2774 | |
| 2775 | if (switch_test_flag(member, MFLAG_ENDCONF)((member)->flags & MFLAG_ENDCONF)) { |
| 2776 | if (!--conference->end_count) { |
| 2777 | //switch_set_flag_locked(conference, CFLAG_DESTRUCT); |
| 2778 | conference->endconf_time = switch_epoch_time_now(NULL((void*)0)); |
| 2779 | } |
| 2780 | } |
| 2781 | |
| 2782 | conference_send_presence(conference); |
| 2783 | switch_channel_set_variable(channel, "conference_call_key", NULL)switch_channel_set_variable_var_check(channel, "conference_call_key" , ((void*)0), SWITCH_TRUE); |
| 2784 | |
| 2785 | if ((conference->min && switch_test_flag(conference, CFLAG_ENFORCE_MIN)((conference)->flags & CFLAG_ENFORCE_MIN) && (conference->count + conference->count_ghosts) < conference->min) |
| 2786 | || (switch_test_flag(conference, CFLAG_DYNAMIC)((conference)->flags & CFLAG_DYNAMIC) && (conference->count + conference->count_ghosts == 0))) { |
| 2787 | switch_set_flag(conference, CFLAG_DESTRUCT)(conference)->flags |= (CFLAG_DESTRUCT); |
| 2788 | } else { |
| 2789 | if (!switch_true(switch_channel_get_variable(channel, "conference_permanent_wait_mod_moh")switch_channel_get_variable_dup(channel, "conference_permanent_wait_mod_moh" , SWITCH_TRUE, -1)) && switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) { |
| 2790 | /* Stop MOH if any */ |
| 2791 | conference_stop_file(conference, FILE_STOP_ASYNC); |
| 2792 | } |
| 2793 | if (!exit_sound && conference->exit_sound && switch_test_flag(conference, CFLAG_EXIT_SOUND)((conference)->flags & CFLAG_EXIT_SOUND)) { |
| 2794 | conference_play_file(conference, conference->exit_sound, 0, channel, 0); |
| 2795 | } |
| 2796 | if (conference->count == 1 && conference->alone_sound && !switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD) && !switch_test_flag(member, MFLAG_GHOST)((member)->flags & MFLAG_GHOST)) { |
| 2797 | conference_stop_file(conference, FILE_STOP_ASYNC); |
| 2798 | conference_play_file(conference, conference->alone_sound, 0, channel, 0); |
| 2799 | } |
| 2800 | } |
| 2801 | |
| 2802 | if (test_eflag(conference, EFLAG_DEL_MEMBER)((conference)->eflags & EFLAG_DEL_MEMBER) && |
| 2803 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 2803, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance") == SWITCH_STATUS_SUCCESS) { |
| 2804 | conference_add_event_member_data(member, event); |
| 2805 | conference_add_event_data(conference, event); |
| 2806 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "del-member"); |
| 2807 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 2807, &event, ((void*)0)); |
| 2808 | } |
| 2809 | } |
| 2810 | switch_mutex_unlock(conference->member_mutex); |
| 2811 | unlock_member(member)switch_mutex_unlock(member->read_mutex); switch_mutex_unlock (member->write_mutex); |
| 2812 | switch_mutex_unlock(member->audio_out_mutex); |
| 2813 | switch_mutex_unlock(member->audio_in_mutex); |
| 2814 | |
| 2815 | |
| 2816 | if (conference->la && member->session) { |
| 2817 | switch_live_array_del(conference->la, switch_core_session_get_uuid(member->session)); |
| 2818 | //switch_live_array_clear_alias(conference->la, switch_core_session_get_uuid(member->session), "conference"); |
| 2819 | adv_la(conference, member, SWITCH_FALSE); |
| 2820 | } |
| 2821 | |
| 2822 | send_rfc_event(conference); |
| 2823 | send_json_event(conference); |
| 2824 | |
| 2825 | if (switch_test_flag(conference, CFLAG_POSITIONAL)((conference)->flags & CFLAG_POSITIONAL)) { |
| 2826 | gen_arc(conference, NULL((void*)0)); |
| 2827 | } |
| 2828 | |
| 2829 | if (member->session) { |
| 2830 | switch_core_media_hard_mute(member->session, SWITCH_FALSE); |
| 2831 | } |
| 2832 | |
| 2833 | switch_mutex_unlock(conference->mutex); |
| 2834 | status = SWITCH_STATUS_SUCCESS; |
| 2835 | |
| 2836 | return status; |
| 2837 | } |
| 2838 | |
| 2839 | /* Thread bridging video between two members, there will be two threads if video briding is used */ |
| 2840 | static void *SWITCH_THREAD_FUNC conference_video_bridge_thread_run(switch_thread_t *thread, void *obj) |
| 2841 | { |
| 2842 | struct vid_helper *vh = obj; |
| 2843 | switch_core_session_t *session_a = vh->member_a->session; |
| 2844 | switch_core_session_t *session_b = vh->member_b->session; |
| 2845 | switch_channel_t *channel_a = switch_core_session_get_channel(session_a); |
| 2846 | switch_channel_t *channel_b = switch_core_session_get_channel(session_b); |
| 2847 | switch_status_t status; |
| 2848 | switch_frame_t *read_frame; |
| 2849 | conference_obj_t *conference = vh->member_a->conference; |
| 2850 | |
| 2851 | switch_thread_rwlock_rdlock(conference->rwlock); |
| 2852 | switch_thread_rwlock_rdlock(vh->member_a->rwlock); |
| 2853 | switch_thread_rwlock_rdlock(vh->member_b->rwlock); |
| 2854 | |
| 2855 | |
| 2856 | switch_channel_set_flag(channel_a, CF_VIDEO_PASSIVE)switch_channel_set_flag_value(channel_a, CF_VIDEO_PASSIVE, 1); |
| 2857 | |
| 2858 | /* Acquire locks for both sessions so the helper object and member structures don't get destroyed before we exit */ |
| 2859 | switch_core_session_read_lock(session_a); |
| 2860 | switch_core_session_read_lock(session_b); |
| 2861 | |
| 2862 | vh->up = 1; |
| 2863 | while (vh->up == 1 && switch_test_flag(vh->member_a, MFLAG_RUNNING)((vh->member_a)->flags & MFLAG_RUNNING) && switch_test_flag(vh->member_b, MFLAG_RUNNING)((vh->member_b)->flags & MFLAG_RUNNING) && |
| 2864 | switch_channel_ready(channel_a)switch_channel_test_ready(channel_a, SWITCH_TRUE, SWITCH_FALSE ) && switch_channel_ready(channel_b)switch_channel_test_ready(channel_b, SWITCH_TRUE, SWITCH_FALSE )) { |
| 2865 | |
| 2866 | if (switch_channel_test_flag(channel_a, CF_VIDEO_REFRESH_REQ)) { |
| 2867 | switch_core_session_refresh_video(session_b); |
| 2868 | switch_channel_clear_flag(channel_a, CF_VIDEO_REFRESH_REQ); |
| 2869 | } |
| 2870 | |
| 2871 | status = switch_core_session_read_video_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0); |
| 2872 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { |
| 2873 | break; |
| 2874 | } |
| 2875 | |
| 2876 | if (!switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) { |
| 2877 | if (switch_core_session_write_video_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { |
| 2878 | break; |
| 2879 | } |
| 2880 | } |
| 2881 | } |
| 2882 | switch_channel_clear_flag(channel_a, CF_VIDEO_PASSIVE); |
| 2883 | |
| 2884 | switch_thread_rwlock_unlock(vh->member_b->rwlock); |
| 2885 | switch_thread_rwlock_unlock(vh->member_a->rwlock); |
| 2886 | |
| 2887 | switch_core_session_rwunlock(session_a); |
| 2888 | switch_core_session_rwunlock(session_b); |
| 2889 | |
| 2890 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2890, ((void*)0), SWITCH_LOG_DEBUG, "%s video thread ended.\n", switch_channel_get_name(channel_a)); |
| 2891 | |
| 2892 | switch_thread_rwlock_unlock(conference->rwlock); |
| 2893 | |
| 2894 | vh->up = 0; |
| 2895 | return NULL((void*)0); |
| 2896 | } |
| 2897 | |
| 2898 | |
| 2899 | /* Main video monitor thread (1 per distinct conference room) */ |
| 2900 | static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thread, void *obj) |
| 2901 | { |
| 2902 | conference_obj_t *conference = (conference_obj_t *) obj; |
| 2903 | conference_member_t *imember; |
| 2904 | switch_frame_t *vid_frame = NULL((void*)0); |
| 2905 | switch_status_t status; |
| 2906 | int want_refresh = 0; |
| 2907 | int yield = 0; |
| 2908 | switch_core_session_t *session; |
| 2909 | char buf[65536]; |
| 2910 | conference_member_t *floor_holder = NULL((void*)0); |
| 2911 | |
| 2912 | conference->video_running = 1; |
| 2913 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 2913, ((void*)0), SWITCH_LOG_DEBUG, "Video thread started for conference %s\n", conference->name); |
| 2914 | |
| 2915 | while (conference->video_running == 1 && globals.running && !switch_test_flag(conference, CFLAG_DESTRUCT)((conference)->flags & CFLAG_DESTRUCT)) { |
| 2916 | if (yield) { |
| 2917 | switch_yield(yield)switch_sleep(yield);; |
| 2918 | yield = 0; |
| 2919 | } |
| 2920 | |
| 2921 | switch_mutex_lock(conference->mutex); |
| 2922 | |
| 2923 | if (conference->video_floor_holder) { |
| 2924 | floor_holder = conference->video_floor_holder; |
| 2925 | } else { |
| 2926 | floor_holder = NULL((void*)0); |
| 2927 | } |
| 2928 | |
| 2929 | |
| 2930 | if (!floor_holder) { |
| 2931 | yield = 100000; |
| 2932 | goto do_continue; |
| 2933 | } |
| 2934 | |
| 2935 | if (!floor_holder->session || !floor_holder->channel || !switch_channel_test_flag(floor_holder->channel, CF_VIDEO)) { |
| 2936 | yield = 100000; |
| 2937 | goto do_continue; |
| 2938 | } |
| 2939 | |
| 2940 | session = floor_holder->session; |
| 2941 | |
| 2942 | if ((status = switch_core_session_read_lock(session)) == SWITCH_STATUS_SUCCESS) { |
| 2943 | switch_mutex_unlock(conference->mutex); |
| 2944 | if (!switch_channel_ready(switch_core_session_get_channel(session))switch_channel_test_ready(switch_core_session_get_channel(session ), SWITCH_TRUE, SWITCH_FALSE)) { |
| 2945 | status = SWITCH_STATUS_FALSE; |
| 2946 | } else { |
| 2947 | status = switch_core_session_read_video_frame(session, &vid_frame, SWITCH_IO_FLAG_NONE, 0); |
| 2948 | } |
| 2949 | switch_mutex_lock(conference->mutex); |
| 2950 | switch_core_session_rwunlock(session); |
| 2951 | } |
| 2952 | |
| 2953 | if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)) { |
| 2954 | yield = 100000; |
| 2955 | goto do_continue; |
| 2956 | } |
| 2957 | |
| 2958 | if (vid_frame && switch_test_flag(vid_frame, SFF_CNG)((vid_frame)->flags & SFF_CNG)) { |
| 2959 | yield = 10000; |
| 2960 | goto do_continue; |
| 2961 | } |
| 2962 | |
| 2963 | memcpy(buf, vid_frame->packet, vid_frame->packetlen); |
| 2964 | |
| 2965 | switch_mutex_unlock(conference->mutex); |
| 2966 | switch_mutex_lock(conference->mutex); |
| 2967 | want_refresh = 0; |
| 2968 | |
| 2969 | if (switch_test_flag(conference, CFLAG_FLOOR_CHANGE)((conference)->flags & CFLAG_FLOOR_CHANGE)) { |
| 2970 | switch_clear_flag(conference, CFLAG_FLOOR_CHANGE)(conference)->flags &= ~(CFLAG_FLOOR_CHANGE); |
| 2971 | } |
| 2972 | |
| 2973 | for (imember = conference->members; imember; imember = imember->next) { |
| 2974 | switch_core_session_t *isession = imember->session; |
| 2975 | switch_channel_t *ichannel; |
| 2976 | |
| 2977 | if (!isession || switch_core_session_read_lock(isession) != SWITCH_STATUS_SUCCESS) { |
| 2978 | continue; |
| 2979 | } |
| 2980 | |
| 2981 | ichannel = switch_core_session_get_channel(imember->session); |
| 2982 | |
| 2983 | if (switch_channel_test_flag(ichannel, CF_VIDEO_REFRESH_REQ)) { |
| 2984 | want_refresh++; |
| 2985 | switch_channel_clear_flag(ichannel, CF_VIDEO_REFRESH_REQ); |
| 2986 | } |
| 2987 | |
| 2988 | if (isession && switch_channel_test_flag(ichannel, CF_VIDEO)) { |
| 2989 | memcpy(vid_frame->packet, buf, vid_frame->packetlen); |
| 2990 | switch_core_session_write_video_frame(imember->session, vid_frame, SWITCH_IO_FLAG_NONE, 0); |
| 2991 | } |
| 2992 | |
| 2993 | switch_core_session_rwunlock(isession); |
| 2994 | } |
| 2995 | |
| 2996 | if (want_refresh && session) { |
| 2997 | switch_core_session_refresh_video(session); |
| 2998 | want_refresh = 0; |
| 2999 | } |
| 3000 | |
| 3001 | do_continue: |
| 3002 | switch_mutex_unlock(conference->mutex); |
| 3003 | } |
| 3004 | |
| 3005 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3005, ((void*)0), SWITCH_LOG_DEBUG, "Video thread ending for conference %s\n", conference->name); |
| 3006 | conference->video_running = 0; |
| 3007 | |
| 3008 | return NULL((void*)0); |
| 3009 | } |
| 3010 | |
| 3011 | static void conference_command_handler(switch_live_array_t *la, const char *cmd, const char *sessid, cJSON *jla, void *user_data) |
| 3012 | { |
| 3013 | } |
| 3014 | |
| 3015 | /* Main monitor thread (1 per distinct conference room) */ |
| 3016 | static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *obj) |
| 3017 | { |
| 3018 | conference_obj_t *conference = (conference_obj_t *) obj; |
| 3019 | conference_member_t *imember, *omember; |
| 3020 | uint32_t samples = switch_samples_per_packet(conference->rate, conference->interval)((uint32_t)((float)conference->rate / (1000.0f / (float)conference ->interval))); |
| 3021 | uint32_t bytes = samples * 2 * conference->channels; |
| 3022 | uint8_t ready = 0, total = 0; |
| 3023 | switch_timer_t timer = { 0 }; |
| 3024 | switch_event_t *event; |
| 3025 | uint8_t *file_frame; |
| 3026 | uint8_t *async_file_frame; |
| 3027 | int16_t *bptr; |
| 3028 | uint32_t x = 0; |
| 3029 | int32_t z = 0; |
| 3030 | int member_score_sum = 0; |
| 3031 | int divisor = 0; |
| 3032 | conference_cdr_node_t *np; |
| 3033 | |
| 3034 | if (!(divisor = conference->rate / 8000)) { |
| 3035 | divisor = 1; |
| 3036 | } |
| 3037 | |
| 3038 | file_frame = switch_core_alloc(conference->pool, SWITCH_RECOMMENDED_BUFFER_SIZE)switch_core_perform_alloc(conference->pool, 8192, "mod_conference.c" , (const char *)__func__, 3038); |
| 3039 | async_file_frame = switch_core_alloc(conference->pool, SWITCH_RECOMMENDED_BUFFER_SIZE)switch_core_perform_alloc(conference->pool, 8192, "mod_conference.c" , (const char *)__func__, 3039); |
| 3040 | |
| 3041 | if (switch_core_timer_init(&timer, conference->timer_name, conference->interval, samples, conference->pool) == SWITCH_STATUS_SUCCESS) { |
| 3042 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3042, ((void*)0), SWITCH_LOG_DEBUG, "Setup timer success interval: %u samples: %u\n", conference->interval, samples); |
| 3043 | } else { |
| 3044 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3044, ((void*)0), SWITCH_LOG_ERROR, "Timer Setup Failed. Conference Cannot Start\n"); |
| 3045 | return NULL((void*)0); |
| 3046 | } |
| 3047 | |
| 3048 | switch_mutex_lock(globals.hash_mutex); |
| 3049 | globals.threads++; |
| 3050 | switch_mutex_unlock(globals.hash_mutex); |
| 3051 | |
| 3052 | conference->auto_recording = 0; |
| 3053 | conference->record_count = 0; |
| 3054 | |
| 3055 | |
| 3056 | |
| 3057 | switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT)switch_event_create_subclass_detailed("mod_conference.c", (const char * )(const char *)__func__, 3057, &event, SWITCH_EVENT_CUSTOM , "conference::maintenance"); |
| 3058 | conference_add_event_data(conference, event); |
| 3059 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-create"); |
| 3060 | switch_event_fire(&event)switch_event_fire_detailed("mod_conference.c", (const char * ) (const char *)__func__, 3060, &event, ((void*)0)); |
| 3061 | |
| 3062 | if (switch_test_flag(conference, CFLAG_LIVEARRAY_SYNC)((conference)->flags & CFLAG_LIVEARRAY_SYNC)) { |
| 3063 | char *p; |
| 3064 | |
| 3065 | if (strchr(conference->name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conference->name) && ('@') == '\0' ? (char *) __rawmemchr (conference->name, '@') : __builtin_strchr (conference-> name, '@')))) { |
| 3066 | conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s", conference->name); |
| 3067 | conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s", conference->name); |
| 3068 | } else { |
| 3069 | conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s@%s", conference->name, conference->domain); |
| 3070 | conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s@%s", conference->name, conference->domain); |
| 3071 | } |
| 3072 | |
| 3073 | conference->la_name = switch_core_strdup(conference->pool, conference->name)switch_core_perform_strdup(conference->pool, conference-> name, "mod_conference.c", (const char *)__func__, 3073); |
| 3074 | if ((p = strchr(conference->la_name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p (conference->la_name) && ('@') == '\0' ? (char *) __rawmemchr (conference->la_name, '@') : __builtin_strchr (conference->la_name, '@'))))) { |
| 3075 | *p = '\0'; |
| 3076 | } |
| 3077 | |
| 3078 | switch_live_array_create(conference->la_event_channel, conference->la_name, globals.event_channel_id, &conference->la); |
| 3079 | switch_live_array_set_user_data(conference->la, conference); |
| 3080 | switch_live_array_set_command_handler(conference->la, conference_command_handler); |
| 3081 | } |
| 3082 | |
| 3083 | |
| 3084 | while (globals.running && !switch_test_flag(conference, CFLAG_DESTRUCT)((conference)->flags & CFLAG_DESTRUCT)) { |
| 3085 | switch_size_t file_sample_len = samples; |
| 3086 | switch_size_t file_data_len = samples * 2 * conference->channels; |
| 3087 | int has_file_data = 0, members_with_video = 0; |
| 3088 | uint32_t conf_energy = 0; |
| 3089 | int nomoh = 0; |
| 3090 | conference_member_t *floor_holder, *video_bridge_members[2] = { 0 }; |
| 3091 | |
| 3092 | /* Sync the conference to a single timing source */ |
| 3093 | if (switch_core_timer_next(&timer) != SWITCH_STATUS_SUCCESS) { |
| 3094 | switch_set_flag(conference, CFLAG_DESTRUCT)(conference)->flags |= (CFLAG_DESTRUCT); |
| 3095 | break; |
| 3096 | } |
| 3097 | |
| 3098 | switch_mutex_lock(conference->mutex); |
| 3099 | has_file_data = ready = total = 0; |
| 3100 | |
| 3101 | floor_holder = conference->floor_holder; |
| 3102 | |
| 3103 | /* Read one frame of audio from each member channel and save it for redistribution */ |
| 3104 | for (imember = conference->members; imember; imember = imember->next) { |
| 3105 | uint32_t buf_read = 0; |
| 3106 | total++; |
| 3107 | imember->read = 0; |
| 3108 | |
| 3109 | if (switch_test_flag(imember, MFLAG_RUNNING)((imember)->flags & MFLAG_RUNNING) && imember->session) { |
| 3110 | switch_channel_t *channel = switch_core_session_get_channel(imember->session); |
| 3111 | |
| 3112 | if ((!floor_holder || (imember->score_iir > SCORE_IIR_SPEAKING_MAX300 && (floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN100)))) {// && |
| 3113 | //(!switch_test_flag(conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) { |
| 3114 | floor_holder = imember; |
| 3115 | } |
| 3116 | |
| 3117 | if (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_test_flag(channel, CF_VIDEO)) { |
| 3118 | members_with_video++; |
| 3119 | |
| 3120 | if (switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE) && switch_test_flag(imember, MFLAG_VIDEO_BRIDGE)((imember)->flags & MFLAG_VIDEO_BRIDGE)) { |
| 3121 | if (!video_bridge_members[0]) { |
| 3122 | video_bridge_members[0] = imember; |
| 3123 | } else { |
| 3124 | video_bridge_members[1] = imember; |
| 3125 | } |
| 3126 | } |
| 3127 | } |
| 3128 | |
| 3129 | if (switch_test_flag(imember, MFLAG_NOMOH)((imember)->flags & MFLAG_NOMOH)) { |
| 3130 | nomoh++; |
| 3131 | } |
| 3132 | } |
| 3133 | |
| 3134 | switch_clear_flag_locked(imember, MFLAG_HAS_AUDIO)switch_mutex_lock(imember->flag_mutex); (imember)->flags &= ~(MFLAG_HAS_AUDIO); switch_mutex_unlock(imember->flag_mutex );; |
| 3135 | switch_mutex_lock(imember->audio_in_mutex); |
| 3136 | |
| 3137 | if (switch_buffer_inuse(imember->audio_buffer) >= bytes |
| 3138 | && (buf_read = (uint32_t) switch_buffer_read(imember->audio_buffer, imember->frame, bytes))) { |
| 3139 | imember->read = buf_read; |
| 3140 | switch_set_flag_locked(imember, MFLAG_HAS_AUDIO)((imember->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail ("imember->flag_mutex != ((void*)0)", "mod_conference.c", 3140, __PRETTY_FUNCTION__));switch_mutex_lock(imember->flag_mutex );(imember)->flags |= (MFLAG_HAS_AUDIO);switch_mutex_unlock (imember->flag_mutex);; |
| 3141 | ready++; |
| 3142 | } |
| 3143 | switch_mutex_unlock(imember->audio_in_mutex); |
| 3144 | } |
| 3145 | |
| 3146 | if (floor_holder != conference->floor_holder) { |
| 3147 | conference_set_floor_holder(conference, floor_holder); |
| 3148 | } |
| 3149 | |
| 3150 | if (conference->perpetual_sound && !conference->async_fnode) { |
| 3151 | conference_play_file(conference, conference->perpetual_sound, CONF_DEFAULT_LEADIN20, NULL((void*)0), 1); |
| 3152 | } else if (conference->moh_sound && ((nomoh == 0 && conference->count == 1) |
| 3153 | || switch_test_flag(conference, CFLAG_WAIT_MOD)((conference)->flags & CFLAG_WAIT_MOD)) && !conference->async_fnode && !conference->fnode) { |
| 3154 | conference_play_file(conference, conference->moh_sound, CONF_DEFAULT_LEADIN20, NULL((void*)0), 1); |
| 3155 | } |
| 3156 | |
| 3157 | |
| 3158 | /* Find if no one talked for more than x number of second */ |
| 3159 | if (conference->terminate_on_silence && conference->count > 1) { |
| 3160 | int is_talking = 0; |
| 3161 | |
| 3162 | for (imember = conference->members; imember; imember = imember->next) { |
| 3163 | if (switch_epoch_time_now(NULL((void*)0)) - imember->join_time <= conference->terminate_on_silence) { |
| 3164 | is_talking++; |
| 3165 | } else if (imember->last_talking != 0 && switch_epoch_time_now(NULL((void*)0)) - imember->last_talking <= conference->terminate_on_silence) { |
| 3166 | is_talking++; |
| 3167 | } |
| 3168 | } |
| 3169 | if (is_talking == 0) { |
| 3170 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3170, ((void*)0), SWITCH_LOG_DEBUG, "Conference has been idle for over %d seconds, terminating\n", conference->terminate_on_silence); |
| 3171 | switch_set_flag(conference, CFLAG_DESTRUCT)(conference)->flags |= (CFLAG_DESTRUCT); |
| 3172 | } |
| 3173 | } |
| 3174 | |
| 3175 | /* Start auto recording if there's the minimum number of required participants. */ |
| 3176 | if (conference->auto_record && !conference->auto_recording && (conference->count >= conference->min_recording_participants)) { |
| 3177 | conference->auto_recording++; |
| 3178 | conference->record_count++; |
| 3179 | imember = conference->members; |
| 3180 | if (imember) { |
| 3181 | switch_channel_t *channel = switch_core_session_get_channel(imember->session); |
| 3182 | char *rfile = switch_channel_expand_variables(channel, conference->auto_record)switch_channel_expand_variables_check(channel, conference-> auto_record, ((void*)0), ((void*)0), 0); |
| 3183 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3183, ((void*)0), SWITCH_LOG_DEBUG, "Auto recording file: %s\n", rfile); |
| 3184 | launch_conference_record_thread(conference, rfile, SWITCH_TRUE); |
| 3185 | |
| 3186 | if (rfile != conference->auto_record) { |
| 3187 | conference->record_filename = switch_core_strdup(conference->pool, rfile)switch_core_perform_strdup(conference->pool, rfile, "mod_conference.c" , (const char *)__func__, 3187); |
| 3188 | switch_safe_free(rfile)if (rfile) {free(rfile);rfile=((void*)0);}; |
| 3189 | } else { |
| 3190 | conference->record_filename = switch_core_strdup(conference->pool, conference->auto_record)switch_core_perform_strdup(conference->pool, conference-> auto_record, "mod_conference.c", (const char *)__func__, 3190 ); |
| 3191 | } |
| 3192 | /* Set the conference recording variable for each member */ |
| 3193 | for (omember = conference->members; omember; omember = omember->next) { |
| 3194 | if (!omember->session) continue; |
| 3195 | channel = switch_core_session_get_channel(omember->session); |
| 3196 | switch_channel_set_variable(channel, "conference_recording", conference->record_filename)switch_channel_set_variable_var_check(channel, "conference_recording" , conference->record_filename, SWITCH_TRUE); |
| 3197 | } |
| 3198 | } else { |
| 3199 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_conference.c", (const char *)__func__ , 3199, ((void*)0), SWITCH_LOG_ERROR, "Auto Record Failed. No members in conference.\n"); |
| 3200 | } |
| 3201 | } |
| 3202 | |
| 3203 | |
| 3204 | if (members_with_video) { |
| 3205 | if (conference->video_running != 1) { |
| 3206 | if (!switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)((conference)->flags & CFLAG_VIDEO_BRIDGE)) { |
| 3207 | launch_conference_video_thread(conference); |
| 3208 | } |
| 3209 | } |
| 3210 | |
| 3211 | if (conference->vh[0].up == 0 && |
| 3212 | conference->vh[1].up == 0 && |
| 3213 | video_bridge_members[0] && |
| 3214 | video_bridge_members[1] && |
| 3215 | switch_test_flag(video_bridge_members[0], MFLAG_RUNNING)((video_bridge_members[0])->flags & MFLAG_RUNNING) && |
| 3216 | switch_test_flag(video_bridge_members[1], MFLAG_RUNNING)((video_bridge_members[1])->flags & MFLAG_RUNNING) && |
| 3217 | switch_channel_ready(switch_core_session_get_channel(video_bridge_members[0]->session))switch_channel_test_ready(switch_core_session_get_channel(video_bridge_members [0]->session), SWITCH_TRUE, SWITCH_FALSE) && |
| 3218 | switch_channel_ready(switch_core_session_get_channel(video_bridge_members[1]->session))switch_channel_test_ready(switch_core_session_get_channel(video_bridge_members [1]->session), SWITCH_TRUE, SWITCH_FALSE) |
| 3219 | ) { |
| 3220 | conference->mh.up = 2; |
| 3221 | if (launch_conference_video_bridge_thread(video_bridge_members[0], video_bridge_members[1])) { |
| 3222 | conference->mh.up = 1; |
| 3223 | } else { |
| 3224 | conference->mh.up = -1; |
| 3225 | } |
| 3226 | } |
| 3227 | } |
| 3228 | |
| 3229 | /* If a file or speech event is being played */ |
| 3230 | if (conference->fnode && !switch_test_flag(conference->fnode, NFLAG_PAUSE)((conference->fnode)->flags & NFLAG_PAUSE)) { |
| 3231 | /* Lead in time */ |
| 3232 | if (conference->fnode->leadin) { |
| 3233 | conference->fnode->leadin--; |
| 3234 | } else if (!conference->fnode->done) { |
| 3235 | file_sample_len = samples; |
| 3236 | |
| 3237 | if (conference->fnode->type == NODE_TYPE_SPEECH) { |
| 3238 | switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_BLOCKING; |
| 3239 | switch_size_t speech_len = file_data_len; |
| 3240 | |
| 3241 | if (conference->fnode->al) { |
| 3242 | speech_len /= 2; |
| 3243 | } |
| 3244 | |
| 3245 | if (switch_core_speech_read_tts(conference->fnode->sh, file_frame, &speech_len, &flags) == SWITCH_STATUS_SUCCESS) { |
| 3246 | |
| 3247 | if (conference->fnode->al) { |
| 3248 | process_al(conference->fnode->al, file_frame, speech_len, conference->rate); |
| 3249 | } |
| 3250 | |
| 3251 | file_sample_len = file_data_len / 2 / conference->fnode->sh->channels; |
| 3252 | |
| 3253 | |
| 3254 | } else { |
| 3255 | file_sample_len = file_data_len = 0; |
| 3256 | } |
| 3257 | } else if (conference->fnode->type == NODE_TYPE_FILE) { |
| 3258 | switch_core_file_read(&conference->fnode->fh, file_frame, &file_sample_len); |
| 3259 | if (conference->fnode->fh.vol) { |
| 3260 | switch_change_sln_volume_granular((void *)file_frame, (uint32_t)file_sample_len * conference->fnode->fh.channels, |
| 3261 | conference->fnode->fh.vol); |
| 3262 | } |
| 3263 | if (conference->fnode->al) { |
| 3264 | process_al(conference->fnode->al, file_frame, file_sample_len * 2, conference->fnode->fh.samplerate); |
| 3265 | } |
| 3266 | } |
| 3267 | |
| 3268 | if (file_sample_len <= 0) { |
| 3269 | conference->fnode->done++; |
| 3270 | } else { |
| 3271 | has_file_data = 1; |
| 3272 | } |
| 3273 | } |
| 3274 | } |
| 3275 | |
| 3276 | if (conference->async_fnode) { |
| 3277 | /* Lead in time */ |
| 3278 | if (conference->async_fnode->leadin) { |
| 3279 | conference->async_fnode->leadin--; |
| 3280 | } else if (!conference->async_fnode->done) { |
| 3281 | file_sample_len = samples; |
| 3282 | switch_core_file_read(&conference->async_fnode->fh, async_file_frame, &file_sample_len); |
| 3283 | if (conference->async_fnode->al) { |
| 3284 | process_al(conference->async_fnode->al, file_frame, file_sample_len * 2, conference->async_fnode->fh.samplerate); |
| 3285 | } |
| 3286 | if (file_sample_len <= 0) { |
| 3287 | conference->async_fnode->done++; |
| 3288 | } else { |
| 3289 | if (has_file_data) { |
| 3290 | switch_size_t x; |
| 3291 | for (x = 0; x < file_sample_len * conference->channels; x++) { |
| 3292 | int32_t z; |
| 3293 | int16_t *muxed; |
| 3294 | |
| 3295 | muxed = (int16_t *) file_frame; |
| 3296 | bptr = (int16_t *) async_file_frame; |
| 3297 | z = muxed[x] + bptr[x]; |
| 3298 | switch_normalize_to_16bit(z)if (z > 32767) z = 32767; else if (z < -32768) z = -32768 ;; |
| 3299 | muxed[x] = (int16_t) z; |
| 3300 | } |
| 3301 | } else { |
| 3302 | memcpy(file_frame, async_file_frame, file_sample_len * 2 * conference->channels); |
| 3303 | has_file_data = 1; |
| 3304 | } |
| 3305 | } |
| 3306 | } |
| 3307 | } |
| 3308 | |
| 3309 | if (ready || has_file_data) { |
| 3310 | /* Use more bits in the main_frame to preserve the exact sum of the audio samples. */ |
| 3311 | int main_frame[SWITCH_RECOMMENDED_BUFFER_SIZE8192] = { 0 }; |
| 3312 | int16_t write_frame[SWITCH_RECOMMENDED_BUFFER_SIZE8192] = { 0 }; |
| 3313 | |
| 3314 | |
| 3315 | /* Init the main frame with file data if there is any. */ |
| 3316 | bptr = (int16_t *) file_frame; |
| 3317 | if (has_file_data && file_sample_len) { |
| 3318 | |
| 3319 | for (x = 0; x < bytes / 2; x++) { |
| 3320 | if (x <= file_sample_len * conference->channels) { |
| 3321 | main_frame[x] = (int32_t) bptr[x]; |
| 3322 | } else { |
| 3323 | memset(&main_frame[x], 255, sizeof(main_frame[x])); |
| 3324 | } |
| 3325 | } |
| 3326 | } |
| 3327 | |
| 3328 | member_score_sum = 0; |
| 3329 | conference->mux_loop_count = 0; |
| 3330 | conference->member_loop_count = 0; |
| 3331 | |
| 3332 | |
| 3333 | /* Copy audio from every member known to be producing audio into the main frame. */ |
| 3334 | for (omember = conference->members; omember; omember = omember->next) { |
| 3335 | conference->member_loop_count++; |
| 3336 | |
| 3337 | if (!(switch_test_flag(omember, MFLAG_RUNNING)((omember)->flags & MFLAG_RUNNING) && switch_test_flag(omember, MFLAG_HAS_AUDIO)((omember)->flags & MFLAG_HAS_AUDIO))) { |
| 3338 | continue; |
| 3339 | } |
| 3340 | |
| 3341 | if (conference->agc_level) { |
| 3342 | if (switch_test_flag(omember, MFLAG_TALKING)((omember)->flags & MFLAG_TALKING) && switch_test_flag(omember, MFLAG_CAN_SPEAK)((omember)->flags & MFLAG_CAN_SPEAK)) { |
| 3343 | member_score_sum += omember->score; |
| 3344 | conference->mux_loop_count++; |
| 3345 | } |
| 3346 | } |
| 3347 | |
| 3348 | bptr = (int16_t *) omember->frame; |
| 3349 | for (x = 0; x < omember->read / 2; x++) { |
| 3350 | main_frame[x] += (int32_t) bptr[x]; |
| 3351 | } |
| 3352 | } |
| 3353 | |
| 3354 | if (conference->agc_level && conference->member_loop_count) { |
| 3355 | conf_energy = 0; |
| 3356 | |
| 3357 | for (x = 0; x < bytes / 2; x++) { |
| 3358 | z = abs(main_frame[x]); |
| 3359 | switch_normalize_to_16bit(z)if (z > 32767) z = 32767; else if (z < -32768) z = -32768 ;; |
| 3360 | conf_energy += (int16_t) z; |
| 3361 | } |
| 3362 | |
| 3363 | conference->score = conf_energy / ((bytes / 2) / divisor) / conference->member_loop_count; |
| 3364 | |
| 3365 | conference->avg_tally += conference->score; |
| 3366 | conference->avg_score = conference->avg_tally / ++conference->avg_itt; |
| 3367 | if (!conference->avg_itt) conference->avg_tally = conference->score; |
| 3368 | } |
| 3369 | |
| 3370 | /* Create write frame once per member who is not deaf for each sample in the main frame |
| 3371 | check if our audio is involved and if so, subtract it from the sample so we don't hear ourselves. |
| 3372 | Since main frame was 32 bit int, we did not lose any detail, now that we have to convert to 16 bit we can |
| 3373 | cut it off at the min and max range if need be and write the frame to the output buffer. |
| 3374 | */ |
| 3375 | for (omember = conference->members; omember; omember = omember->next) { |
| 3376 | switch_size_t ok = 1; |
| 3377 | |
| 3378 | if (!switch_test_flag(omember, MFLAG_RUNNING)((omember)->flags & MFLAG_RUNNING)) { |
| 3379 | continue; |
| 3380 | } |
| 3381 | |
| 3382 | if (!switch_test_flag(omember, MFLAG_CAN_HEAR)((omember)->flags & MFLAG_CAN_HEAR)) { |
| 3383 | switch_mutex_lock(omember->audio_out_mutex); |
| 3384 | memset(write_frame, 255, bytes); |
| 3385 | ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes); |
Value stored to 'ok' is never read | |
| 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 | */ |