nopin"},
-};
-
-#define CONFFUNCAPISIZE (sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0]))
-
-switch_status_t conf_api_dispatch(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv, const char *cmdline, int argn)
-{
- switch_status_t status = SWITCH_STATUS_FALSE;
- uint32_t i, found = 0;
- switch_assert(conference != NULL);
- switch_assert(stream != NULL);
-
- /* loop through the command table to find a match */
- for (i = 0; i < CONFFUNCAPISIZE && !found; i++) {
- if (strcasecmp(argv[argn], conf_api_sub_commands[i].pname) == 0) {
- found = 1;
- switch (conf_api_sub_commands[i].fntype) {
-
- /* commands that we've broken the command line into arguments for */
- case CONF_API_SUB_ARGS_SPLIT:
- {
- conf_api_args_cmd_t pfn = (conf_api_args_cmd_t) conf_api_sub_commands[i].pfnapicmd;
-
- if (pfn(conference, stream, argc, argv) != SWITCH_STATUS_SUCCESS) {
- /* command returned error, so show syntax usage */
- stream->write_function(stream, conf_api_sub_commands[i].psyntax);
- }
- }
- break;
-
- /* member specific command that can be itteratted */
- case CONF_API_SUB_MEMBER_TARGET:
- {
- uint32_t id = 0;
- uint8_t all = 0;
- uint8_t last = 0;
-
- if (argv[argn + 1]) {
- if (!(id = atoi(argv[argn + 1]))) {
- all = strcasecmp(argv[argn + 1], "all") ? 0 : 1;
- last = strcasecmp(argv[argn + 1], "last") ? 0 : 1;
- }
- }
-
- if (all) {
- conference_member_itterator(conference, stream, (conf_api_member_cmd_t) conf_api_sub_commands[i].pfnapicmd, argv[argn + 2]);
- } else if (last) {
- conference_member_t *member = NULL;
- conference_member_t *last_member = NULL;
-
- switch_mutex_lock(conference->member_mutex);
-
- /* find last (oldest) member */
- member = conference->members;
- while (member != NULL) {
- if (last_member == NULL || member->id > last_member->id) {
- last_member = member;
- }
- member = member->next;
- }
-
- /* exec functio on last (oldest) member */
- if (last_member != NULL && last_member->session && !switch_test_flag(last_member, MFLAG_NOCHANNEL)) {
- conf_api_member_cmd_t pfn = (conf_api_member_cmd_t) conf_api_sub_commands[i].pfnapicmd;
- pfn(last_member, stream, argv[argn + 2]);
- }
-
- switch_mutex_unlock(conference->member_mutex);
- } else if (id) {
- conf_api_member_cmd_t pfn = (conf_api_member_cmd_t) conf_api_sub_commands[i].pfnapicmd;
- conference_member_t *member = conference_member_get(conference, id);
-
- if (member != NULL) {
- pfn(member, stream, argv[argn + 2]);
- } else {
- stream->write_function(stream, "Non-Existant ID %u\n", id);
- }
- } else {
- stream->write_function(stream, conf_api_sub_commands[i].psyntax);
- }
- }
- break;
-
- /* commands that deals with all text after command */
- case CONF_API_SUB_ARGS_AS_ONE:
- {
- conf_api_text_cmd_t pfn = (conf_api_text_cmd_t) conf_api_sub_commands[i].pfnapicmd;
- char *start_text;
- const char *modified_cmdline = cmdline;
- const char *cmd = conf_api_sub_commands[i].pname;
-
- if (!zstr(modified_cmdline) && (start_text = strstr(modified_cmdline, cmd))) {
- modified_cmdline = start_text + strlen(cmd);
- while (modified_cmdline && (*modified_cmdline == ' ' || *modified_cmdline == '\t')) {
- modified_cmdline++;
- }
- }
-
- /* call the command handler */
- if (pfn(conference, stream, modified_cmdline) != SWITCH_STATUS_SUCCESS) {
- /* command returned error, so show syntax usage */
- stream->write_function(stream, conf_api_sub_commands[i].psyntax);
- }
- }
- break;
- }
- }
- }
-
- if (!found) {
- stream->write_function(stream, "Confernece command '%s' not found.\n", argv[argn]);
- } else {
- status = SWITCH_STATUS_SUCCESS;
- }
-
- return status;
-}
-
-/* API Interface Function */
-SWITCH_STANDARD_API(conf_api_main)
-{
- char *lbuf = NULL;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- char *http = NULL, *type = NULL;
- int argc;
- char *argv[25] = { 0 };
-
- if (!cmd) {
- cmd = "help";
- }
-
- if (stream->param_event) {
- http = switch_event_get_header(stream->param_event, "http-host");
- type = switch_event_get_header(stream->param_event, "content-type");
- }
-
- if (http) {
- /* Output must be to a web browser */
- if (type && !strcasecmp(type, "text/html")) {
- stream->write_function(stream, "\n");
- }
- }
-
- if (!(lbuf = strdup(cmd))) {
- return status;
- }
-
- argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
-
- /* try to find a command to execute */
- if (argc && argv[0]) {
- conference_obj_t *conference = NULL;
-
- if ((conference = conference_find(argv[0]))) {
- if (switch_thread_rwlock_tryrdlock(conference->rwlock) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Read Lock Fail\n");
- goto done;
- }
- if (argc >= 2) {
- conf_api_dispatch(conference, stream, argc, argv, cmd, 1);
- } else {
- stream->write_function(stream, "Conference command, not specified.\nTry 'help'\n");
- }
- switch_thread_rwlock_unlock(conference->rwlock);
-
- } else if (argv[0]) {
- /* special case the list command, because it doesn't require a conference argument */
- if (strcasecmp(argv[0], "list") == 0) {
- conf_api_sub_list(NULL, stream, argc, argv);
- } else if (strcasecmp(argv[0], "xml_list") == 0) {
- conf_api_sub_xml_list(NULL, stream, argc, argv);
- } else if (strcasecmp(argv[0], "help") == 0 || strcasecmp(argv[0], "commands") == 0) {
- stream->write_function(stream, "%s\n", api_syntax);
- } else if (argv[1] && strcasecmp(argv[1], "dial") == 0) {
- if (conf_api_sub_dial(NULL, stream, argc, argv) != SWITCH_STATUS_SUCCESS) {
- /* command returned error, so show syntax usage */
- stream->write_function(stream, conf_api_sub_commands[CONF_API_COMMAND_DIAL].psyntax);
- }
- } else if (argv[1] && strcasecmp(argv[1], "bgdial") == 0) {
- if (conf_api_sub_bgdial(NULL, stream, argc, argv) != SWITCH_STATUS_SUCCESS) {
- /* command returned error, so show syntax usage */
- stream->write_function(stream, conf_api_sub_commands[CONF_API_COMMAND_BGDIAL].psyntax);
- }
- } else {
- stream->write_function(stream, "Conference %s not found\n", argv[0]);
- }
- }
-
- } else {
- stream->write_function(stream, "No parameters specified.\nTry 'help conference'\n");
- }
-
- done:
- switch_safe_free(lbuf);
-
- return status;
-}
-
-/* generate an outbound call from the conference */
-static switch_status_t conference_outcall(conference_obj_t *conference,
- char *conference_name,
- switch_core_session_t *session,
- char *bridgeto, uint32_t timeout, char *flags, char *cid_name, char *cid_num, switch_call_cause_t *cause)
-{
- switch_core_session_t *peer_session = NULL;
- switch_channel_t *peer_channel;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- switch_channel_t *caller_channel = NULL;
- char appdata[512];
- int rdlock = 0;
-
- *cause = SWITCH_CAUSE_NORMAL_CLEARING;
-
- if (conference == NULL) {
- char *dialstr = switch_mprintf("{ignore_early_media=true}%s", bridgeto);
- status = switch_ivr_originate(NULL, &peer_session, cause, dialstr, 60, NULL, cid_name, cid_num, NULL, NULL, SOF_NONE, NULL);
- switch_safe_free(dialstr);
-
- if (status != SWITCH_STATUS_SUCCESS) {
- return status;
- }
-
- peer_channel = switch_core_session_get_channel(peer_session);
- rdlock = 1;
- goto callup;
- }
-
- conference_name = conference->name;
-
- if (switch_thread_rwlock_tryrdlock(conference->rwlock) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Read Lock Fail\n");
- return SWITCH_STATUS_FALSE;
- }
-
- if (session != NULL) {
- caller_channel = switch_core_session_get_channel(session);
- }
-
- if (zstr(cid_name)) {
- cid_name = conference->caller_id_name;
- }
-
- if (zstr(cid_num)) {
- cid_num = conference->caller_id_number;
- }
-
- /* establish an outbound call leg */
-
- if (switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, NULL, SOF_NONE, NULL) !=
- SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create outgoing channel, cause: %s\n",
- switch_channel_cause2str(*cause));
- if (caller_channel) {
- switch_channel_hangup(caller_channel, *cause);
- }
- goto done;
- }
-
- rdlock = 1;
- peer_channel = switch_core_session_get_channel(peer_session);
- switch_channel_set_state(peer_channel, CS_SOFT_EXECUTE);
-
- /* make sure the conference still exists */
- if (!switch_test_flag(conference, CFLAG_RUNNING)) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Conference is gone now, nevermind..\n");
- if (caller_channel) {
- switch_channel_hangup(caller_channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION);
- }
- switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ROUTE_DESTINATION);
- goto done;
- }
-
- if (caller_channel && switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
- switch_channel_answer(caller_channel);
- }
-
- callup:
-
- /* if the outbound call leg is ready */
- if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
- switch_caller_extension_t *extension = NULL;
-
- /* build an extension name object */
- if ((extension = switch_caller_extension_new(peer_session, conference_name, conference_name)) == 0) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n");
- status = SWITCH_STATUS_MEMERR;
- goto done;
- }
- /* add them to the conference */
- if (flags && strcasecmp(flags, "none")) {
- switch_snprintf(appdata, sizeof(appdata), "%s+flags{%s}", conference_name, flags);
- switch_caller_extension_add_application(peer_session, extension, (char *) global_app_name, appdata);
- } else {
- switch_caller_extension_add_application(peer_session, extension, (char *) global_app_name, conference_name);
- }
-
- switch_channel_set_caller_extension(peer_channel, extension);
- switch_channel_set_state(peer_channel, CS_EXECUTE);
-
- } else {
- switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ANSWER);
- status = SWITCH_STATUS_FALSE;
- goto done;
- }
-
- done:
- if (conference) {
- switch_thread_rwlock_unlock(conference->rwlock);
- }
- if (rdlock && peer_session) {
- switch_core_session_rwunlock(peer_session);
- }
-
- return status;
-}
-
-struct bg_call {
- conference_obj_t *conference;
- switch_core_session_t *session;
- char *bridgeto;
- uint32_t timeout;
- char *flags;
- char *cid_name;
- char *cid_num;
- char *conference_name;
- char *uuid;
- switch_memory_pool_t *pool;
-};
-
-static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread, void *obj)
-{
- struct bg_call *call = (struct bg_call *) obj;
-
- if (call) {
- switch_call_cause_t cause;
- switch_event_t *event;
-
- conference_outcall(call->conference, call->conference_name,
- call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, &cause);
-
- if (call->conference && test_eflag(call->conference, EFLAG_BGDIAL_RESULT) &&
- switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
- conference_add_event_data(call->conference, event);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "bgdial-result");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Result", switch_channel_cause2str(cause));
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-UUID", call->uuid);
- switch_event_fire(&event);
- }
- switch_safe_free(call->bridgeto);
- switch_safe_free(call->flags);
- switch_safe_free(call->cid_name);
- switch_safe_free(call->cid_num);
- switch_safe_free(call->conference_name);
- switch_safe_free(call->uuid);
- if (call->pool) {
- switch_core_destroy_memory_pool(&call->pool);
- }
- switch_safe_free(call);
- }
-
- return NULL;
-}
-
-static switch_status_t conference_outcall_bg(conference_obj_t *conference,
- char *conference_name,
- switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name,
- const char *cid_num, const char *call_uuid)
-{
- struct bg_call *call = NULL;
- switch_thread_t *thread;
- switch_threadattr_t *thd_attr = NULL;
- switch_memory_pool_t *pool = NULL;
-
- if (!(call = malloc(sizeof(*call))))
- return SWITCH_STATUS_MEMERR;
-
- memset(call, 0, sizeof(*call));
- call->conference = conference;
- call->session = session;
- call->timeout = timeout;
-
- if (conference) {
- pool = conference->pool;
- } else {
- switch_core_new_memory_pool(&pool);
- call->pool = pool;
- }
-
- if (bridgeto) {
- call->bridgeto = strdup(bridgeto);
- }
- if (flags) {
- call->flags = strdup(flags);
- }
- if (cid_name) {
- call->cid_name = strdup(cid_name);
- }
- if (cid_num) {
- call->cid_num = strdup(cid_num);
- }
-
- if (conference_name) {
- call->conference_name = strdup(conference_name);
- }
-
- if (call_uuid) {
- call->uuid = strdup(call_uuid);
- }
-
- switch_threadattr_create(&thd_attr, pool);
- switch_threadattr_detach_set(thd_attr, 1);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_thread_create(&thread, thd_attr, conference_outcall_run, call, pool);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Launching BG Thread for outcall\n");
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-/* Play a file */
-static switch_status_t conference_local_play_file(conference_obj_t *conference, switch_core_session_t *session, char *path, uint32_t leadin, void *buf,
- uint32_t buflen)
-{
- uint32_t x = 0;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- switch_channel_t *channel;
- char *expanded = NULL;
- switch_input_args_t args = { 0 }, *ap = NULL;
-
- if (buf) {
- args.buf = buf;
- args.buflen = buflen;
- ap = &args;
- }
-
- /* generate some space infront of the file to be played */
- for (x = 0; x < leadin; x++) {
- switch_frame_t *read_frame;
- status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
-
- if (!SWITCH_READ_ACCEPTABLE(status)) {
- break;
- }
- }
-
- /* if all is well, really play the file */
- if (status == SWITCH_STATUS_SUCCESS) {
- char *dpath = NULL;
-
- channel = switch_core_session_get_channel(session);
- if ((expanded = switch_channel_expand_variables(channel, path)) != path) {
- path = expanded;
- } else {
- expanded = NULL;
- }
-
- if (!strncasecmp(path, "say:", 4)) {
- if (!(conference->tts_engine && conference->tts_voice)) {
- status = SWITCH_STATUS_FALSE;
- } else {
- status = switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, path + 4, ap);
- }
- goto done;
- }
-
- if (conference->sound_prefix) {
- if (!(dpath = switch_mprintf("%s%s%s", conference->sound_prefix, SWITCH_PATH_SEPARATOR, path))) {
- status = SWITCH_STATUS_MEMERR;
- goto done;
- }
- path = dpath;
- }
-
- status = switch_ivr_play_file(session, NULL, path, ap);
- switch_safe_free(dpath);
- }
-
- done:
- switch_safe_free(expanded);
-
- return status;
-}
-
-static void set_mflags(const char *flags, member_flag_t *f)
-{
- if (flags) {
- char *dup = strdup(flags);
- char *p;
- char *argv[10] = { 0 };
- int i, argc = 0;
-
- for (p = dup; p && *p; p++) {
- if (*p == ',') {
- *p = '|';
- }
- }
-
- argc = switch_separate_string(dup, '|', argv, (sizeof(argv) / sizeof(argv[0])));
-
- for (i = 0; i < argc && argv[i]; i++) {
- if (!strcasecmp(argv[i], "mute")) {
- *f &= ~MFLAG_CAN_SPEAK;
- } else if (!strcasecmp(argv[i], "deaf")) {
- *f &= ~MFLAG_CAN_HEAR;
- } else if (!strcasecmp(argv[i], "waste")) {
- *f |= MFLAG_WASTE_BANDWIDTH;
- } else if (!strcasecmp(argv[i], "mute-detect")) {
- *f |= MFLAG_MUTE_DETECT;
- } else if (!strcasecmp(argv[i], "dist-dtmf")) {
- *f |= MFLAG_DIST_DTMF;
- } else if (!strcasecmp(argv[i], "moderator")) {
- *f |= MFLAG_MOD;
- } else if (!strcasecmp(argv[i], "endconf")) {
- *f |= MFLAG_ENDCONF;
- } else if (!strcasecmp(argv[i], "mintwo")) {
- *f |= MFLAG_MINTWO;
- }
- }
-
- free(dup);
- }
-}
-
-
-
-static void set_cflags(const char *flags, uint32_t *f)
-{
- if (flags) {
- char *dup = strdup(flags);
- char *p;
- char *argv[10] = { 0 };
- int i, argc = 0;
-
- for (p = dup; p && *p; p++) {
- if (*p == ',') {
- *p = '|';
- }
- }
-
- argc = switch_separate_string(dup, '|', argv, (sizeof(argv) / sizeof(argv[0])));
-
- for (i = 0; i < argc && argv[i]; i++) {
- if (!strcasecmp(argv[i], "wait-mod")) {
- *f |= CFLAG_WAIT_MOD;
- } else if (!strcasecmp(argv[i], "video-floor-only")) {
- *f |= CFLAG_VID_FLOOR;
- } else if (!strcasecmp(argv[i], "waste-bandwidth")) {
- *f |= CFLAG_WASTE_BANDWIDTH;
- }
- }
-
- free(dup);
- }
-}
-
-
-static void clear_eflags(char *events, uint32_t *f)
-{
- char buf[512] = "";
- char *next = NULL;
- char *event = buf;
-
- if (events) {
- switch_copy_string(buf, events, sizeof(buf));
-
- while (event) {
- next = strchr(event, ',');
- if (next) {
- *next++ = '\0';
- }
-
- if (!strcmp(event, "add-member")) {
- *f &= ~EFLAG_ADD_MEMBER;
- } else if (!strcmp(event, "del-member")) {
- *f &= ~EFLAG_DEL_MEMBER;
- } else if (!strcmp(event, "energy-level")) {
- *f &= ~EFLAG_ENERGY_LEVEL;
- } else if (!strcmp(event, "volume-level")) {
- *f &= ~EFLAG_VOLUME_LEVEL;
- } else if (!strcmp(event, "gain-level")) {
- *f &= ~EFLAG_GAIN_LEVEL;
- } else if (!strcmp(event, "dtmf")) {
- *f &= ~EFLAG_DTMF;
- } else if (!strcmp(event, "stop-talking")) {
- *f &= ~EFLAG_STOP_TALKING;
- } else if (!strcmp(event, "start-talking")) {
- *f &= ~EFLAG_START_TALKING;
- } else if (!strcmp(event, "mute-detect")) {
- *f &= ~EFLAG_MUTE_DETECT;
- } else if (!strcmp(event, "mute-member")) {
- *f &= ~EFLAG_MUTE_MEMBER;
- } else if (!strcmp(event, "unmute-member")) {
- *f &= ~EFLAG_UNMUTE_MEMBER;
- } else if (!strcmp(event, "kick-member")) {
- *f &= ~EFLAG_KICK_MEMBER;
- } else if (!strcmp(event, "dtmf-member")) {
- *f &= ~EFLAG_DTMF_MEMBER;
- } else if (!strcmp(event, "energy-level-member")) {
- *f &= ~EFLAG_ENERGY_LEVEL_MEMBER;
- } else if (!strcmp(event, "volume-in-member")) {
- *f &= ~EFLAG_VOLUME_IN_MEMBER;
- } else if (!strcmp(event, "volume-out-member")) {
- *f &= ~EFLAG_VOLUME_OUT_MEMBER;
- } else if (!strcmp(event, "play-file")) {
- *f &= ~EFLAG_PLAY_FILE;
- } else if (!strcmp(event, "play-file-member")) {
- *f &= ~EFLAG_PLAY_FILE_MEMBER;
- } else if (!strcmp(event, "speak-text")) {
- *f &= ~EFLAG_SPEAK_TEXT;
- } else if (!strcmp(event, "speak-text-member")) {
- *f &= ~EFLAG_SPEAK_TEXT_MEMBER;
- } else if (!strcmp(event, "lock")) {
- *f &= ~EFLAG_LOCK;
- } else if (!strcmp(event, "unlock")) {
- *f &= ~EFLAG_UNLOCK;
- } else if (!strcmp(event, "transfer")) {
- *f &= ~EFLAG_TRANSFER;
- } else if (!strcmp(event, "bgdial-result")) {
- *f &= ~EFLAG_BGDIAL_RESULT;
- } else if (!strcmp(event, "floor-change")) {
- *f &= ~EFLAG_FLOOR_CHANGE;
- }
-
- event = next;
- }
- }
-}
-
-SWITCH_STANDARD_APP(conference_auto_function)
-{
- switch_channel_t *channel = switch_core_session_get_channel(session);
- call_list_t *call_list, *np;
-
- call_list = switch_channel_get_private(channel, "_conference_autocall_list_");
-
- if (zstr(data)) {
- call_list = NULL;
- } else {
- np = switch_core_session_alloc(session, sizeof(*np));
- switch_assert(np != NULL);
-
- np->string = switch_core_session_strdup(session, data);
- if (call_list) {
- np->next = call_list;
- np->itteration = call_list->itteration + 1;
- } else {
- np->itteration = 1;
- }
- call_list = np;
- }
- switch_channel_set_private(channel, "_conference_autocall_list_", call_list);
-}
-
-
-static int setup_media(conference_member_t *member, conference_obj_t *conference)
-{
- switch_codec_implementation_t read_impl = { 0 };
- switch_core_session_get_read_impl(member->session, &read_impl);
-
- switch_core_session_reset(member->session, SWITCH_TRUE, SWITCH_FALSE);
-
- if (switch_core_codec_ready(&member->read_codec)) {
- switch_core_codec_destroy(&member->read_codec);
- }
-
- if (member->read_resampler) {
- switch_resample_destroy(&member->read_resampler);
- }
-
-
- switch_core_session_get_read_impl(member->session, &member->orig_read_impl);
- member->native_rate = read_impl.samples_per_second;
-
- /* Setup a Signed Linear codec for reading audio. */
- if (switch_core_codec_init(&member->read_codec,
- "L16",
- NULL, read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000,
- 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member->pool) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG,
- "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
- read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000);
-
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n",
- read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000);
-
- goto done;
- }
-
- if (!member->frame_size) {
- member->frame_size = SWITCH_RECOMMENDED_BUFFER_SIZE;
- member->frame = switch_core_alloc(member->pool, member->frame_size);
- member->mux_frame = switch_core_alloc(member->pool, member->frame_size);
- }
-
- if (read_impl.actual_samples_per_second != conference->rate) {
- if (switch_resample_create(&member->read_resampler,
- read_impl.actual_samples_per_second,
- conference->rate, member->frame_size, SWITCH_RESAMPLE_QUALITY, 1) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_CRIT, "Unable to create resampler!\n");
- goto done;
- }
-
-
- member->resample_out = switch_core_alloc(member->pool, member->frame_size);
- member->resample_out_len = member->frame_size;
-
- /* Setup an audio buffer for the resampled audio */
- if (switch_buffer_create_dynamic(&member->resample_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX)
- != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n");
- goto done;
- }
- }
-
-
- /* Setup a Signed Linear codec for writing audio. */
- if (switch_core_codec_init(&member->write_codec,
- "L16",
- NULL,
- conference->rate,
- read_impl.microseconds_per_packet / 1000,
- 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member->pool) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG,
- "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", conference->rate, read_impl.microseconds_per_packet / 1000);
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n",
- conference->rate, read_impl.microseconds_per_packet / 1000);
- goto codec_done2;
- }
-
- /* Setup an audio buffer for the incoming audio */
- if (switch_buffer_create_dynamic(&member->audio_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n");
- goto codec_done1;
- }
-
- /* Setup an audio buffer for the outgoing audio */
- if (switch_buffer_create_dynamic(&member->mux_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n");
- goto codec_done1;
- }
-
- return 0;
-
- codec_done1:
- switch_core_codec_destroy(&member->read_codec);
- codec_done2:
- switch_core_codec_destroy(&member->write_codec);
- done:
-
- return -1;
-
-
-}
-
-
-/* Application interface function that is called from the dialplan to join the channel to a conference */
-SWITCH_STANDARD_APP(conference_function)
-{
- switch_codec_t *read_codec = NULL;
- uint32_t flags = 0;
- conference_member_t member = { 0 };
- conference_obj_t *conference = NULL;
- switch_channel_t *channel = switch_core_session_get_channel(session);
- char *mydata = NULL;
- char *conf_name = NULL;
- char *bridge_prefix = "bridge:";
- char *flags_prefix = "+flags{";
- char *bridgeto = NULL;
- char *profile_name = NULL;
- switch_xml_t cxml = NULL, cfg = NULL, profiles = NULL;
- const char *flags_str;
- member_flag_t mflags = 0;
- switch_core_session_message_t msg = { 0 };
- uint8_t rl = 0, isbr = 0;
- char *dpin = NULL;
- conf_xml_cfg_t xml_cfg = { 0 };
- switch_event_t *params = NULL;
- int locked = 0;
-
- /* Save the original read codec. */
- if (!(read_codec = switch_core_session_get_read_codec(session))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Channel has no media!\n");
- return;
- }
-
-
- if (zstr(data)) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Invalid arguments\n");
- return;
- }
-
- mydata = switch_core_session_strdup(session, data);
-
- if (!mydata) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Pool Failure\n");
- return;
- }
-
- if ((flags_str = strstr(mydata, flags_prefix))) {
- char *p;
- *((char *) flags_str) = '\0';
- flags_str += strlen(flags_prefix);
- if ((p = strchr(flags_str, '}'))) {
- *p = '\0';
- }
- } else {
- flags_str = switch_channel_get_variable(channel, "conference_member_flags");
- }
-
- /* is this a bridging conference ? */
- if (!strncasecmp(mydata, bridge_prefix, strlen(bridge_prefix))) {
- isbr = 1;
- mydata += strlen(bridge_prefix);
- if ((bridgeto = strchr(mydata, ':'))) {
- *bridgeto++ = '\0';
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Config Error!\n");
- goto done;
- }
- }
-
- conf_name = mydata;
-
- /* eat all leading spaces on conference name, which can cause problems */
- while (*conf_name == ' ') {
- conf_name++;
- }
-
- /* is there a conference pin ? */
- if ((dpin = strchr(conf_name, '+'))) {
- *dpin++ = '\0';
- }
-
- /* is there profile specification ? */
- if ((profile_name = strchr(conf_name, '@'))) {
- *profile_name++ = '\0';
- } else {
- profile_name = "default";
- }
-
-#if 0
- if (0) {
- member.dtmf_parser = conference->dtmf_parser;
- } else {
-
- }
-#endif
-
- switch_event_create(¶ms, SWITCH_EVENT_COMMAND);
- switch_assert(params);
- switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conf_name", conf_name);
- switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile_name", profile_name);
-
- /* Open the config from the xml registry */
- if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, params))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf_name);
- goto done;
- }
-
- if ((profiles = switch_xml_child(cfg, "profiles"))) {
- xml_cfg.profile = switch_xml_find_child(profiles, "profile", "name", profile_name);
- }
-
- xml_cfg.controls = switch_xml_child(cfg, "caller-controls");
-
- /* if this is a bridging call, and it's not a duplicate, build a */
- /* conference object, and skip pin handling, and locked checking */
-
- if (!locked) {
- switch_mutex_lock(globals.setup_mutex);
- locked = 1;
- }
-
- if (isbr) {
- char *uuid = switch_core_session_get_uuid(session);
-
- if (!strcmp(conf_name, "_uuid_")) {
- conf_name = uuid;
- }
-
- if ((conference = conference_find(conf_name))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Conference %s already exists!\n", conf_name);
- goto done;
- }
-
- /* Create the conference object. */
- conference = conference_new(conf_name, xml_cfg, NULL);
-
- if (!conference) {
- goto done;
- }
-
- if (locked) {
- switch_mutex_unlock(globals.setup_mutex);
- locked = 0;
- }
-
- switch_channel_set_variable(channel, "conference_name", conference->name);
-
- /* Set the minimum number of members (once you go above it you cannot go below it) */
- conference->min = 2;
-
- /* Indicate the conference is dynamic */
- switch_set_flag_locked(conference, CFLAG_DYNAMIC);
-
- /* Indicate the conference has a bridgeto party */
- switch_set_flag_locked(conference, CFLAG_BRIDGE_TO);
-
- /* Start the conference thread for this conference */
- launch_conference_thread(conference);
-
- } else {
- int enforce_security = !switch_channel_test_flag(channel, CF_OUTBOUND);
- const char *pvar = switch_channel_get_variable(channel, "conference_enforce_security");
-
- if (pvar) {
- enforce_security = switch_true(pvar);
- }
-
- if ((conference = conference_find(conf_name))) {
- if (locked) {
- switch_mutex_unlock(globals.setup_mutex);
- locked = 0;
- }
- }
-
- /* if the conference exists, get the pointer to it */
- if (!conference) {
- const char *max_members_str;
-
- /* couldn't find the conference, create one */
- conference = conference_new(conf_name, xml_cfg, NULL);
-
- if (!conference) {
- goto done;
- }
-
- if (locked) {
- switch_mutex_unlock(globals.setup_mutex);
- locked = 0;
- }
-
- switch_channel_set_variable(channel, "conference_name", conference->name);
-
- /* Set MOH from variable if not set */
- if (zstr(conference->moh_sound)) {
- conference->moh_sound = switch_core_strdup(conference->pool, switch_channel_get_variable(channel, "conference_moh_sound"));
- }
- /* Set perpetual-sound from variable if not set */
- if (zstr(conference->perpetual_sound)) {
- conference->perpetual_sound = switch_core_strdup(conference->pool, switch_channel_get_variable(channel, "conference_perpetual_sound"));
- }
-
- /* Set the minimum number of members (once you go above it you cannot go below it) */
- conference->min = 1;
-
- /* check for variable used to specify override for max_members */
- if (!zstr(max_members_str = switch_channel_get_variable(channel, "conference_max_members"))) {
- uint32_t max_members_val;
- errno = 0; /* sanity first */
- max_members_val = strtol(max_members_str, NULL, 0); /* base 0 lets 0x... for hex 0... for octal and base 10 otherwise through */
- if (errno == ERANGE || errno == EINVAL || max_members_val < 0 || max_members_val == 1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
- "conference_max_members variable %s is invalid, not setting a limit\n", max_members_str);
- } else {
- conference->max_members = max_members_val;
- }
- }
-
- /* Indicate the conference is dynamic */
- switch_set_flag_locked(conference, CFLAG_DYNAMIC);
-
- /* Start the conference thread for this conference */
- launch_conference_thread(conference);
- } else { /* setup user variable */
- switch_channel_set_variable(channel, "conference_name", conference->name);
- }
-
- /* acquire a read lock on the thread so it can't leave without us */
- if (switch_thread_rwlock_tryrdlock(conference->rwlock) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Read Lock Fail\n");
- goto done;
- }
- rl++;
-
- if (!dpin && conference->pin) {
- dpin = conference->pin;
- }
-
-
-
- /* if this is not an outbound call, deal with conference pins */
- if (enforce_security && !zstr(dpin)) {
- char pin_buf[80] = "";
- int pin_retries = 3; /* XXX - this should be configurable - i'm too lazy to do it right now... */
- int pin_valid = 0;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- char *supplied_pin_value;
-
- /* Answer the channel */
- switch_channel_answer(channel);
-
- /* look for PIN in channel variable first. If not present or invalid revert to prompting user */
- supplied_pin_value = switch_core_strdup(conference->pool, switch_channel_get_variable(channel, "supplied_pin"));
- if (!zstr(supplied_pin_value)) {
- char *supplied_pin_value_start;
- int i = 0;
- if ((supplied_pin_value_start = (char *) switch_stristr(cf_pin_url_param_name, supplied_pin_value))) {
- /* pin supplied as a URL parameter, move pointer to start of actual pin value */
- supplied_pin_value = supplied_pin_value_start + strlen(cf_pin_url_param_name);
- }
- while (*supplied_pin_value != 0 && *supplied_pin_value != ';') {
- pin_buf[i++] = *supplied_pin_value++;
- }
- pin_valid = (strcmp(pin_buf, dpin) == 0);
- memset(pin_buf, 0, sizeof(pin_buf));
- }
-
- if (!conference->pin_sound) {
- conference->pin_sound = switch_core_strdup(conference->pool, "conference/conf-pin.wav");
- }
-
- if (!conference->bad_pin_sound) {
- conference->bad_pin_sound = switch_core_strdup(conference->pool, "conference/conf-bad-pin.wav");
- }
-
- while (!pin_valid && pin_retries && status == SWITCH_STATUS_SUCCESS) {
- switch_status_t pstatus = SWITCH_STATUS_FALSE;
-
- /* be friendly */
- if (conference->pin_sound) {
- pstatus = conference_local_play_file(conference, session, conference->pin_sound, 20, pin_buf, sizeof(pin_buf));
- } else if (conference->tts_engine && conference->tts_voice) {
- pstatus =
- switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, "please enter the conference pin number", NULL);
- } else {
- pstatus = switch_ivr_speak_text(session, "flite", "slt", "please enter the conference pin number", NULL);
- }
-
- if (pstatus != SWITCH_STATUS_SUCCESS && pstatus != SWITCH_STATUS_BREAK) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot ask the user for a pin, ending call");
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- }
-
- /* wait for them if neccessary */
- if (strlen(pin_buf) < strlen(dpin)) {
- char *buf = pin_buf + strlen(pin_buf);
- char term = '\0';
-
- status = switch_ivr_collect_digits_count(session,
- buf,
- sizeof(pin_buf) - strlen(pin_buf), strlen(dpin) - strlen(pin_buf), "#", &term, 10000, 0, 0);
- if (status == SWITCH_STATUS_TIMEOUT) {
- status = SWITCH_STATUS_SUCCESS;
- }
- }
-
- pin_valid = (status == SWITCH_STATUS_SUCCESS && strcmp(pin_buf, dpin) == 0);
- if (!pin_valid) {
- /* zero the collected pin */
- memset(pin_buf, 0, sizeof(pin_buf));
-
- /* more friendliness */
- if (conference->bad_pin_sound) {
- conference_local_play_file(conference, session, conference->bad_pin_sound, 20, pin_buf, sizeof(pin_buf));
- }
- }
- pin_retries--;
- }
-
- if (!pin_valid) {
- goto done;
- }
- }
-
- if (conference->special_announce) {
- conference_local_play_file(conference, session, conference->special_announce, CONF_DEFAULT_LEADIN, NULL, 0);
- }
-
- /* don't allow more callers if the conference is locked, unless we invited them */
- if (switch_test_flag(conference, CFLAG_LOCKED) && enforce_security) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Conference %s is locked.\n", conf_name);
- if (conference->locked_sound) {
- /* Answer the channel */
- switch_channel_answer(channel);
- conference_local_play_file(conference, session, conference->locked_sound, 20, NULL, 0);
- }
- goto done;
- }
-
- /* dont allow more callers than the max_members allows for -- I explicitly didnt allow outbound calls
- * someone else can add that (see above) if they feel that outbound calls should be able to violate the
- * max_members limit
- */
- if ((conference->max_members > 0) && (conference->count >= conference->max_members)) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Conference %s is full.\n", conf_name);
- if (conference->maxmember_sound) {
- /* Answer the channel */
- switch_channel_answer(channel);
- conference_local_play_file(conference, session, conference->maxmember_sound, 20, NULL, 0);
- }
- goto done;
- }
-
- }
-
- /* Release the config registry handle */
- if (cxml) {
- switch_xml_free(cxml);
- cxml = NULL;
- }
-
- /* if we're using "bridge:" make an outbound call and bridge it in */
- if (!zstr(bridgeto) && strcasecmp(bridgeto, "none")) {
- switch_call_cause_t cause;
- if (conference_outcall(conference, NULL, session, bridgeto, 60, NULL, NULL, NULL, &cause) != SWITCH_STATUS_SUCCESS) {
- goto done;
- }
- } else {
- /* if we're not using "bridge:" set the conference answered flag */
- /* and this isn't an outbound channel, answer the call */
- if (!switch_channel_test_flag(channel, CF_OUTBOUND))
- switch_set_flag(conference, CFLAG_ANSWERED);
- }
-
- member.session = session;
- member.pool = switch_core_session_get_pool(session);
-
- if (setup_media(&member, conference)) {
- flags = 0;
- goto done;
- }
-
- /* Prepare MUTEXS */
- member.id = next_member_id();
- switch_mutex_init(&member.flag_mutex, SWITCH_MUTEX_NESTED, member.pool);
- switch_mutex_init(&member.write_mutex, SWITCH_MUTEX_NESTED, member.pool);
- switch_mutex_init(&member.read_mutex, SWITCH_MUTEX_NESTED, member.pool);
- switch_mutex_init(&member.audio_in_mutex, SWITCH_MUTEX_NESTED, member.pool);
- switch_mutex_init(&member.audio_out_mutex, SWITCH_MUTEX_NESTED, member.pool);
-
- /* Install our Signed Linear codec so we get the audio in that format */
- switch_core_session_set_read_codec(member.session, &member.read_codec);
-
-
- mflags = conference->mflags;
- set_mflags(flags_str, &mflags);
- switch_set_flag_locked((&member), MFLAG_RUNNING | mflags);
-
- if (mflags & MFLAG_MINTWO) {
- conference->min = 2;
- }
-
- /* Add the caller to the conference */
- if (conference_add_member(conference, &member) != SWITCH_STATUS_SUCCESS) {
- switch_core_codec_destroy(&member.read_codec);
- goto done;
- }
-
- msg.from = __FILE__;
-
- /* Tell the channel we are going to be in a bridge */
- msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
- switch_core_session_receive_message(session, &msg);
-
- /* Run the confernece loop */
- conference_loop_output(&member);
- switch_channel_set_private(channel, "_conference_autocall_list_", NULL);
-
- /* Tell the channel we are no longer going to be in a bridge */
- msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
- switch_core_session_receive_message(session, &msg);
-
- /* Remove the caller from the conference */
- conference_del_member(member.conference, &member);
-
- /* Put the original codec back */
- switch_core_session_set_read_codec(member.session, NULL);
-
- /* Clean Up. */
-
- done:
-
- if (locked) {
- switch_mutex_unlock(globals.setup_mutex);
- locked = 0;
- }
-
- if (member.read_resampler) {
- switch_resample_destroy(&member.read_resampler);
- }
-
- switch_event_destroy(¶ms);
- switch_buffer_destroy(&member.resample_buffer);
- switch_buffer_destroy(&member.audio_buffer);
- switch_buffer_destroy(&member.mux_buffer);
- if (conference && member.dtmf_parser != conference->dtmf_parser) {
- switch_ivr_digit_stream_parser_destroy(member.dtmf_parser);
- }
-
- if (conference) {
- switch_mutex_lock(conference->mutex);
- if (switch_test_flag(conference, CFLAG_DYNAMIC) && conference->count == 0) {
- switch_set_flag_locked(conference, CFLAG_DESTRUCT);
- }
- switch_mutex_unlock(conference->mutex);
- }
-
- /* Release the config registry handle */
- if (cxml) {
- switch_xml_free(cxml);
- }
-
- if (conference && switch_test_flag(&member, MFLAG_KICKED) && conference->kicked_sound) {
- char *toplay = NULL;
- char *dfile = NULL;
-
- if (!strncasecmp(conference->kicked_sound, "say:", 4)) {
- if (conference->tts_engine && conference->tts_voice) {
- switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, conference->kicked_sound + 4, NULL);
- }
- } else {
- if (conference->sound_prefix) {
- dfile = switch_mprintf("%s%s%s", conference->sound_prefix, SWITCH_PATH_SEPARATOR, conference->kicked_sound);
- switch_assert(dfile);
- toplay = dfile;
- } else {
- toplay = conference->kicked_sound;
- }
-
- switch_ivr_play_file(session, NULL, toplay, NULL);
- switch_safe_free(dfile);
- }
- }
-
- switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
-
- /* release the readlock */
- if (rl) {
- switch_thread_rwlock_unlock(conference->rwlock);
- }
-}
-
-/* Create a thread for the conference and launch it */
-static void launch_conference_thread(conference_obj_t *conference)
-{
- switch_thread_t *thread;
- switch_threadattr_t *thd_attr = NULL;
-
- switch_set_flag_locked(conference, CFLAG_RUNNING);
- switch_threadattr_create(&thd_attr, conference->pool);
- switch_threadattr_detach_set(thd_attr, 1);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_mutex_lock(globals.hash_mutex);
- switch_mutex_unlock(globals.hash_mutex);
- switch_thread_create(&thread, thd_attr, conference_thread_run, conference, conference->pool);
-}
-
-
-/* Create a video thread for the conference and launch it */
-static void launch_conference_video_thread(conference_obj_t *conference)
-{
- switch_thread_t *thread;
- switch_threadattr_t *thd_attr = NULL;
-
- switch_threadattr_create(&thd_attr, conference->pool);
- switch_threadattr_detach_set(thd_attr, 1);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_thread_create(&thread, thd_attr, conference_video_thread_run, conference, conference->pool);
- conference->video_running = 1;
-}
-
-static void launch_conference_record_thread(conference_obj_t *conference, char *path)
-{
- switch_thread_t *thread;
- switch_threadattr_t *thd_attr = NULL;
- switch_memory_pool_t *pool;
- conference_record_t *rec;
-
- /* Setup a memory pool to use. */
- if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
- }
-
- /* Create a node object */
- if (!(rec = switch_core_alloc(pool, sizeof(*rec)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Alloc Failure\n");
- switch_core_destroy_memory_pool(&pool);
- return;
- }
-
- rec->conference = conference;
- rec->path = switch_core_strdup(pool, path);
- rec->pool = pool;
-
- switch_threadattr_create(&thd_attr, rec->pool);
- switch_threadattr_detach_set(thd_attr, 1);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_thread_create(&thread, thd_attr, conference_record_thread_run, rec, rec->pool);
-}
-
-static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject,
- const char *body, const char *type, const char *hint)
-{
- char name[512] = "", *p, *lbuf = NULL;
- conference_obj_t *conference = NULL;
- switch_stream_handle_t stream = { 0 };
-
- if ((p = strchr(to, '+'))) {
- to = ++p;
- }
-
- if (!body) {
- return SWITCH_STATUS_SUCCESS;
- }
-
- if ((p = strchr(to, '@'))) {
- switch_copy_string(name, to, ++p - to);
- } else {
- switch_copy_string(name, to, sizeof(name));
- }
-
- if (!(conference = conference_find(name))) {
- switch_core_chat_send(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", "Conference not active.", NULL, NULL);
- return SWITCH_STATUS_FALSE;
- }
-
- SWITCH_STANDARD_STREAM(stream);
-
- if (body != NULL && (lbuf = strdup(body))) {
- /* special case list */
- if (switch_stristr("list", lbuf)) {
- conference_list_pretty(conference, &stream);
- /* provide help */
- } else {
- return SWITCH_STATUS_SUCCESS;
- }
- }
-
- switch_safe_free(lbuf);
-
- switch_core_chat_send(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", stream.data, NULL, NULL);
- switch_safe_free(stream.data);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t conf_default_controls(conference_obj_t *conference)
-{
- switch_status_t status = SWITCH_STATUS_FALSE;
- uint32_t i;
- caller_control_action_t *action;
-
- switch_assert(conference != NULL);
-
- for (i = 0, status = SWITCH_STATUS_SUCCESS; status == SWITCH_STATUS_SUCCESS && i < CCFNTBL_QTY; i++) {
- if (!zstr(ccfntbl[i].digits)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
- "Installing default caller control action '%s' bound to '%s'.\n", ccfntbl[i].key, ccfntbl[i].digits);
- action = (caller_control_action_t *) switch_core_alloc(conference->pool, sizeof(caller_control_action_t));
- if (action != NULL) {
- action->fndesc = &ccfntbl[i];
- action->data = NULL;
- status = switch_ivr_digit_stream_parser_set_event(conference->dtmf_parser, ccfntbl[i].digits, action);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
- "unable to alloc memory for caller control binding '%s' to '%s'\n", ccfntbl[i].key, ccfntbl[i].digits);
- status = SWITCH_STATUS_MEMERR;
- }
- }
- }
-
- return status;
-}
-
-static switch_status_t conference_new_install_caller_controls_custom(conference_obj_t *conference, switch_xml_t xml_controls, switch_xml_t xml_menus)
-{
- switch_status_t status = SWITCH_STATUS_FALSE;
- switch_xml_t xml_kvp;
-
- switch_assert(conference != NULL);
-
- if (!xml_controls) {
- return status;
- }
-
- /* parse the controls tree for caller control digit strings */
- for (xml_kvp = switch_xml_child(xml_controls, "control"); xml_kvp; xml_kvp = xml_kvp->next) {
- char *key = (char *) switch_xml_attr(xml_kvp, "action");
- char *val = (char *) switch_xml_attr(xml_kvp, "digits");
- char *data = (char *) switch_xml_attr_soft(xml_kvp, "data");
-
- if (!zstr(key) && !zstr(val)) {
- uint32_t i;
-
- /* scan through all of the valid actions, and if found, */
- /* set the new caller control action digit string, then */
- /* stop scanning the table, and go to the next xml kvp. */
- for (i = 0, status = SWITCH_STATUS_NOOP; i < CCFNTBL_QTY && status == SWITCH_STATUS_NOOP; i++) {
-
- if (strcasecmp(ccfntbl[i].key, key) == 0) {
-
- caller_control_action_t *action;
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Installing caller control action '%s' bound to '%s'.\n", key, val);
- action = (caller_control_action_t *) switch_core_alloc(conference->pool, sizeof(caller_control_action_t));
- if (action != NULL) {
- action->fndesc = &ccfntbl[i];
- action->data = (void *) switch_core_strdup(conference->pool, data);
- action->binded_dtmf = switch_core_strdup(conference->pool, val);
- status = switch_ivr_digit_stream_parser_set_event(conference->dtmf_parser, val, action);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
- "unable to alloc memory for caller control binding '%s' to '%s'\n", ccfntbl[i].key, ccfntbl[i].digits);
- status = SWITCH_STATUS_MEMERR;
- }
- }
- }
- if (status == SWITCH_STATUS_NOOP) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid caller control action name '%s'.\n", key);
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid caller control config entry pair action = '%s' digits = '%s'\n", key, val);
- }
- }
-
- return status;
-}
-
-static conference_obj_t *conference_find(char *name)
-{
- conference_obj_t *conference;
-
- switch_mutex_lock(globals.hash_mutex);
- conference = switch_core_hash_find(globals.conference_hash, name);
- switch_mutex_unlock(globals.hash_mutex);
-
- return conference;
-}
-
-/* create a new conferene with a specific profile */
-static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_memory_pool_t *pool)
-{
- conference_obj_t *conference;
- switch_xml_t xml_kvp;
- char *timer_name = NULL;
- char *domain = NULL;
- char *tts_engine = NULL;
- char *tts_voice = NULL;
- char *enter_sound = NULL;
- char *sound_prefix = NULL;
- char *exit_sound = NULL;
- char *alone_sound = NULL;
- char *ack_sound = NULL;
- char *nack_sound = NULL;
- char *muted_sound = NULL;
- char *mute_detect_sound = NULL;
- char *unmuted_sound = NULL;
- char *locked_sound = NULL;
- char *is_locked_sound = NULL;
- char *is_unlocked_sound = NULL;
- char *kicked_sound = NULL;
- char *pin = NULL;
- char *pin_sound = NULL;
- char *bad_pin_sound = NULL;
- char *energy_level = NULL;
- char *caller_id_name = NULL;
- char *caller_id_number = NULL;
- char *caller_controls = NULL;
- char *member_flags = NULL;
- char *conference_flags = NULL;
- char *perpetual_sound = NULL;
- char *moh_sound = NULL;
- uint32_t max_members = 0;
- uint32_t announce_count = 0;
- char *maxmember_sound = NULL;
- uint32_t rate = 8000, interval = 20;
- switch_status_t status;
- int comfort_noise_level = 0;
- char *suppress_events = NULL;
- char *verbose_events = NULL;
- char *auto_record = NULL;
-
- /* Validate the conference name */
- if (zstr(name)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Record! no name.\n");
- return NULL;
- }
-
- switch_mutex_lock(globals.hash_mutex);
-
- /* parse the profile tree for param values */
- if (cfg.profile)
- for (xml_kvp = switch_xml_child(cfg.profile, "param"); xml_kvp; xml_kvp = xml_kvp->next) {
- char *var = (char *) switch_xml_attr_soft(xml_kvp, "name");
- char *val = (char *) switch_xml_attr_soft(xml_kvp, "value");
- char buf[128] = "";
- char *p;
-
- if ((p = strchr(var, '_'))) {
- switch_copy_string(buf, var, sizeof(buf));
- for (p = buf; *p; p++) {
- if (*p == '_') {
- *p = '-';
- }
- }
- var = buf;
- }
-
- if (!strcasecmp(var, "rate") && !zstr(val)) {
- uint32_t tmp = atoi(val);
- if (tmp == 8000 || tmp == 12000 || tmp == 16000 || tmp == 24000 || tmp == 32000 || tmp == 48000) {
- rate = tmp;
- }
- } else if (!strcasecmp(var, "domain") && !zstr(val)) {
- domain = val;
- } else if (!strcasecmp(var, "interval") && !zstr(val)) {
- uint32_t tmp = atoi(val);
- if (SWITCH_ACCEPTABLE_INTERVAL(tmp)) {
- interval = tmp;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
- "Interval must be multipe of 10 and less than %d, Using default of 20\n", SWITCH_MAX_INTERVAL);
- }
- } else if (!strcasecmp(var, "timer-name") && !zstr(val)) {
- timer_name = val;
- } else if (!strcasecmp(var, "tts-engine") && !zstr(val)) {
- tts_engine = val;
- } else if (!strcasecmp(var, "tts-voice") && !zstr(val)) {
- tts_voice = val;
- } else if (!strcasecmp(var, "enter-sound") && !zstr(val)) {
- enter_sound = val;
- } else if (!strcasecmp(var, "exit-sound") && !zstr(val)) {
- exit_sound = val;
- } else if (!strcasecmp(var, "alone-sound") && !zstr(val)) {
- alone_sound = val;
- } else if (!strcasecmp(var, "perpetual-sound") && !zstr(val)) {
- perpetual_sound = val;
- } else if (!strcasecmp(var, "moh-sound") && !zstr(val)) {
- moh_sound = val;
- } else if (!strcasecmp(var, "ack-sound") && !zstr(val)) {
- ack_sound = val;
- } else if (!strcasecmp(var, "nack-sound") && !zstr(val)) {
- nack_sound = val;
- } else if (!strcasecmp(var, "muted-sound") && !zstr(val)) {
- muted_sound = val;
- } else if (!strcasecmp(var, "mute-detect-sound") && !zstr(val)) {
- mute_detect_sound = val;
- } else if (!strcasecmp(var, "unmuted-sound") && !zstr(val)) {
- unmuted_sound = val;
- } else if (!strcasecmp(var, "locked-sound") && !zstr(val)) {
- locked_sound = val;
- } else if (!strcasecmp(var, "is-locked-sound") && !zstr(val)) {
- is_locked_sound = val;
- } else if (!strcasecmp(var, "is-unlocked-sound") && !zstr(val)) {
- is_unlocked_sound = val;
- } else if (!strcasecmp(var, "member-flags") && !zstr(val)) {
- member_flags = val;
- } else if (!strcasecmp(var, "conference-flags") && !zstr(val)) {
- conference_flags = val;
- } else if (!strcasecmp(var, "kicked-sound") && !zstr(val)) {
- kicked_sound = val;
- } else if (!strcasecmp(var, "pin") && !zstr(val)) {
- pin = val;
- } else if (!strcasecmp(var, "pin-sound") && !zstr(val)) {
- pin_sound = val;
- } else if (!strcasecmp(var, "bad-pin-sound") && !zstr(val)) {
- bad_pin_sound = val;
- } else if (!strcasecmp(var, "energy-level") && !zstr(val)) {
- energy_level = val;
- } else if (!strcasecmp(var, "caller-id-name") && !zstr(val)) {
- caller_id_name = val;
- } else if (!strcasecmp(var, "caller-id-number") && !zstr(val)) {
- caller_id_number = val;
- } else if (!strcasecmp(var, "caller-controls") && !zstr(val)) {
- caller_controls = val;
- } else if (!strcasecmp(var, "comfort-noise") && !zstr(val)) {
- int tmp;
- tmp = atoi(val);
- if (tmp > 1 && tmp < 10000) {
- comfort_noise_level = tmp;
- } else if (switch_true(val)) {
- comfort_noise_level = 1400;
- }
- } else if (!strcasecmp(var, "sound-prefix") && !zstr(val)) {
- sound_prefix = val;
- } else if (!strcasecmp(var, "max-members") && !zstr(val)) {
- errno = 0; /* sanity first */
- max_members = strtol(val, NULL, 0); /* base 0 lets 0x... for hex 0... for octal and base 10 otherwise through */
- if (errno == ERANGE || errno == EINVAL || max_members < 0 || max_members == 1) {
- /* a negative wont work well, and its foolish to have a conference limited to 1 person unless the outbound
- * stuff is added, see comments above
- */
- max_members = 0; /* set to 0 to disable max counts */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-members %s is invalid, not setting a limit\n", val);
- }
- } else if (!strcasecmp(var, "max-members-sound") && !zstr(val)) {
- maxmember_sound = val;
- } else if (!strcasecmp(var, "announce-count") && !zstr(val)) {
- errno = 0; /* safety first */
- announce_count = strtol(val, NULL, 0);
- if (errno == ERANGE || errno == EINVAL) {
- announce_count = 0;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "announce-count is invalid, not anouncing member counts\n");
- }
- } else if (!strcasecmp(var, "suppress-events") && !zstr(val)) {
- suppress_events = val;
- } else if (!strcasecmp(var, "verbose-events") && !zstr(val)) {
- verbose_events = val;
- } else if (!strcasecmp(var, "auto-record") && !zstr(val)) {
- auto_record = val;
- }
- }
-
- /* Set defaults and various paramaters */
-
- /* Timer module to use */
- if (zstr(timer_name)) {
- timer_name = "soft";
- }
-
- /* Caller ID Name */
- if (zstr(caller_id_name)) {
- caller_id_name = (char *) global_app_name;
- }
-
- /* Caller ID Number */
- if (zstr(caller_id_number)) {
- caller_id_number = "0000000000";
- }
-
- if (!pool) {
- /* Setup a memory pool to use. */
- if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
- status = SWITCH_STATUS_TERM;
- conference = NULL;
- goto end;
- }
- }
-
- /* Create the conference object. */
- if (!(conference = switch_core_alloc(pool, sizeof(*conference)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- status = SWITCH_STATUS_TERM;
- conference = NULL;
- goto end;
- }
-
- /* initialize the conference object with settings from the specified profile */
- conference->pool = pool;
- conference->profile_name = switch_core_strdup(conference->pool, cfg.profile ? switch_xml_attr_soft(cfg.profile, "name") : "none");
- if (timer_name) {
- conference->timer_name = switch_core_strdup(conference->pool, timer_name);
- }
- if (tts_engine) {
- conference->tts_engine = switch_core_strdup(conference->pool, tts_engine);
- }
- if (tts_voice) {
- conference->tts_voice = switch_core_strdup(conference->pool, tts_voice);
- }
-
- conference->comfort_noise_level = comfort_noise_level;
- conference->caller_id_name = switch_core_strdup(conference->pool, caller_id_name);
- conference->caller_id_number = switch_core_strdup(conference->pool, caller_id_number);
-
-
- if (!zstr(perpetual_sound)) {
- conference->perpetual_sound = switch_core_strdup(conference->pool, perpetual_sound);
- }
-
- conference->mflags = MFLAG_CAN_SPEAK | MFLAG_CAN_HEAR;
-
- if (!zstr(moh_sound) && switch_is_moh(moh_sound)) {
- conference->moh_sound = switch_core_strdup(conference->pool, moh_sound);
- }
-
- if (member_flags) {
- set_mflags(member_flags, &conference->mflags);
- }
-
- if (conference_flags) {
- set_cflags(conference_flags, &conference->flags);
- }
-
- if (sound_prefix) {
- conference->sound_prefix = switch_core_strdup(conference->pool, sound_prefix);
- }
-
- if (!zstr(enter_sound)) {
- conference->enter_sound = switch_core_strdup(conference->pool, enter_sound);
- }
-
- if (!zstr(exit_sound)) {
- conference->exit_sound = switch_core_strdup(conference->pool, exit_sound);
- }
-
- if (!zstr(ack_sound)) {
- conference->ack_sound = switch_core_strdup(conference->pool, ack_sound);
- }
-
- if (!zstr(nack_sound)) {
- conference->nack_sound = switch_core_strdup(conference->pool, nack_sound);
- }
-
- if (!zstr(muted_sound)) {
- conference->muted_sound = switch_core_strdup(conference->pool, muted_sound);
- }
-
- if (zstr(mute_detect_sound)) {
- if (!zstr(muted_sound)) {
- conference->mute_detect_sound = switch_core_strdup(conference->pool, muted_sound);
- }
- } else {
- conference->mute_detect_sound = switch_core_strdup(conference->pool, mute_detect_sound);
- }
-
- if (!zstr(unmuted_sound)) {
- conference->unmuted_sound = switch_core_strdup(conference->pool, unmuted_sound);
- }
-
- if (!zstr(kicked_sound)) {
- conference->kicked_sound = switch_core_strdup(conference->pool, kicked_sound);
- }
-
- if (!zstr(pin_sound)) {
- conference->pin_sound = switch_core_strdup(conference->pool, pin_sound);
- }
-
- if (!zstr(bad_pin_sound)) {
- conference->bad_pin_sound = switch_core_strdup(conference->pool, bad_pin_sound);
- }
-
- if (!zstr(pin)) {
- conference->pin = switch_core_strdup(conference->pool, pin);
- }
-
- if (!zstr(alone_sound)) {
- conference->alone_sound = switch_core_strdup(conference->pool, alone_sound);
- }
-
- if (!zstr(locked_sound)) {
- conference->locked_sound = switch_core_strdup(conference->pool, locked_sound);
- }
-
- if (!zstr(is_locked_sound)) {
- conference->is_locked_sound = switch_core_strdup(conference->pool, is_locked_sound);
- }
-
- if (!zstr(is_unlocked_sound)) {
- conference->is_unlocked_sound = switch_core_strdup(conference->pool, is_unlocked_sound);
- }
-
- if (!zstr(energy_level)) {
- conference->energy_level = atoi(energy_level);
- }
-
- if (!zstr(maxmember_sound)) {
- conference->maxmember_sound = switch_core_strdup(conference->pool, maxmember_sound);
- }
- /* its going to be 0 by default, set to a value otherwise so this should be safe */
- conference->max_members = max_members;
- conference->announce_count = announce_count;
-
- conference->name = switch_core_strdup(conference->pool, name);
- if (domain) {
- conference->domain = switch_core_strdup(conference->pool, domain);
- } else {
- conference->domain = "cluecon.com";
- }
- conference->rate = rate;
- conference->interval = interval;
- conference->dtmf_parser = NULL;
-
- conference->eflags = 0xFFFFFFFF;
- if (!zstr(suppress_events)) {
- clear_eflags(suppress_events, &conference->eflags);
- }
-
- if (!zstr(auto_record)) {
- conference->auto_record = switch_core_strdup(conference->pool, auto_record);
- }
-
- if (!zstr(verbose_events) && switch_true(verbose_events)) {
- conference->verbose_events = 1;
- }
-
- /* caller control configuration chores */
- if (switch_ivr_digit_stream_parser_new(conference->pool, &conference->dtmf_parser) == SWITCH_STATUS_SUCCESS) {
-
- /* if no controls, or default controls specified, install default */
- if (caller_controls == NULL || *caller_controls == '\0' || strcasecmp(caller_controls, "default") == 0) {
- status = conf_default_controls(conference);
- } else if (strcasecmp(caller_controls, "none") != 0) {
- /* try to build caller control if the group has been specified and != "none" */
- switch_xml_t xml_controls = switch_xml_find_child(cfg.controls, "group", "name", caller_controls);
- status = conference_new_install_caller_controls_custom(conference, xml_controls, NULL);
-
- if (status != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to install caller controls group '%s'\n", caller_controls);
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "No caller controls installed.\n");
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate caller control digit parser.\n");
- }
-
- /* Activate the conference mutex for exclusivity */
- switch_mutex_init(&conference->mutex, SWITCH_MUTEX_NESTED, conference->pool);
- switch_mutex_init(&conference->flag_mutex, SWITCH_MUTEX_NESTED, conference->pool);
- switch_thread_rwlock_create(&conference->rwlock, conference->pool);
- switch_mutex_init(&conference->member_mutex, SWITCH_MUTEX_NESTED, conference->pool);
- switch_mutex_lock(globals.hash_mutex);
- switch_core_hash_insert(globals.conference_hash, conference->name, conference);
- switch_mutex_unlock(globals.hash_mutex);
-
- end:
-
- switch_mutex_unlock(globals.hash_mutex);
-
- return conference;
-}
-
-static void pres_event_handler(switch_event_t *event)
-{
- char *to = switch_event_get_header(event, "to");
- char *dup_to = NULL, *conf_name, *e;
- conference_obj_t *conference;
-
- if (!to || strncasecmp(to, "conf+", 5)) {
- return;
- }
-
- if (!(dup_to = strdup(to))) {
- return;
- }
-
- conf_name = dup_to + 5;
-
- if ((e = strchr(conf_name, '@'))) {
- *e = '\0';
- }
-
- if ((conference = conference_find(conf_name))) {
- if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", conference->name);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d caller%s)", conference->count, conference->count == 1 ? "" : "s");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", conf_name);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_ROUTING");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", conference->count == 1 ? "early" : "confirmed");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", conference->count == 1 ? "outbound" : "inbound");
- switch_event_fire(&event);
- }
- } else if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", conf_name);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", to);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Idle");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "idle");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", conf_name);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_HANGUP");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "terminated");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound");
- switch_event_fire(&event);
- }
-
- switch_safe_free(dup_to);
-}
-
-static void send_presence(switch_event_types_t id)
-{
- switch_xml_t cxml, cfg, advertise, room;
- switch_event_t *params = NULL;
-
- switch_event_create(¶ms, SWITCH_EVENT_COMMAND);
- switch_assert(params);
- switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "presence", "true");
-
-
- /* Open the config from the xml registry */
- if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, params))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf_name);
- goto done;
- }
-
- if ((advertise = switch_xml_child(cfg, "advertise"))) {
- for (room = switch_xml_child(advertise, "room"); room; room = room->next) {
- char *name = (char *) switch_xml_attr_soft(room, "name");
- char *status = (char *) switch_xml_attr_soft(room, "status");
- switch_event_t *event;
-
- if (name && switch_event_create(&event, id) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", name);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", name);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status ? status : "Available");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "idle");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
- switch_event_fire(&event);
- }
- }
- }
-
- done:
- switch_event_destroy(¶ms);
-
- /* Release the config registry handle */
- if (cxml) {
- switch_xml_free(cxml);
- cxml = NULL;
- }
-}
-
-/* Called by FreeSWITCH when the module loads */
-SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load)
-{
- uint32_t i;
- size_t nl, ol = 0;
- char *p = NULL, *tmp = NULL;
- switch_chat_interface_t *chat_interface;
- switch_api_interface_t *api_interface;
- switch_application_interface_t *app_interface;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
-
- memset(&globals, 0, sizeof(globals));
-
- /* Connect my internal structure to the blank pointer passed to me */
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
-
- /* build api interface help ".syntax" field string */
- p = strdup("");
- for (i = 0; i < CONFFUNCAPISIZE; i++) {
- nl = strlen(conf_api_sub_commands[i].psyntax) + 4;
- if (p != NULL) {
- ol = strlen(p);
- }
- tmp = realloc(p, ol + nl);
- if (tmp != NULL) {
- p = tmp;
- strcat(p, "\t\t");
- strcat(p, conf_api_sub_commands[i].psyntax);
- if (i < CONFFUNCAPISIZE - 1) {
- strcat(p, "\n");
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't realloc\n");
- return SWITCH_STATUS_TERM;
- }
-
- }
- api_syntax = p;
-
- /* create/register custom event message type */
- if (switch_event_reserve_subclass(CONF_EVENT_MAINT) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", CONF_EVENT_MAINT);
- return SWITCH_STATUS_TERM;
- }
-
- /* Setup the pool */
- globals.conference_pool = pool;
-
- /* Setup a hash to store conferences by name */
- switch_core_hash_init(&globals.conference_hash, globals.conference_pool);
- switch_mutex_init(&globals.conference_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool);
- switch_mutex_init(&globals.id_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool);
- switch_mutex_init(&globals.hash_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool);
- switch_mutex_init(&globals.setup_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool);
-
- /* Subscribe to presence request events */
- if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.node) !=
- SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't subscribe to presence request events!\n");
- return SWITCH_STATUS_GENERR;
- }
-
- SWITCH_ADD_API(api_interface, "conference", "Conference module commands", conf_api_main, p);
- SWITCH_ADD_APP(app_interface, global_app_name, global_app_name, NULL, conference_function, NULL, SAF_NONE);
- SWITCH_ADD_APP(app_interface, "conference_set_auto_outcall", "conference_set_auto_outcall", NULL, conference_auto_function, NULL, SAF_NONE);
- SWITCH_ADD_CHAT(chat_interface, CONF_CHAT_PROTO, chat_send);
-
- send_presence(SWITCH_EVENT_PRESENCE_IN);
-
- globals.running = 1;
- /* indicate that the module should continue to be loaded */
- return status;
-}
-
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_conference_shutdown)
-{
- if (globals.running) {
-
- /* signal all threads to shutdown */
- globals.running = 0;
-
- /* wait for all threads */
- while (globals.threads) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for %d threads\n", globals.threads);
- switch_yield(100000);
- }
-
- switch_event_unbind(&globals.node);
- switch_event_free_subclass(CONF_EVENT_MAINT);
-
- /* free api interface help ".syntax" field string */
- switch_safe_free(api_syntax);
- }
- switch_core_hash_destroy(&globals.conference_hash);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
- */
diff --git a/src/mod/applications/mod_conference/mod_conference.c.rej b/src/mod/applications/mod_conference/mod_conference.c.rej
deleted file mode 100644
index a9890b9dda..0000000000
--- a/src/mod/applications/mod_conference/mod_conference.c.rej
+++ /dev/null
@@ -1,50 +0,0 @@
-***************
-*** 3410,3420 ****
- }
- if (test_eflag(member->conference, EFLAG_VOLUME_IN_MEMBER) &&
- data && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
- conference_add_event_member_data(member, event);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-in-member");
-- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%u", member->volume_in_level);
- switch_event_fire(&event);
- }
-
- return SWITCH_STATUS_SUCCESS;
- }
---- 3410,3420 ----
- }
- if (test_eflag(member->conference, EFLAG_VOLUME_IN_MEMBER) &&
- data && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
- conference_add_event_member_data(member, event);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-in-member");
-+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%d", member->volume_in_level);
- switch_event_fire(&event);
- }
-
- return SWITCH_STATUS_SUCCESS;
- }
-***************
-*** 3437,3447 ****
- }
- if (test_eflag(member->conference, EFLAG_VOLUME_OUT_MEMBER) && data &&
- switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
- conference_add_event_member_data(member, event);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-out-member");
-- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%u", member->volume_out_level);
- switch_event_fire(&event);
- }
-
- return SWITCH_STATUS_SUCCESS;
- }
---- 3437,3447 ----
- }
- if (test_eflag(member->conference, EFLAG_VOLUME_OUT_MEMBER) && data &&
- switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
- conference_add_event_member_data(member, event);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-out-member");
-+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%d", member->volume_out_level);
- switch_event_fire(&event);
- }
-
- return SWITCH_STATUS_SUCCESS;
- }
diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c
index 6a494d8b11..616b423cb2 100755
--- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c
+++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c
@@ -50,10 +50,6 @@
#include
-/* Defaults */
-static char SQL_LOOKUP[] = "SELECT %s AS nibble_balance FROM %s WHERE %s='%s'";
-static char SQL_SAVE[] = "UPDATE %s SET %s=%s-%f WHERE %s='%s'";
-
typedef struct {
switch_time_t lastts; /* Last time we did any billing */
float total; /* Total amount billed so far */
@@ -300,7 +296,6 @@ static void transfer_call(switch_core_session_t *session, char *destination)
/* At this time, billing never succeeds if you don't have a database. */
static switch_status_t bill_event(float billamount, const char *billaccount, switch_channel_t *channel)
{
- switch_stream_handle_t sql_stream = { 0 };
char *sql = NULL, *dsql = NULL;
switch_odbc_statement_handle_t stmt = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
@@ -318,11 +313,9 @@ static switch_status_t bill_event(float billamount, const char *billaccount, swi
sql = globals.custom_sql_save;
}
} else {
- SWITCH_STANDARD_STREAM(sql_stream);
- sql_stream.write_function(&sql_stream, SQL_SAVE, globals.db_table, globals.db_column_cash,
- globals.db_column_cash, billamount, globals.db_column_account, billaccount);
-
- sql = (char *) sql_stream.data;
+ sql = dsql = switch_mprintf("UPDATE %s SET %s=%s-%f WHERE %s='%s'", globals.db_table, globals.db_column_cash,
+ globals.db_column_cash, billamount, globals.db_column_account, billaccount);
+
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing update query\n[%s]\n", sql);
@@ -339,23 +332,18 @@ static switch_status_t bill_event(float billamount, const char *billaccount, swi
}
switch_safe_free(dsql);
- switch_safe_free(sql_stream.data);
-
return status;
}
static float get_balance(const char *billaccount, switch_channel_t *channel)
{
- switch_stream_handle_t sql_stream = { 0 };
- char *sql = NULL;
+ char *dsql = NULL, *sql = NULL;
nibblebill_results_t pdata;
float balance = 0.00f;
- SWITCH_STANDARD_STREAM(sql_stream);
if (!switch_odbc_available()) {
- balance = -1.00f;
- goto end;
+ return -1.00f;
}
memset(&pdata, 0, sizeof(pdata));
@@ -363,13 +351,15 @@ static float get_balance(const char *billaccount, switch_channel_t *channel)
if (globals.custom_sql_lookup) {
if (switch_string_var_check_const(globals.custom_sql_lookup) || switch_string_has_escaped_data(globals.custom_sql_lookup)) {
sql = switch_channel_expand_variables(channel, globals.custom_sql_lookup);
+ if (sql != globals.custom_sql_lookup) dsql = sql;
} else {
sql = globals.custom_sql_lookup;
}
} else {
- sql_stream.write_function(&sql_stream, SQL_LOOKUP, globals.db_column_cash, globals.db_table, globals.db_column_account, billaccount);
- sql = sql_stream.data;
+ sql = dsql = switch_mprintf("SELECT %s AS nibble_balance FROM %s WHERE %s='%s'",
+ globals.db_column_cash, globals.db_table, globals.db_column_account, billaccount);
}
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doing lookup query\n[%s]\n", sql);
if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, nibblebill_callback, &pdata, NULL) != SWITCH_ODBC_SUCCESS) {
@@ -377,19 +367,13 @@ static float get_balance(const char *billaccount, switch_channel_t *channel)
/* Return -1 for safety */
balance = -1.00f;
- goto end;
} else {
/* Successfully retrieved! */
balance = pdata.balance;
-
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Retrieved current balance for account %s (balance = %f)\n", billaccount, balance);
}
-end:
- if (sql != globals.custom_sql_lookup && sql != sql_stream.data) {
- switch_safe_free(sql);
- }
- switch_safe_free(sql_stream.data);
+ switch_safe_free(dsql);
return balance;
}
diff --git a/src/mod/formats/mod_sndfile/mod_sndfile.c.orig b/src/mod/formats/mod_sndfile/mod_sndfile.c.orig
deleted file mode 100644
index 020943ce5a..0000000000
--- a/src/mod/formats/mod_sndfile/mod_sndfile.c.orig
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2010, Anthony Minessale II
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II
- *
- *
- * mod_sndfile.c -- Framework Demo Module
- *
- */
-#include
-#include
-
-SWITCH_MODULE_LOAD_FUNCTION(mod_sndfile_load);
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sndfile_shutdown);
-SWITCH_MODULE_DEFINITION(mod_sndfile, mod_sndfile_load, mod_sndfile_shutdown, NULL);
-
-static switch_memory_pool_t *module_pool = NULL;
-
-static struct {
- switch_hash_t *format_hash;
-} globals;
-
-struct format_map {
- char *ext;
- char *uext;
- uint32_t format;
-};
-
-struct sndfile_context {
- SF_INFO sfinfo;
- SNDFILE *handle;
-};
-
-typedef struct sndfile_context sndfile_context;
-
-static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const char *path)
-{
- sndfile_context *context;
- int mode = 0;
- char *ext;
- struct format_map *map = NULL;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- char *alt_path = NULL, *last, *ldup = NULL;
- size_t alt_len = 0;
- int rates[4] = { 8000, 16000, 32000, 48000 };
- int i;
-#ifdef WIN32
- char ps = '\\';
-#else
- char ps = '/';
-#endif
-
- if ((ext = strrchr(path, '.')) == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n");
- return SWITCH_STATUS_GENERR;
- }
- ext++;
-
- if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) {
- mode += SFM_READ;
- }
-
- if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
- if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND)) {
- mode += SFM_RDWR;
- } else {
- mode += SFM_WRITE;
- }
- }
-
- if (!mode) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Mode!\n");
- return SWITCH_STATUS_GENERR;
- }
-
- if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) {
- return SWITCH_STATUS_MEMERR;
- }
-
- map = switch_core_hash_find(globals.format_hash, ext);
-
- if (mode & SFM_WRITE) {
- context->sfinfo.channels = handle->channels;
- context->sfinfo.samplerate = handle->samplerate;
- if (handle->samplerate == 8000 || handle->samplerate == 16000 ||
- handle->samplerate == 24000 || handle->samplerate == 32000 || handle->samplerate == 48000 ||
- handle->samplerate == 11025 || handle->samplerate == 22050 || handle->samplerate == 44100) {
- context->sfinfo.format |= SF_FORMAT_PCM_16;
- }
- }
-
- if (map) {
- context->sfinfo.format |= map->format;
- }
-
- if (!strcmp(ext, "r8") || !strcmp(ext, "raw")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 8000;
- } else if (!strcmp(ext, "r16")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 16000;
- } else if (!strcmp(ext, "r24")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_24;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 24000;
- } else if (!strcmp(ext, "r32")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 32000;
- } else if (!strcmp(ext, "gsm")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_GSM610;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 8000;
- } else if (!strcmp(ext, "ul")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_ULAW;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 8000;
- } else if (!strcmp(ext, "al")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_ALAW;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 8000;
- } else if (!strcmp(ext, "adpcm")) {
- context->sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 8000;
- }
-
- if ((mode & SFM_WRITE) && sf_format_check(&context->sfinfo) == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error : file format is invalid (0x%08X).\n", context->sfinfo.format);
- return SWITCH_STATUS_GENERR;
- }
-
- alt_len = strlen(path) + 10;
- switch_zmalloc(alt_path, alt_len);
-
- switch_copy_string(alt_path, path, alt_len);
-
- /* This block attempts to add the sample rate to the path
- if the sample rate is already present in the path it does nothing
- and reverts to the original file name.
- */
- if ((last = strrchr(alt_path, ps))) {
- last++;
-#ifdef WIN32
- if (strrchr(last, '/')) {
- last = strrchr(alt_path, '/'); /* do not swallow a forward slash if they are intermixed under windows */
- last++;
- }
-#endif
- ldup = strdup(last);
- switch_assert(ldup);
- switch_snprintf(last, alt_len - (last - alt_path), "%d%s%s", handle->samplerate, SWITCH_PATH_SEPARATOR, ldup);
- if ((context->handle = sf_open(alt_path, mode, &context->sfinfo))) {
- path = alt_path;
- } else {
- /* Try to find the file at the highest rate possible if we can't find one that matches the exact rate.
- If we don't find any, we will default back to the original file name.
- */
- for (i = 3; i >= 0; i--) {
- switch_snprintf(last, alt_len - (last - alt_path), "%d%s%s", rates[i], SWITCH_PATH_SEPARATOR, ldup);
- if ((context->handle = sf_open(alt_path, mode, &context->sfinfo))) {
- path = alt_path;
- break;
- }
- }
- }
- }
-
- if (!context->handle) {
- if ((context->handle = sf_open(path, mode, &context->sfinfo)) == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening File [%s] [%s]\n", path, sf_strerror(context->handle));
- status = SWITCH_STATUS_GENERR;
- goto end;
- }
- }
- //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opening File [%s] rate %dhz\n", path, context->sfinfo.samplerate);
- handle->samples = (unsigned int) context->sfinfo.frames;
- handle->samplerate = context->sfinfo.samplerate;
- handle->channels = (uint8_t) context->sfinfo.channels;
- handle->format = context->sfinfo.format;
- handle->sections = context->sfinfo.sections;
- handle->seekable = context->sfinfo.seekable;
- handle->speed = 0;
- handle->private_info = context;
-
- if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND)) {
- handle->pos = sf_seek(context->handle, 0, SEEK_END);
- } else {
- sf_count_t frames = 0;
- sf_command(context->handle, SFC_FILE_TRUNCATE, &frames, sizeof(frames));
- }
-
-
- end:
-
- switch_safe_free(alt_path);
- switch_safe_free(ldup);
-
- return status;
-}
-
-static switch_status_t sndfile_file_truncate(switch_file_handle_t *handle, int64_t offset)
-{
- sndfile_context *context = handle->private_info;
- sf_command(context->handle, SFC_FILE_TRUNCATE, &offset, sizeof(offset));
- handle->pos = 0;
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t sndfile_file_close(switch_file_handle_t *handle)
-{
- sndfile_context *context = handle->private_info;
-
- sf_close(context->handle);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t sndfile_file_seek(switch_file_handle_t *handle, unsigned int *cur_sample, int64_t samples, int whence)
-{
- sndfile_context *context = handle->private_info;
-
- if (!handle->seekable) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File is not seekable\n");
- return SWITCH_STATUS_NOTIMPL;
- }
-
- *cur_sample = (unsigned int) sf_seek(context->handle, samples, whence);
- handle->pos = *cur_sample;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t sndfile_file_read(switch_file_handle_t *handle, void *data, size_t *len)
-{
- size_t inlen = *len;
- sndfile_context *context = handle->private_info;
-
- if (switch_test_flag(handle, SWITCH_FILE_DATA_RAW)) {
- *len = (size_t) sf_read_raw(context->handle, data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_INT)) {
- *len = (size_t) sf_readf_int(context->handle, (int *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_SHORT)) {
- *len = (size_t) sf_readf_short(context->handle, (short *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_FLOAT)) {
- *len = (size_t) sf_readf_float(context->handle, (float *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_DOUBLE)) {
- *len = (size_t) sf_readf_double(context->handle, (double *) data, inlen);
- } else {
- *len = (size_t) sf_readf_int(context->handle, (int *) data, inlen);
- }
-
- handle->pos += *len;
- handle->sample_count += *len;
-
- return *len ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
-}
-
-static switch_status_t sndfile_file_write(switch_file_handle_t *handle, void *data, size_t *len)
-{
- size_t inlen = *len;
- sndfile_context *context = handle->private_info;
-
- if (switch_test_flag(handle, SWITCH_FILE_DATA_RAW)) {
- *len = (size_t) sf_write_raw(context->handle, data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_INT)) {
- *len = (size_t) sf_writef_int(context->handle, (int *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_SHORT)) {
- *len = (size_t) sf_writef_short(context->handle, (short *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_FLOAT)) {
- *len = (size_t) sf_writef_float(context->handle, (float *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_DOUBLE)) {
- *len = (size_t) sf_writef_double(context->handle, (double *) data, inlen);
- } else {
- *len = (size_t) sf_writef_int(context->handle, (int *) data, inlen);
- }
-
- handle->sample_count += *len;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t sndfile_file_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string)
-{
- sndfile_context *context = handle->private_info;
-
- return sf_set_string(context->handle, (int) col, string) ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t sndfile_file_get_string(switch_file_handle_t *handle, switch_audio_col_t col, const char **string)
-{
- sndfile_context *context = handle->private_info;
- const char *s;
-
- if ((s = sf_get_string(context->handle, (int) col))) {
- *string = s;
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_FALSE;
-}
-
-/* Registration */
-
-static char **supported_formats;
-
-static switch_status_t setup_formats(void)
-{
- SF_FORMAT_INFO info;
- SF_INFO sfinfo;
- char buffer[128];
- int format, major_count, subtype_count, m, s;
- int len, x, skip;
- char *extras[] = { "r8", "r16", "r24", "r32", "gsm", "ul", "al", "adpcm", NULL };
- int exlen = (sizeof(extras) / sizeof(extras[0]));
- buffer[0] = 0;
-
- sf_command(NULL, SFC_GET_LIB_VERSION, buffer, sizeof(buffer));
- if (strlen(buffer) < 1) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Line %d: could not retrieve lib version.\n", __LINE__);
- return SWITCH_STATUS_FALSE;
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "\nLibSndFile Version : %s Supported Formats\n", buffer);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "================================================================================\n");
- sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof(int));
- sf_command(NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &subtype_count, sizeof(int));
-
- sfinfo.channels = 1;
- len = ((major_count + (exlen + 2)) * sizeof(char *));
- supported_formats = switch_core_permanent_alloc(len);
-
- len = 0;
- for (m = 0; m < major_count; m++) {
- skip = 0;
- info.format = m;
- sf_command(NULL, SFC_GET_FORMAT_MAJOR, &info, sizeof(info));
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s (extension \"%s\")\n", info.name, info.extension);
- for (x = 0; x < len; x++) {
- if (supported_formats[x] == info.extension) {
- skip++;
- break;
- }
- }
- if (!skip) {
- char *p;
- struct format_map *map = switch_core_permanent_alloc(sizeof(*map));
- switch_assert(map);
-
- map->ext = switch_core_permanent_strdup(info.extension);
- map->uext = switch_core_permanent_strdup(info.extension);
- map->format = info.format;
- if (map->ext) {
- for (p = map->ext; *p; p++) {
- *p = (char) switch_tolower(*p);
- }
- switch_core_hash_insert(globals.format_hash, map->ext, map);
- }
- if (map->uext) {
- for (p = map->uext; *p; p++) {
- *p = (char) switch_toupper(*p);
- }
- switch_core_hash_insert(globals.format_hash, map->uext, map);
- }
- supported_formats[len++] = (char *) info.extension;
- }
- format = info.format;
-
- for (s = 0; s < subtype_count; s++) {
- info.format = s;
- sf_command(NULL, SFC_GET_FORMAT_SUBTYPE, &info, sizeof(info));
- format = (format & SF_FORMAT_TYPEMASK) | info.format;
- sfinfo.format = format;
- /*
- if (sf_format_check(&sfinfo)) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, " %s\n", info.name);
- }
- */
- }
- }
- for (m = 0; m < exlen; m++) {
- supported_formats[len++] = extras[m];
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_NOTICE, "================================================================================\n");
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MODULE_LOAD_FUNCTION(mod_sndfile_load)
-{
- switch_file_interface_t *file_interface;
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
-
- switch_core_hash_init(&globals.format_hash, module_pool);
-
- if (setup_formats() != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_FALSE;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
- file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
- file_interface->interface_name = modname;
- file_interface->extens = supported_formats;
- file_interface->file_open = sndfile_file_open;
- file_interface->file_close = sndfile_file_close;
- file_interface->file_truncate = sndfile_file_truncate;
- file_interface->file_read = sndfile_file_read;
- file_interface->file_write = sndfile_file_write;
- file_interface->file_seek = sndfile_file_seek;
- file_interface->file_set_string = sndfile_file_set_string;
- file_interface->file_get_string = sndfile_file_get_string;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sndfile_shutdown)
-{
- switch_core_hash_destroy(&globals.format_hash);
- return SWITCH_STATUS_SUCCESS;
-}
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
- */
diff --git a/src/mod/languages/mod_python/mod_python_wrap.cpp.rej b/src/mod/languages/mod_python/mod_python_wrap.cpp.rej
deleted file mode 100644
index 80c9bbaace..0000000000
--- a/src/mod/languages/mod_python/mod_python_wrap.cpp.rej
+++ /dev/null
@@ -1,38 +0,0 @@
-***************
-*** 5555,5561 ****
- SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "EventConsumer_pop" "', argument " "2"" of type '" "int""'");
- }
- arg2 = static_cast< int >(val2);
- result = (Event *)(arg1)->pop(arg2);
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN | 0 );
- return resultobj;
- fail:
---- 5555,5563 ----
- SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "EventConsumer_pop" "', argument " "2"" of type '" "int""'");
- }
- arg2 = static_cast< int >(val2);
-+ Py_BEGIN_ALLOW_THREADS;
- result = (Event *)(arg1)->pop(arg2);
-+ Py_END_ALLOW_THREADS;
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN | 0 );
- return resultobj;
- fail:
-***************
-*** 5577,5583 ****
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EventConsumer_pop" "', argument " "1"" of type '" "EventConsumer *""'");
- }
- arg1 = reinterpret_cast< EventConsumer * >(argp1);
- result = (Event *)(arg1)->pop();
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN | 0 );
- return resultobj;
- fail:
---- 5579,5587 ----
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EventConsumer_pop" "', argument " "1"" of type '" "EventConsumer *""'");
- }
- arg1 = reinterpret_cast< EventConsumer * >(argp1);
-+ Py_BEGIN_ALLOW_THREADS;
- result = (Event *)(arg1)->pop();
-+ Py_END_ALLOW_THREADS;
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN | 0 );
- return resultobj;
- fail:
diff --git a/src/switch_core.c.orig b/src/switch_core.c.orig
deleted file mode 100644
index fe0ffcbaba..0000000000
--- a/src/switch_core.c.orig
+++ /dev/null
@@ -1,2018 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2010, Anthony Minessale II
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II
- * Michael Jerris
- * Paul D. Tinsley
- * Marcel Barbulescu
- *
- *
- * switch_core.c -- Main Core Library
- *
- */
-
-
-
-#include
-#include
-#include
-#include
-#include "private/switch_core_pvt.h"
-#ifndef WIN32
-#include
-#ifdef HAVE_SETRLIMIT
-#include
-#endif
-#endif
-#include
-
-
-SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 };
-
-/* The main runtime obj we keep this hidden for ourselves */
-struct switch_runtime runtime = { 0 };
-static void switch_load_core_config(const char *file);
-
-static void send_heartbeat(void)
-{
- switch_event_t *event;
- switch_core_time_duration_t duration;
-
- switch_core_measure_time(switch_core_uptime(), &duration);
-
- if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time",
- "%u year%s, "
- "%u day%s, "
- "%u hour%s, "
- "%u minute%s, "
- "%u second%s, "
- "%u millisecond%s, "
- "%u microsecond%s",
- duration.yr, duration.yr == 1 ? "" : "s",
- duration.day, duration.day == 1 ? "" : "s",
- duration.hr, duration.hr == 1 ? "" : "s",
- duration.min, duration.min == 1 ? "" : "s",
- duration.sec, duration.sec == 1 ? "" : "s",
- duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s");
-
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu());
- switch_event_fire(&event);
- }
-}
-
-static char main_ip4[256] = "";
-static char main_ip6[256] = "";
-
-static void check_ip(void)
-{
- char guess_ip4[256] = "";
- char guess_ip6[256] = "";
- char old_ip4[256] = "";
- char old_ip6[256] = "";
- int ok4 = 1, ok6 = 1;
- int mask = 0;
- static char hostname[256] = "";
-
- gethostname(hostname, sizeof(hostname));
- switch_core_set_variable("hostname", hostname);
-
- switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET);
- switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6);
-
- if (!*main_ip4) {
- switch_set_string(main_ip4, guess_ip4);
- } else {
- if (!(ok4 = !strcmp(main_ip4, guess_ip4))) {
- struct in_addr in;
-
- in.s_addr = mask;
- switch_set_string(old_ip4, main_ip4);
- switch_set_string(main_ip4, guess_ip4);
- switch_core_set_variable("local_ip_v4", guess_ip4);
- switch_core_set_variable("local_mask_v4", inet_ntoa(in));
- }
- }
-
- if (!*main_ip6) {
- switch_set_string(main_ip6, guess_ip6);
- } else {
- if (!(ok6 = !strcmp(main_ip6, guess_ip6))) {
- switch_set_string(old_ip6, main_ip6);
- switch_set_string(main_ip6, guess_ip6);
- switch_core_set_variable("local_ip_v6", guess_ip6);
- }
- }
-
- if (!ok4 || !ok6) {
- switch_event_t *event;
-
- if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change");
- if (!ok4) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4);
- }
- if (!ok6) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6);
- }
- switch_event_fire(&event);
- }
- }
-}
-
-SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback)
-{
- send_heartbeat();
- check_ip();
-
- /* reschedule this task */
- task->runtime = switch_epoch_time_now(NULL) + 20;
-}
-
-
-SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console)
-{
- if ((runtime.console = fopen(console, "a")) == 0) {
- fprintf(stderr, "Cannot open output file %s.\n", console);
- return SWITCH_STATUS_FALSE;
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_DECLARE(FILE *) switch_core_get_console(void)
-{
- return runtime.console;
-}
-
-SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel)
-{
- FILE *handle = stdout;
-
- switch (channel) {
- case SWITCH_CHANNEL_ID_LOG:
- case SWITCH_CHANNEL_ID_LOG_CLEAN:
- handle = runtime.console;
- break;
- default:
- handle = runtime.console;
- break;
- }
-
- return handle;
-}
-
-SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler)
-{
- int index, tmp_index = 0;
- const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS + 1] = { 0 };
-
- switch_mutex_lock(runtime.global_mutex);
-
- for (index = 0; index < runtime.state_handler_index; index++) {
- const switch_state_handler_table_t *cur = runtime.state_handlers[index];
- runtime.state_handlers[index] = NULL;
- if (cur == state_handler) {
- continue;
- }
- tmp[tmp_index++] = cur;
- }
-
- runtime.state_handler_index = 0;
-
- for (index = 0; index < tmp_index; index++) {
- runtime.state_handlers[runtime.state_handler_index++] = tmp[index];
- }
- switch_mutex_unlock(runtime.global_mutex);
-}
-
-
-SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table_t *state_handler)
-{
- int index;
-
- switch_mutex_lock(runtime.global_mutex);
- index = runtime.state_handler_index++;
-
- if (runtime.state_handler_index >= SWITCH_MAX_STATE_HANDLERS) {
- index = -1;
- } else {
- runtime.state_handlers[index] = state_handler;
- }
-
- switch_mutex_unlock(runtime.global_mutex);
- return index;
-}
-
-SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index)
-{
-
- if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) {
- return NULL;
- }
-
- return runtime.state_handlers[index];
-}
-
-SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream)
-{
- switch_hash_index_t *hi;
- const void *var;
- void *val;
- switch_mutex_lock(runtime.global_mutex);
- for (hi = switch_hash_first(NULL, runtime.global_vars); hi; hi = switch_hash_next(hi)) {
- char *vvar, *vval;
- switch_hash_this(hi, &var, NULL, &val);
- vvar = (char *) var;
- vval = (char *) val;
- stream->write_function(stream, "%s=%s\n", vvar, vval);
- }
- switch_mutex_unlock(runtime.global_mutex);
-}
-
-SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname)
-{
- char *val;
- switch_mutex_lock(runtime.global_var_mutex);
- val = (char *) switch_core_hash_find(runtime.global_vars, varname);
- switch_mutex_unlock(runtime.global_var_mutex);
- return val;
-}
-
-static void switch_core_unset_variables(void)
-{
- switch_hash_index_t *hi;
- const void *var;
- void *val;
-
- switch_mutex_lock(runtime.global_var_mutex);
- for (hi = switch_hash_first(NULL, runtime.global_vars); hi; hi = switch_hash_next(hi)) {
- switch_hash_this(hi, &var, NULL, &val);
- free(val);
- }
- switch_mutex_unlock(runtime.global_var_mutex);
-}
-
-SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value)
-{
- char *val;
-
- if (varname) {
- switch_mutex_lock(runtime.global_var_mutex);
- val = (char *) switch_core_hash_find(runtime.global_vars, varname);
- if (val) {
- free(val);
- }
- if (value) {
- char *v = strdup(value);
- switch_string_var_check(v, SWITCH_TRUE);
- switch_core_hash_insert(runtime.global_vars, varname, v);
- } else {
- switch_core_hash_delete(runtime.global_vars, varname);
- }
- switch_mutex_unlock(runtime.global_var_mutex);
- }
-}
-
-SWITCH_DECLARE(char *) switch_core_get_uuid(void)
-{
- return runtime.uuid_str;
-}
-
-
-static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj)
-{
- switch_core_session_t *session = obj;
- switch_channel_t *channel;
- switch_frame_t *read_frame;
-
-// switch_assert(thread != NULL);
-// switch_assert(session != NULL);
-
- if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
- return NULL;
- }
-
- switch_mutex_lock(session->frame_read_mutex);
-
- channel = switch_core_session_get_channel(session);
-
- switch_channel_set_flag(channel, CF_SERVICE);
- while (switch_channel_test_flag(channel, CF_SERVICE)) {
- switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
- case SWITCH_STATUS_SUCCESS:
- case SWITCH_STATUS_TIMEOUT:
- case SWITCH_STATUS_BREAK:
- break;
- default:
- switch_channel_clear_flag(channel, CF_SERVICE);
- continue;
- }
- }
-
- switch_mutex_unlock(session->frame_read_mutex);
-
- switch_core_session_rwunlock(session);
-
- return NULL;
-}
-
-/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */
-SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_session_t *session)
-{
- switch_channel_t *channel;
- switch_assert(session);
-
- channel = switch_core_session_get_channel(session);
- switch_assert(channel);
-
- switch_channel_clear_flag(channel, CF_SERVICE);
-}
-
-SWITCH_DECLARE(void) switch_core_service_session(switch_core_session_t *session)
-{
- switch_channel_t *channel;
- switch_assert(session);
-
- channel = switch_core_session_get_channel(session);
- switch_assert(channel);
-
- switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session);
-}
-
-/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and
- a void object and trust that that the function will be run in a thread with arg This lets
- you request and activate a thread without giving up any knowledge about what is in the thread
- neither the core nor the calling module know anything about each other.
-
- This thread is expected to never exit until the application exits so the func is responsible
- to make sure that is the case.
-
- The typical use for this is so switch_loadable_module.c can start up a thread for each module
- passing the table of module methods as a session obj into the core without actually allowing
- the core to have any clue and keeping switch_loadable_module.c from needing any thread code.
-
-*/
-
-SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool)
-{
- switch_thread_t *thread = NULL;
- switch_threadattr_t *thd_attr = NULL;
- switch_core_thread_session_t *ts;
- int mypool;
-
- mypool = pool ? 0 : 1;
-
- if (!pool && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory pool\n");
- return NULL;
- }
-
- switch_threadattr_create(&thd_attr, pool);
-
- if ((ts = switch_core_alloc(pool, sizeof(*ts))) == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory\n");
- } else {
- if (mypool) {
- ts->pool = pool;
- }
- ts->objs[0] = obj;
- ts->objs[1] = thread;
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_threadattr_priority_increase(thd_attr);
- switch_thread_create(&thread, thd_attr, func, ts, pool);
- }
-
- return thread;
-}
-
-SWITCH_DECLARE(void) switch_core_set_globals(void)
-{
-#define BUFSIZE 1024
-#ifdef WIN32
- char lpPathBuffer[BUFSIZE];
- DWORD dwBufSize = BUFSIZE;
- char base_dir[1024];
- char *lastbacklash;
- GetModuleFileName(NULL, base_dir, BUFSIZE);
- lastbacklash = strrchr(base_dir, '\\');
- base_dir[(lastbacklash - base_dir)] = '\0';
-#else
- char base_dir[1024] = SWITCH_PREFIX_DIR;
-#endif
-
- if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) {
- switch_snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE, "%s", base_dir);
- }
-
- if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_MOD_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s", SWITCH_MOD_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s%smod", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_CONF_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s", SWITCH_CONF_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s%sconf", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_LOG_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s", SWITCH_LOG_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s%slog", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_RUN_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s", SWITCH_RUN_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s%srun", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.recordings_dir && (SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_RECORDINGS_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s", SWITCH_RECORDINGS_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s%srecordings", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_SOUNDS_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s", SWITCH_SOUNDS_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s%ssounds", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.storage_dir && (SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_STORAGE_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s", SWITCH_STORAGE_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s%sstorage", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_DB_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s", SWITCH_DB_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s%sdb", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_SCRIPT_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s", SWITCH_SCRIPT_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s%sscripts", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_HTDOCS_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s", SWITCH_HTDOCS_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s%shtdocs", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.grammar_dir && (SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_GRAMMAR_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s", SWITCH_GRAMMAR_DIR);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s%sgrammar", base_dir, SWITCH_PATH_SEPARATOR);
-#endif
- }
-
- if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE))) {
-#ifdef SWITCH_TEMP_DIR
- switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", SWITCH_TEMP_DIR);
-#else
-#ifdef WIN32
- GetTempPath(dwBufSize, lpPathBuffer);
- switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer);
-#else
- switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp/");
-#endif
-#endif
- }
-
- switch_assert(SWITCH_GLOBAL_dirs.base_dir);
- switch_assert(SWITCH_GLOBAL_dirs.mod_dir);
- switch_assert(SWITCH_GLOBAL_dirs.conf_dir);
- switch_assert(SWITCH_GLOBAL_dirs.log_dir);
- switch_assert(SWITCH_GLOBAL_dirs.run_dir);
- switch_assert(SWITCH_GLOBAL_dirs.db_dir);
- switch_assert(SWITCH_GLOBAL_dirs.script_dir);
- switch_assert(SWITCH_GLOBAL_dirs.htdocs_dir);
- switch_assert(SWITCH_GLOBAL_dirs.grammar_dir);
- switch_assert(SWITCH_GLOBAL_dirs.recordings_dir);
- switch_assert(SWITCH_GLOBAL_dirs.sounds_dir);
- switch_assert(SWITCH_GLOBAL_dirs.temp_dir);
-}
-
-SWITCH_DECLARE(int32_t) set_high_priority(void)
-{
-#ifdef WIN32
- SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
-#else
-
-#ifdef USE_SETRLIMIT
- struct rlimit lim = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-
-#ifdef USE_SCHED_SETSCHEDULER
- /*
- * Try to use a round-robin scheduler
- * with a fallback if that does not work
- */
- struct sched_param sched = { 0 };
- sched.sched_priority = 1;
- if (sched_setscheduler(0, SCHED_RR, &sched)) {
- sched.sched_priority = 0;
- if (sched_setscheduler(0, SCHED_OTHER, &sched)) {
- return -1;
- }
- }
-#endif
-
-#ifdef HAVE_SETPRIORITY
- /*
- * setpriority() works on FreeBSD (6.2), nice() doesn't
- */
- if (setpriority(PRIO_PROCESS, getpid(), -10) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
- }
-#else
- if (nice(-10) != -10) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
- }
-#endif
-
-#ifdef USE_SETRLIMIT
- /*
- * The amount of memory which can be mlocked is limited for non-root users.
- * FS will segfault (= hitting the limit) soon after mlockall has been called
- * and we've switched to a different user.
- * So let's try to remove the mlock limit here...
- */
- if (setrlimit(RLIMIT_MEMLOCK, &lim) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to disable memlock limit, application may crash if run as non-root user!\n");
- }
-#endif
-
-#ifdef USE_MLOCKALL
- /*
- * Pin memory pages to RAM to prevent being swapped to disk
- */
- mlockall(MCL_CURRENT | MCL_FUTURE);
-#endif
-
-#endif
- return 0;
-}
-
-SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group)
-{
-#ifndef WIN32
- uid_t runas_uid = 0;
- gid_t runas_gid = 0;
- struct passwd *runas_pw = NULL;
-
- if (user) {
- /*
- * Lookup user information in the system's db
- */
- runas_pw = getpwnam(user);
- if (!runas_pw) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown user \"%s\"\n", user);
- return -1;
- }
- runas_uid = runas_pw->pw_uid;
- }
-
- if (group) {
- struct group *gr = NULL;
-
- /*
- * Lookup group information in the system's db
- */
- gr = getgrnam(group);
- if (!gr) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown group \"%s\"\n", group);
- return -1;
- }
- runas_gid = gr->gr_gid;
- }
-
- if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) {
- /* already running as the right user and group, nothing to do! */
- return 0;
- }
-
- if (runas_uid) {
-#ifdef HAVE_SETGROUPS
- /*
- * Drop all group memberships prior to changing anything
- * or else we're going to inherit the parent's list of groups
- * (which is not what we want...)
- */
- if (setgroups(0, NULL) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to drop group access list\n");
- return -1;
- }
-#endif
- if (runas_gid) {
- /*
- * A group has been passed, switch to it
- * (without loading the user's other groups)
- */
- if (setgid(runas_gid) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n");
- return -1;
- }
- } else {
- /*
- * No group has been passed, use the user's primary group in this case
- */
- if (setgid(runas_pw->pw_gid) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n");
- return -1;
- }
-#ifdef HAVE_INITGROUPS
- /*
- * Set all the other groups the user is a member of
- * (This can be really useful for fine-grained access control)
- */
- if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to set group access list for user\n");
- return -1;
- }
-#endif
- }
-
- /*
- * Finally drop all privileges by switching to the new userid
- */
- if (setuid(runas_uid) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change uid!\n");
- return -1;
- }
- }
-#endif
- return 0;
-}
-
-SWITCH_DECLARE(void) switch_core_runtime_loop(int bg)
-{
-#ifdef WIN32
- HANDLE shutdown_event;
- char path[256] = "";
-#endif
- if (bg) {
- bg = 0;
-#ifdef WIN32
- switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
- shutdown_event = CreateEvent(NULL, FALSE, FALSE, path);
- if (shutdown_event) {
- WaitForSingleObject(shutdown_event, INFINITE);
- }
-#else
- runtime.running = 1;
- while (runtime.running) {
- switch_yield(1000000);
- }
-#endif
- } else {
- /* wait for console input */
- switch_console_loop();
- }
-}
-
-SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext)
-{
- if (!ext) {
- return NULL;
- }
- return (const char *) switch_core_hash_find(runtime.mime_types, ext);
-}
-
-
-SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void)
-{
- return switch_hash_first(NULL, runtime.mime_types);
-}
-
-SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext)
-{
- const char *check;
- switch_status_t status = SWITCH_STATUS_FALSE;
-
- switch_assert(type);
- switch_assert(ext);
-
- check = (const char *) switch_core_hash_find(runtime.mime_types, ext);
-
- if (!check) {
- char *ptype = switch_core_permanent_strdup(type);
- char *ext_list = strdup(ext);
- int argc = 0;
- char *argv[20] = { 0 };
- int x;
-
- switch_assert(ext_list);
-
- if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
-
- for (x = 0; x < argc; x++) {
- if (argv[x] && ptype) {
- switch_core_hash_insert(runtime.mime_types, argv[x], ptype);
- }
- }
-
- status = SWITCH_STATUS_SUCCESS;
- }
-
- free(ext_list);
- }
-
- return status;
-}
-
-static void load_mime_types(void)
-{
- char *cf = "mime.types";
- int fd = -1;
- char line_buf[1024] = "";
- char *mime_path = NULL;
-
- mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf);
- switch_assert(mime_path);
-
- fd = open(mime_path, O_RDONLY | O_BINARY);
- if (fd <= 0) {
- goto end;
- }
-
- while ((switch_fd_read_line(fd, line_buf, sizeof(line_buf)))) {
- char *p;
- char *type = line_buf;
-
- if (*line_buf == '#') {
- continue;
- }
-
- if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) {
- *p = '\0';
- }
-
- if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) {
- *p++ = '\0';
-
- while (*p == ' ' || *p == '\t') {
- p++;
- }
-
- switch_core_mime_add_type(type, p);
- }
-
- }
-
- if (fd > -1) {
- close(fd);
- fd = -1;
- }
-
- end:
-
- switch_safe_free(mime_path);
-
-}
-
-SWITCH_DECLARE(void) switch_core_setrlimits(void)
-{
-#ifdef HAVE_SETRLIMIT
- struct rlimit rlp;
-
- /*
- Setting the stack size on FreeBSD results in an instant crash.
-
- If anyone knows how to fix this,
- feel free to submit a patch to http://jira.freeswitch.org
- */
-
-#ifndef __FreeBSD__
- memset(&rlp, 0, sizeof(rlp));
- rlp.rlim_cur = SWITCH_THREAD_STACKSIZE;
- rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
- setrlimit(RLIMIT_STACK, &rlp);
-#endif
-
- memset(&rlp, 0, sizeof(rlp));
- rlp.rlim_cur = 999999;
- rlp.rlim_max = 999999;
- setrlimit(RLIMIT_NOFILE, &rlp);
-
- memset(&rlp, 0, sizeof(rlp));
- rlp.rlim_cur = RLIM_INFINITY;
- rlp.rlim_max = RLIM_INFINITY;
-
- setrlimit(RLIMIT_CPU, &rlp);
- setrlimit(RLIMIT_DATA, &rlp);
- setrlimit(RLIMIT_FSIZE, &rlp);
-#ifdef RLIMIT_NPROC
- setrlimit(RLIMIT_NPROC, &rlp);
-#endif
-#ifdef RLIMIT_RTPRIO
- setrlimit(RLIMIT_RTPRIO, &rlp);
-#endif
-
-#if !defined(__OpenBSD__) && !defined(__NetBSD__)
- setrlimit(RLIMIT_AS, &rlp);
-#endif
-#endif
- return;
-}
-
-typedef struct {
- switch_memory_pool_t *pool;
- switch_hash_t *hash;
-} switch_ip_list_t;
-
-static switch_ip_list_t IP_LIST = { 0 };
-
-SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)
-{
- switch_network_list_t *list;
- uint32_t ip, net, mask, bits;
- switch_bool_t ok = SWITCH_FALSE;
-
- switch_mutex_lock(runtime.global_mutex);
- switch_inet_pton(AF_INET, ip_str, &ip);
-
- ip = htonl(ip);
-
- if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {
- ok = switch_network_list_validate_ip_token(list, ip, token);
- } else if (strchr(list_name, '/')) {
- if (strchr(list_name, ',')) {
- char *list_name_dup = strdup(list_name);
- char *argv[32];
- int argc;
-
- switch_assert(list_name_dup);
-
- if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
- int i;
- for (i = 0; i < argc; i++) {
- switch_parse_cidr(argv[i], &net, &mask, &bits);
- if ((ok = switch_test_subnet(ip, net, mask))) {
- break;
- }
- }
- }
- free(list_name_dup);
- } else {
- switch_parse_cidr(list_name, &net, &mask, &bits);
- ok = switch_test_subnet(ip, net, mask);
- }
- }
- switch_mutex_unlock(runtime.global_mutex);
-
- return ok;
-}
-
-
-SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
-{
- switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL;
- switch_network_list_t *rfc_list, *list;
- char guess_ip[16] = "";
- int mask = 0;
- char guess_mask[16] = "";
- char *tmp_name;
- struct in_addr in;
-
- switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);
- in.s_addr = mask;
- switch_set_string(guess_mask, inet_ntoa(in));
-
- switch_mutex_lock(runtime.global_mutex);
-
- if (IP_LIST.hash) {
- switch_core_hash_destroy(&IP_LIST.hash);
- }
-
- if (IP_LIST.pool) {
- switch_core_destroy_memory_pool(&IP_LIST.pool);
- }
-
- memset(&IP_LIST, 0, sizeof(IP_LIST));
- switch_core_new_memory_pool(&IP_LIST.pool);
- switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool);
-
-
- tmp_name = "rfc1918.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
-
- tmp_name = "wan.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE);
- switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
-
- tmp_name = "nat.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
- if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name);
- }
- switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);
- switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
-
- tmp_name = "loopback.auto";
- switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
- switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE);
- switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
-
- tmp_name = "localnet.auto";
- switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
-
- if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name);
- }
- switch_core_hash_insert(IP_LIST.hash, tmp_name, list);
-
-
- if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) {
- if ((x_lists = switch_xml_child(cfg, "network-lists"))) {
- for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) {
- const char *name = switch_xml_attr(x_list, "name");
- const char *dft = switch_xml_attr(x_list, "default");
- switch_bool_t default_type = SWITCH_TRUE;
-
- if (zstr(name)) {
- continue;
- }
-
- if (dft) {
- default_type = switch_true(dft);
- }
-
- if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) {
- abort();
- }
-
- if (reload) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
- }
-
-
- for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) {
- const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL;
- switch_bool_t ok = default_type;
- const char *type = switch_xml_attr(x_node, "type");
-
- if (type) {
- ok = switch_true(type);
- }
-
- cidr = switch_xml_attr(x_node, "cidr");
- host = switch_xml_attr(x_node, "host");
- mask = switch_xml_attr(x_node, "mask");
- domain = switch_xml_attr(x_node, "domain");
-
- if (domain) {
- switch_event_t *my_params = NULL;
- switch_xml_t x_domain, xml_root;
- switch_xml_t gt, gts, ut, uts;
-
- switch_event_create(&my_params, SWITCH_EVENT_GENERAL);
- switch_assert(my_params);
- switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain);
- switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list");
-
- if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain);
- switch_event_destroy(&my_params);
- continue;
- }
-
- switch_event_destroy(&my_params);
-
- for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) {
- const char *user_cidr = switch_xml_attr(ut, "cidr");
- const char *id = switch_xml_attr(ut, "id");
-
- if (id && user_cidr) {
- char *token = switch_mprintf("%s@%s", id, domain);
- switch_assert(token);
- switch_network_list_add_cidr_token(list, user_cidr, ok, token);
- free(token);
- }
- }
-
- for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) {
- for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {
- for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {
- for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {
- const char *user_cidr = switch_xml_attr(ut, "cidr");
- const char *id = switch_xml_attr(ut, "id");
-
- if (id && user_cidr) {
- char *token = switch_mprintf("%s@%s", id, domain);
- switch_assert(token);
- switch_network_list_add_cidr_token(list, user_cidr, ok, token);
- free(token);
- }
- }
- }
- }
- }
-
- switch_xml_free(xml_root);
- } else if (cidr) {
- if (switch_network_list_add_cidr(list, cidr, ok) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
- "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
- }
- } else if (host && mask) {
- if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
- "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name);
- }
- }
-
- switch_core_hash_insert(IP_LIST.hash, name, list);
- }
- }
- }
-
- switch_xml_free(xml);
- }
-
- switch_mutex_unlock(runtime.global_mutex);
-}
-
-SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration)
-{
- if (duration) {
- if (duration > SWITCH_MAX_DTMF_DURATION) {
- duration = SWITCH_MAX_DTMF_DURATION;
- }
- if (duration < SWITCH_MIN_DTMF_DURATION) {
- duration = SWITCH_MIN_DTMF_DURATION;
- }
- runtime.max_dtmf_duration = duration;
- }
- return runtime.max_dtmf_duration;
-}
-
-SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration)
-{
- if (duration) {
- if (duration < SWITCH_MIN_DTMF_DURATION) {
- duration = SWITCH_MIN_DTMF_DURATION;
- }
- if (duration > SWITCH_MAX_DTMF_DURATION) {
- duration = SWITCH_MAX_DTMF_DURATION;
- }
- runtime.default_dtmf_duration = duration;
- }
- return runtime.default_dtmf_duration;
-}
-
-SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration)
-{
- if (duration) {
- if (duration < SWITCH_MIN_DTMF_DURATION) {
- duration = SWITCH_MIN_DTMF_DURATION;
- }
- if (duration > SWITCH_MAX_DTMF_DURATION) {
- duration = SWITCH_MAX_DTMF_DURATION;
- }
- }
- return runtime.min_dtmf_duration;
-}
-
-static void switch_core_set_serial(void)
-{
- char buf[13] = "";
- char path[256];
-
- int fd = -1, write_fd = -1;
- switch_ssize_t bytes = 0;
-
- switch_snprintf(path, sizeof(path), "%s%sfreeswitch.serial", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR);
-
-
- if ((fd = open(path, O_RDONLY, 0)) < 0) {
- char *ip = switch_core_get_variable("local_ip_v4");
- uint32_t ipi = 0;
- switch_byte_t *byte;
- int i = 0;
-
- switch_inet_pton(AF_INET, ip, &ipi);
- byte = (switch_byte_t *) & ipi;
-
- for (i = 0; i < 8; i += 2) {
- switch_snprintf(buf + i, sizeof(buf) - i, "%0.2x", *byte);
- byte++;
- }
-
- switch_stun_random_string(buf + 8, 4, "0123456789abcdef");
-
- if ((write_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) {
- bytes = write(write_fd, buf, sizeof(buf));
- close(write_fd);
- write_fd = -1;
- }
- } else {
- bytes = read(fd, buf, sizeof(buf));
- close(fd);
- fd = -1;
- }
-
- switch_core_set_variable("switch_serial", buf);
-}
-
-SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)
-{
- switch_uuid_t uuid;
- char guess_ip[256];
- int mask = 0;
- struct in_addr in;
- char hostname[256] = "";
-
- if (runtime.runlevel > 0) {
- /* one per customer */
- return SWITCH_STATUS_SUCCESS;
- }
-
- runtime.runlevel++;
-
- runtime.dummy_cng_frame.data = runtime.dummy_data;
- runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data);
- runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data);
- switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG);
-
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
- runtime.hard_log_level = SWITCH_LOG_DEBUG;
- runtime.mailer_app = "sendmail";
- runtime.mailer_app_args = "-t";
- runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION;
- runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION;
- runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION;
-
- /* INIT APR and Create the pool context */
- if (apr_initialize() != SWITCH_STATUS_SUCCESS) {
- *err = "FATAL ERROR! Could not initialize APR\n";
- return SWITCH_STATUS_MEMERR;
- }
-
- if (!(runtime.memory_pool = switch_core_memory_init())) {
- *err = "FATAL ERROR! Could not allocate memory pool\n";
- return SWITCH_STATUS_MEMERR;
- }
- switch_assert(runtime.memory_pool != NULL);
-
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
- switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);
-
- switch_mutex_init(&runtime.uuid_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
-
- switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
- switch_mutex_init(&runtime.session_hash_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
- switch_mutex_init(&runtime.global_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
- switch_mutex_init(&runtime.global_var_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
- switch_core_set_globals();
- switch_core_session_init(runtime.memory_pool);
- switch_core_hash_init(&runtime.global_vars, runtime.memory_pool);
- switch_core_hash_init(&runtime.mime_types, runtime.memory_pool);
- load_mime_types();
- runtime.flags = flags;
- runtime.sps_total = 30;
-
- *err = NULL;
-
- if (console) {
- runtime.console = stdout;
- }
-
- gethostname(hostname, sizeof(hostname));
- switch_core_set_variable("hostname", hostname);
-
- switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);
- switch_core_set_variable("local_ip_v4", guess_ip);
- in.s_addr = mask;
- switch_core_set_variable("local_mask_v4", inet_ntoa(in));
-
-
- switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6);
- switch_core_set_variable("local_ip_v6", guess_ip);
- switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir);
- switch_core_set_variable("recordings_dir", SWITCH_GLOBAL_dirs.recordings_dir);
- switch_core_set_variable("sound_prefix", SWITCH_GLOBAL_dirs.sounds_dir);
- switch_core_set_variable("sounds_dir", SWITCH_GLOBAL_dirs.sounds_dir);
- switch_core_set_serial();
-
- switch_console_init(runtime.memory_pool);
- switch_event_init(runtime.memory_pool);
-
- if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) {
- apr_terminate();
- return SWITCH_STATUS_MEMERR;
- }
-
- if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
- switch_nat_init(runtime.memory_pool);
- }
-
- switch_log_init(runtime.memory_pool, runtime.colorize_console);
-
- runtime.tipping_point = 5000;
- runtime.timer_affinity = -1;
- switch_load_core_config("switch.conf");
-
-
- switch_core_state_machine_init(runtime.memory_pool);
-
- if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
- abort();
- }
-
- switch_scheduler_task_thread_start();
-
- switch_rtp_init(runtime.memory_pool);
-
- runtime.running = 1;
- runtime.initiated = switch_time_now();
-
- switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL);
-
- switch_uuid_get(&uuid);
- switch_uuid_format(runtime.uuid_str, &uuid);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-#ifdef SIGQUIT
-static void handle_SIGQUIT(int sig)
-{
- if (sig);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Sig Quit!\n");
- return;
-}
-#endif
-
-#ifdef SIGPIPE
-static void handle_SIGPIPE(int sig)
-{
- if (sig);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Sig Pipe!\n");
- return;
-}
-#endif
-
-#ifdef SIGPOLL
-static void handle_SIGPOLL(int sig)
-{
- if (sig);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Sig Poll!\n");
- return;
-}
-#endif
-
-#ifdef SIGIO
-static void handle_SIGIO(int sig)
-{
- if (sig);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Sig I/O!\n");
- return;
-}
-#endif
-
-#ifdef TRAP_BUS
-static void handle_SIGBUS(int sig)
-{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Sig BUS!\n");
- return;
-}
-#endif
-
-static void handle_SIGHUP(int sig)
-{
- if (sig) {
- switch_event_t *event;
-
- if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP");
- switch_event_fire(&event);
- }
- }
- return;
-}
-
-
-static void switch_load_core_config(const char *file)
-{
- switch_xml_t xml = NULL, cfg = NULL;
-
- if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) {
- switch_xml_t settings, param;
-
- if ((settings = switch_xml_child(cfg, "settings"))) {
- for (param = switch_xml_child(settings, "param"); param; param = param->next) {
- const char *var = switch_xml_attr_soft(param, "name");
- const char *val = switch_xml_attr_soft(param, "value");
-
- if (!strcasecmp(var, "loglevel")) {
- int level;
- if (*val > 47 && *val < 58) {
- level = atoi(val);
- } else {
- level = switch_log_str2level(val);
- }
-
- if (level != SWITCH_LOG_INVALID) {
- switch_core_session_ctl(SCSC_LOGLEVEL, &level);
- }
-#ifdef HAVE_SETRLIMIT
- } else if (!strcasecmp(var, "dump-cores")) {
- struct rlimit rlp;
- memset(&rlp, 0, sizeof(rlp));
- rlp.rlim_cur = RLIM_INFINITY;
- rlp.rlim_max = RLIM_INFINITY;
- setrlimit(RLIMIT_CORE, &rlp);
-#endif
- } else if (!strcasecmp(var, "debug-level")) {
- int tmp = atoi(val);
- if (tmp > -1 && tmp < 11) {
- switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
- }
- } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) {
- switch_set_flag((&runtime), SCF_EARLY_HANGUP);
- } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) {
- runtime.colorize_console = SWITCH_TRUE;
- } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) {
- runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "mailer-app-args") && val) {
- runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val);
- } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)) {
- switch_core_sessions_per_second(atoi(val));
- } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)) {
- int tmp = atoi(val);
- if (tmp > 0) {
- switch_core_max_dtmf_duration((uint32_t) tmp);
- }
- } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)) {
- int tmp = atoi(val);
- if (tmp > 0) {
- switch_core_min_dtmf_duration((uint32_t) tmp);
- }
- } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)) {
- int tmp = atoi(val);
- if (tmp > 0) {
- switch_core_default_dtmf_duration((uint32_t) tmp);
- }
- } else if (!strcasecmp(var, "enable-monotonic-timing")) {
- switch_time_set_monotonic(switch_true(var));
- } else if (!strcasecmp(var, "enable-clock-nanosleep")) {
- switch_time_set_nanosleep(switch_true(var));
- } else if (!strcasecmp(var, "enable-cond-yield")) {
- switch_time_set_cond_yield(switch_true(var));
- } else if (!strcasecmp(var, "enable-timer-matrix")) {
- switch_time_set_matrix(switch_true(var));
- } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) {
- switch_core_session_limit(atoi(val));
- } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) {
- switch_core_min_idle_cpu(atof(val));
- } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {
- runtime.tipping_point = atoi(val);
- } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) {
- if (!strcasecmp(val, "disabled")) {
- runtime.timer_affinity = -1;
- } else {
- runtime.timer_affinity = atoi(val);
- }
- } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {
- switch_rtp_set_start_port((switch_port_t) atoi(val));
- } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) {
- switch_rtp_set_end_port((switch_port_t) atoi(val));
- } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) {
- if (switch_odbc_available()) {
- runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val);
- if ((runtime.odbc_user = strchr(runtime.odbc_dsn, ':'))) {
- *runtime.odbc_user++ = '\0';
- if ((runtime.odbc_pass = strchr(runtime.odbc_user, ':'))) {
- *runtime.odbc_pass++ = '\0';
- }
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
- }
-#ifdef ENABLE_ZRTP
- } else if (!strcasecmp(var, "rtp-enable-zrtp")) {
- switch_core_set_variable("zrtp_enabled", val);
-#endif
- }
- }
- }
-
- if ((settings = switch_xml_child(cfg, "variables"))) {
- for (param = switch_xml_child(settings, "variable"); param; param = param->next) {
- const char *var = switch_xml_attr_soft(param, "name");
- const char *val = switch_xml_attr_soft(param, "value");
- if (var && val) {
- switch_core_set_variable(var, val);
- }
- }
- }
-
- switch_xml_free(xml);
- }
-
-
-}
-
-SWITCH_DECLARE(const char *) switch_core_banner(void)
-{
-
-
- return ("\n"
- " _____ ______ _____ _____ ____ _ _ \n"
- " | ___| __ ___ ___/ ___\\ \\ / /_ _|_ _/ ___| | | | \n"
- " | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | | | || | | |_| | \n"
- " | _|| | | __/ __/___) |\\ V V / | | | || |___| _ | \n"
- " |_| |_| \\___|\\___|____/ \\_/\\_/ |___| |_| \\____|_| |_| \n"
- "\n"
- "************************************************************\n"
- "* Anthony Minessale II, Michael Jerris, Brian West, Others *\n"
- "* FreeSWITCH (http://www.freeswitch.org) *\n"
- "* Paypal Donations Appreciated: paypal@freeswitch.org *\n"
- "* Brought to you by ClueCon http://www.cluecon.com/ *\n" "************************************************************\n" "\n");
-}
-
-
-SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err)
-{
- switch_event_t *event;
-
- if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_GENERR;
- }
-
- if (runtime.runlevel > 1) {
- /* one per customer */
- return SWITCH_STATUS_SUCCESS;
- }
-
- runtime.runlevel++;
-
- /* set signal handlers */
- signal(SIGINT, SIG_IGN);
-#ifdef SIGPIPE
- signal(SIGPIPE, handle_SIGPIPE);
-#endif
-#ifdef SIGQUIT
- signal(SIGQUIT, handle_SIGQUIT);
-#endif
-#ifdef SIGPOLL
- signal(SIGPOLL, handle_SIGPOLL);
-#endif
-#ifdef SIGIO
- signal(SIGIO, handle_SIGIO);
-#endif
-#ifdef TRAP_BUS
- signal(SIGBUS, handle_SIGBUS);
-#endif
-#ifdef SIGUSR1
- signal(SIGUSR1, handle_SIGHUP);
-#endif
- signal(SIGHUP, handle_SIGHUP);
-
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");
- if (switch_loadable_module_init() != SWITCH_STATUS_SUCCESS) {
- *err = "Cannot load modules";
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err);
- return SWITCH_STATUS_GENERR;
- }
-
- switch_load_network_lists(SWITCH_FALSE);
-
- switch_load_core_config("post_load_switch.conf");
-
- if (switch_event_create(&event, SWITCH_EVENT_STARTUP) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
- switch_event_fire(&event);
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s", switch_core_banner());
-
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,
- "\nFreeSWITCH Version %s Started.\nMax Sessions[%u]\nSession Rate[%d]\nSQL [%s]\n", SWITCH_VERSION_FULL,
- switch_core_session_limit(0),
- switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled");
-
- switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration)
-{
- switch_time_t temp = total_ms / 1000;
- memset(duration, 0, sizeof(*duration));
- duration->mms = (uint32_t) (total_ms % 1000);
- duration->ms = (uint32_t) (temp % 1000);
- temp = temp / 1000;
- duration->sec = (uint32_t) (temp % 60);
- temp = temp / 60;
- duration->min = (uint32_t) (temp % 60);
- temp = temp / 60;
- duration->hr = (uint32_t) (temp % 24);
- temp = temp / 24;
- duration->day = (uint32_t) (temp % 365);
- duration->yr = (uint32_t) (temp / 365);
-}
-
-SWITCH_DECLARE(switch_time_t) switch_core_uptime(void)
-{
- return switch_micro_time_now() - runtime.initiated;
-}
-
-
-#ifdef _MSC_VER
-static void win_shutdown(void)
-{
-
- HANDLE shutdown_event;
- char path[512];
- /* for windows we need the event to signal for shutting down a background FreeSWITCH */
- snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
-
- /* open the event so we can signal it */
- shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path);
-
- if (shutdown_event) {
- /* signal the event to shutdown */
- SetEvent(shutdown_event);
- /* cleanup */
- CloseHandle(shutdown_event);
- }
-}
-#endif
-
-SWITCH_DECLARE(uint32_t) switch_core_debug_level(void)
-{
- return runtime.debug_level;
-}
-
-
-SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val)
-{
- int *intval = (int *) val;
-
- if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) {
- return -1;
- }
-
- switch (cmd) {
- case SCSC_CALIBRATE_CLOCK:
- switch_time_calibrate_clock();
- break;
- case SCSC_FLUSH_DB_HANDLES:
- switch_cache_db_flush_handles();
- break;
- case SCSC_SEND_SIGHUP:
- handle_SIGHUP(1);
- break;
- case SCSC_SYNC_CLOCK:
- switch_time_sync();
- *intval = 0;
- break;
- case SCSC_PAUSE_INBOUND:
- if (*intval) {
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
- } else {
- switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
- }
- break;
- case SCSC_HUPALL:
- switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST);
- break;
- case SCSC_CANCEL_SHUTDOWN:
- switch_clear_flag((&runtime), SCF_SHUTDOWN_REQUESTED);
- break;
- case SCSC_SAVE_HISTORY:
- switch_console_save_history();
- break;
- case SCSC_CRASH:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n");
- switch_console_save_history();
- abort();
- break;
- case SCSC_SHUTDOWN_NOW:
- switch_console_save_history();
- exit(0);
- break;
- case SCSC_SHUTDOWN_ELEGANT:
- case SCSC_SHUTDOWN_ASAP:
- {
- int x = 19;
- uint32_t count;
-
- switch_set_flag((&runtime), SCF_SHUTDOWN_REQUESTED);
- if (cmd == SCSC_SHUTDOWN_ASAP) {
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
- }
-
- while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) {
- switch_yield(500000);
- if (++x == 20) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
- "Shutdown in progress, %u session(s) remain.\nShutting down %s\n",
- count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls.");
- x = 0;
- }
- }
-
- if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)) {
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
-#ifdef _MSC_VER
- win_shutdown();
-#endif
-
- if (*intval) {
- switch_set_flag((&runtime), SCF_RESTART);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n");
-#ifdef _MSC_VER
- fclose(stdin);
-#endif
- }
- runtime.running = 0;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutdown Cancelled\n");
- switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
- }
- }
- break;
- case SCSC_SHUTDOWN:
-
-#ifdef _MSC_VER
- win_shutdown();
-#endif
-
- if (*intval) {
- switch_set_flag((&runtime), SCF_RESTART);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n");
-#ifdef _MSC_VER
- fclose(stdin);
-#endif
- }
- runtime.running = 0;
- break;
- case SCSC_CHECK_RUNNING:
- *intval = runtime.running;
- break;
- case SCSC_LOGLEVEL:
- if (*intval > -1) {
- runtime.hard_log_level = *intval;
- }
-
- if (runtime.hard_log_level > SWITCH_LOG_DEBUG) {
- runtime.hard_log_level = SWITCH_LOG_DEBUG;
- }
- *intval = runtime.hard_log_level;
- break;
- case SCSC_DEBUG_LEVEL:
- if (*intval > -1) {
- if (*intval > 10)
- *intval = 10;
- runtime.debug_level = *intval;
- }
- *intval = runtime.debug_level;
- break;
- case SCSC_MIN_IDLE_CPU:
- {
- double *dval = (double *) val;
- *dval = switch_core_min_idle_cpu(*dval);
- }
- break;
- case SCSC_MAX_SESSIONS:
- *intval = switch_core_session_limit(*intval);
- break;
- case SCSC_LAST_SPS:
- *intval = runtime.sps_last;
- break;
- case SCSC_MAX_DTMF_DURATION:
- *intval = switch_core_max_dtmf_duration(*intval);
- break;
- case SCSC_MIN_DTMF_DURATION:
- *intval = switch_core_min_dtmf_duration(*intval);
- break;
- case SCSC_DEFAULT_DTMF_DURATION:
- *intval = switch_core_default_dtmf_duration(*intval);
- break;
- case SCSC_SPS:
- switch_mutex_lock(runtime.throttle_mutex);
- if (*intval > 0) {
- runtime.sps_total = *intval;
- }
- *intval = runtime.sps_total;
- switch_mutex_unlock(runtime.throttle_mutex);
- break;
-
- case SCSC_RECLAIM:
- switch_core_memory_reclaim_all();
- *intval = 0;
- break;
- }
-
-
- return 0;
-}
-
-SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void)
-{
- return runtime.flags;
-}
-
-SWITCH_DECLARE(switch_bool_t) switch_core_ready(void)
-{
- return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE;
-}
-
-SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
-{
- switch_event_t *event;
-
- if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down");
- switch_event_fire(&event);
- }
-
- switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
- switch_set_flag((&runtime), SCF_SHUTTING_DOWN);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n");
- switch_core_session_hupall(SWITCH_CAUSE_SYSTEM_SHUTDOWN);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n");
-
- switch_loadable_module_shutdown();
-
- if (switch_test_flag((&runtime), SCF_USE_SQL)) {
- switch_core_sqldb_stop();
- }
- switch_scheduler_task_thread_stop();
-
- switch_rtp_shutdown();
- if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
- switch_nat_shutdown();
- }
- switch_xml_destroy();
-
- switch_console_shutdown();
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n");
- switch_event_shutdown();
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n");
- switch_log_shutdown();
-
- switch_core_unset_variables();
- switch_core_memory_stop();
-
- if (runtime.console && runtime.console != stdout && runtime.console != stderr) {
- fclose(runtime.console);
- runtime.console = NULL;
- }
-
- switch_safe_free(SWITCH_GLOBAL_dirs.base_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.log_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.db_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.script_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir);
- switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir);
-
- switch_core_hash_destroy(&runtime.global_vars);
- switch_core_hash_destroy(&runtime.mime_types);
-
- if (runtime.memory_pool) {
- apr_pool_destroy(runtime.memory_pool);
- apr_terminate();
- }
-
- return switch_test_flag((&runtime), SCF_RESTART) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *name, const char *proto, const char *from, const char *to,
- const char *subject, const char *body, const char *type, const char *hint)
-{
- switch_chat_interface_t *ci;
- switch_status_t status;
-
- if (!name || !(ci = switch_loadable_module_get_chat_interface(name)) || !ci->chat_send) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Chat Interface [%s]!\n", name);
- return SWITCH_STATUS_FALSE;
- }
-
- status = ci->chat_send(proto, from, to, subject, body, type, hint);
-
- UNPROTECT_INTERFACE(ci);
-
- return status;
-}
-
-SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)
-{
- const switch_management_interface_t *ptr;
- switch_status_t status = SWITCH_STATUS_FALSE;
-
- if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) {
- status = ptr->management_function(relative_oid, action, data, datalen);
- }
-
- return status;
-}
-
-SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void)
-{
- switch_core_memory_reclaim_logger();
- switch_core_memory_reclaim_events();
- switch_core_memory_reclaim();
-}
-
-
-struct system_thread_handle {
- const char *cmd;
- switch_thread_cond_t *cond;
- switch_mutex_t *mutex;
- switch_memory_pool_t *pool;
- int ret;
-};
-
-static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj)
-{
- struct system_thread_handle *sth = (struct system_thread_handle *) obj;
-
-#if 0 // if we are a luser we can never turn this back down, didn't we already set the stack size?
-#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
- struct rlimit rlim;
-
- rlim.rlim_cur = SWITCH_SYSTEM_THREAD_STACKSIZE;
- rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
- if (setrlimit(RLIMIT_STACK, &rlim) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
- }
-#endif
-#endif
-
- sth->ret = system(sth->cmd);
-
-#if 0
-#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
- rlim.rlim_cur = SWITCH_THREAD_STACKSIZE;
- rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
- if (setrlimit(RLIMIT_STACK, &rlim) < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
- }
-#endif
-#endif
-
- switch_mutex_lock(sth->mutex);
- switch_thread_cond_signal(sth->cond);
- switch_mutex_unlock(sth->mutex);
-
- switch_core_destroy_memory_pool(&sth->pool);
-
- return NULL;
-}
-
-SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
-{
- switch_thread_t *thread;
- switch_threadattr_t *thd_attr;
- int ret = 0;
- struct system_thread_handle *sth;
- switch_memory_pool_t *pool;
-
- if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
- return 1;
- }
-
- if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle)))) {
- switch_core_destroy_memory_pool(&pool);
- return 1;
- }
-
- sth->pool = pool;
- sth->cmd = switch_core_strdup(pool, cmd);
-
- switch_thread_cond_create(&sth->cond, sth->pool);
- switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool);
- switch_mutex_lock(sth->mutex);
-
- switch_threadattr_create(&thd_attr, sth->pool);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_SYSTEM_THREAD_STACKSIZE);
- switch_threadattr_detach_set(thd_attr, 1);
- switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool);
-
- if (wait) {
- switch_thread_cond_wait(sth->cond, sth->mutex);
- ret = sth->ret;
- }
- switch_mutex_unlock(sth->mutex);
-
- return ret;
-}
-
-
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
- */
diff --git a/src/switch_time.c.orig b/src/switch_time.c.orig
deleted file mode 100644
index cbdc2f8eb1..0000000000
--- a/src/switch_time.c.orig
+++ /dev/null
@@ -1,1962 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2010, Anthony Minessale II
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II
- * Massimo Cetra - Timezone functionality
- *
- *
- * softtimer.c -- Software Timer Module
- *
- */
-
-#include
-#include
-#include "private/switch_core_pvt.h"
-
-//#if defined(DARWIN)
-#define DISABLE_1MS_COND
-//#endif
-
-#ifndef UINT32_MAX
-#define UINT32_MAX 0xffffffff
-#endif
-
-#define MAX_TICK UINT32_MAX - 1024
-
-#define MAX_ELEMENTS 3600
-#define IDLE_SPEED 100
-
-#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
-static int MONO = 1;
-#else
-static int MONO = 0;
-#endif
-
-#if defined(HAVE_CLOCK_NANOSLEEP)
-static int NANO = 1;
-#else
-static int NANO = 0;
-#endif
-
-
-static int OFFSET = 0;
-
-static int COND = 1;
-
-static int MATRIX = 1;
-
-#define ONEMS
-#ifdef ONEMS
-static int STEP_MS = 1;
-static int STEP_MIC = 1000;
-static uint32_t TICK_PER_SEC = 1000;
-static int MS_PER_TICK = 10;
-#else
-static int STEP_MS = 10;
-static int STEP_MIC = 10000;
-static uint32_t TICK_PER_SEC = 1000;
-static int MS_PER_TICK = 10;
-#endif
-
-static switch_memory_pool_t *module_pool = NULL;
-
-static struct {
- int32_t RUNNING;
- int32_t STARTED;
- int32_t use_cond_yield;
- switch_mutex_t *mutex;
- uint32_t timer_count;
-} globals;
-
-#ifdef WIN32
-#undef SWITCH_MOD_DECLARE_DATA
-#define SWITCH_MOD_DECLARE_DATA __declspec(dllexport)
-#endif
-
-SWITCH_MODULE_LOAD_FUNCTION(softtimer_load);
-SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown);
-SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime);
-SWITCH_MODULE_DEFINITION(CORE_SOFTTIMER_MODULE, softtimer_load, softtimer_shutdown, softtimer_runtime);
-
-struct timer_private {
- switch_size_t reference;
- switch_size_t start;
- uint32_t roll;
- uint32_t ready;
-};
-typedef struct timer_private timer_private_t;
-
-struct timer_matrix {
- switch_size_t tick;
- uint32_t count;
- uint32_t roll;
- switch_mutex_t *mutex;
- switch_thread_cond_t *cond;
- switch_thread_rwlock_t *rwlock;
-};
-typedef struct timer_matrix timer_matrix_t;
-
-static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS + 1];
-
-static void os_yield(void)
-{
-#if defined(WIN32)
- SwitchToThread();
-#else
- sched_yield();
-#endif
-}
-
-static void do_sleep(switch_interval_time_t t)
-{
-#if defined(HAVE_CLOCK_NANOSLEEP) || defined(DARWIN)
- struct timespec ts;
-#endif
-
-#if defined(WIN32)
- if (t < 1000) {
- t = 1000;
- }
-#endif
-
-#if !defined(DARWIN)
- if (t > 100000 || !NANO) {
- apr_sleep(t);
- return;
- }
-#endif
-
-#if defined(HAVE_CLOCK_NANOSLEEP)
- t -= OFFSET;
- ts.tv_sec = t / 1000000;
- ts.tv_nsec = ((t % 1000000) * 1000);
- clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
-
-#elif defined(DARWIN)
- ts.tv_sec = t / APR_USEC_PER_SEC;
- ts.tv_nsec = (t % APR_USEC_PER_SEC) * 1000;
- nanosleep(&ts, NULL);
-#else
- apr_sleep(t);
-#endif
-
-#if defined(DARWIN)
- sched_yield();
-#endif
-
-}
-
-static switch_interval_time_t average_time(switch_interval_time_t t, int reps)
-{
- int x = 0;
- switch_time_t start, stop, sum = 0;
-
- for (x = 0; x < reps; x++) {
- start = switch_time_now();
- do_sleep(t);
- stop = switch_time_now();
- sum += (stop - start);
- }
-
- return sum / reps;
-
-}
-
-#define calc_step() if (step > 11) step -= 10; else if (step > 1) step--
-SWITCH_DECLARE(void) switch_time_calibrate_clock(void)
-{
- int x;
- switch_interval_time_t avg, val = 1000, want = 1000;
- int over = 0, under = 0, good = 0, step = 50, diff = 0, retry = 0, lastgood = 0, one_k = 0;
-
-#ifdef HAVE_CLOCK_GETRES
- struct timespec ts;
- long res = 0;
- clock_getres(CLOCK_MONOTONIC, &ts);
- res = ts.tv_nsec / 1000;
-
-
- if (res > 900 && res < 1100) {
- one_k = 1;
- }
-
- if (res > 1500) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
- "Timer resolution of %ld microseconds detected!\n"
- "Do you have your kernel timer frequency set to lower than 1,000Hz? You may experience audio problems.\n", ts.tv_nsec / 1000);
- do_sleep(5000000);
- switch_time_set_cond_yield(SWITCH_TRUE);
- return;
- }
-#endif
-
- top:
- val = 1000;
- step = 50;
- over = under = good = 0;
- OFFSET = 0;
-
- for (x = 0; x < 100; x++) {
- avg = average_time(val, 50);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Test: %ld Average: %ld Step: %d\n", (long) val, (long) avg, step);
-
- diff = abs((int) (want - avg));
- if (diff > 1500) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
- "Abnormally large timer gap %d detected!\n"
- "Do you have your kernel timer frequency set to lower than 1,000Hz? You may experience audio problems.\n", diff);
- do_sleep(5000000);
- switch_time_set_cond_yield(SWITCH_TRUE);
- return;
- }
-
- if (diff <= 100) {
- lastgood = (int) val;
- }
-
- if (diff <= 2) {
- under = over = 0;
- lastgood = (int) val;
- if (++good > 10) {
- break;
- }
- } else if (avg > want) {
- if (under) {
- calc_step();
- }
- under = good = 0;
- if ((val - step) < 0) {
- if (++retry > 2)
- break;
- goto top;
- }
- val -= step;
- over++;
- } else if (avg < want) {
- if (over) {
- calc_step();
- }
- over = good = 0;
- if ((val - step) < 0) {
- if (++retry > 2)
- break;
- goto top;
- }
- val += step;
- under++;
- }
- }
-
- if (good >= 10) {
- OFFSET = (int) (want - val);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset of %d calculated\n", OFFSET);
- } else if (lastgood) {
- OFFSET = (int) (want - lastgood);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset of %d calculated (fallback)\n", OFFSET);
- switch_time_set_cond_yield(SWITCH_TRUE);
- } else if (one_k) {
- OFFSET = 900;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset CANNOT BE DETECTED, forcing OFFSET to 900\n");
- switch_time_set_cond_yield(SWITCH_TRUE);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset NOT calculated\n");
- switch_time_set_cond_yield(SWITCH_TRUE);
- }
-}
-
-
-SWITCH_DECLARE(switch_time_t) switch_micro_time_now(void)
-{
- return (globals.RUNNING == 1 && runtime.timestamp) ? runtime.timestamp : switch_time_now();
-}
-
-
-SWITCH_DECLARE(time_t) switch_epoch_time_now(time_t *t)
-{
- time_t now = switch_micro_time_now() / APR_USEC_PER_SEC;
- if (t) {
- *t = now;
- }
- return now;
-}
-
-SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
-{
- MONO = enable ? 1 : 0;
- switch_time_sync();
-}
-
-
-SWITCH_DECLARE(void) switch_time_set_matrix(switch_bool_t enable)
-{
- MATRIX = enable ? 1 : 0;
- switch_time_sync();
-}
-
-SWITCH_DECLARE(void) switch_time_set_nanosleep(switch_bool_t enable)
-{
-#if defined(HAVE_CLOCK_NANOSLEEP)
- NANO = enable ? 1 : 0;
-#endif
-}
-
-SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable)
-{
- COND = enable ? 1 : 0;
- if (COND) {
- MATRIX = 1;
- }
- switch_time_sync();
-}
-
-static switch_time_t time_now(int64_t offset)
-{
- switch_time_t now;
-
-#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
- if (MONO) {
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset;
- } else {
-#endif
- now = switch_time_now();
-
-#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
- }
-#endif
-
- return now;
-}
-
-SWITCH_DECLARE(void) switch_time_sync(void)
-{
- runtime.reference = switch_time_now();
- runtime.offset = runtime.reference - time_now(0);
- runtime.reference = time_now(runtime.offset);
-}
-
-SWITCH_DECLARE(void) switch_micro_sleep(switch_interval_time_t t)
-{
- do_sleep(t);
-}
-
-SWITCH_DECLARE(void) switch_sleep(switch_interval_time_t t)
-{
-
- if (globals.RUNNING != 1 || t < 1000 || t >= 10000) {
- do_sleep(t);
- return;
- }
-#ifndef DISABLE_1MS_COND
- if (globals.use_cond_yield == 1) {
- switch_cond_yield(t);
- return;
- }
-#endif
-
- do_sleep(t);
-}
-
-
-SWITCH_DECLARE(void) switch_cond_next(void)
-{
- if (globals.timer_count >= runtime.tipping_point) {
- os_yield();
- return;
- }
-#ifdef DISABLE_1MS_COND
- do_sleep(1000);
-#else
- if (globals.RUNNING != 1 || !runtime.timestamp || globals.use_cond_yield != 1) {
- do_sleep(1000);
- return;
- }
- switch_mutex_lock(TIMER_MATRIX[1].mutex);
- switch_thread_cond_wait(TIMER_MATRIX[1].cond, TIMER_MATRIX[1].mutex);
- switch_mutex_unlock(TIMER_MATRIX[1].mutex);
-#endif
-}
-
-SWITCH_DECLARE(void) switch_cond_yield(switch_interval_time_t t)
-{
- switch_time_t want;
- if (!t)
- return;
-
- if (globals.RUNNING != 1 || !runtime.timestamp || globals.use_cond_yield != 1) {
- do_sleep(t);
- return;
- }
- want = runtime.timestamp + t;
- while (globals.RUNNING == 1 && globals.use_cond_yield == 1 && runtime.timestamp < want) {
- switch_mutex_lock(TIMER_MATRIX[1].mutex);
- if (runtime.timestamp < want) {
- switch_thread_cond_wait(TIMER_MATRIX[1].cond, TIMER_MATRIX[1].mutex);
- }
- switch_mutex_unlock(TIMER_MATRIX[1].mutex);
- }
-
-
-}
-
-static switch_status_t timer_init(switch_timer_t *timer)
-{
- timer_private_t *private_info;
- int sanity = 0;
-
- while (globals.STARTED == 0) {
- do_sleep(100000);
- if (++sanity == 300) {
- abort();
- }
- }
-
- if (globals.RUNNING != 1 || !globals.mutex || timer->interval < 1) {
- return SWITCH_STATUS_FALSE;
- }
-
- if ((private_info = switch_core_alloc(timer->memory_pool, sizeof(*private_info)))) {
- switch_mutex_lock(globals.mutex);
- if (!TIMER_MATRIX[timer->interval].mutex) {
- switch_mutex_init(&TIMER_MATRIX[timer->interval].mutex, SWITCH_MUTEX_NESTED, module_pool);
- switch_thread_cond_create(&TIMER_MATRIX[timer->interval].cond, module_pool);
- }
- TIMER_MATRIX[timer->interval].count++;
- switch_mutex_unlock(globals.mutex);
- timer->private_info = private_info;
- private_info->start = private_info->reference = TIMER_MATRIX[timer->interval].tick;
- private_info->roll = TIMER_MATRIX[timer->interval].roll;
- private_info->ready = 1;
-
- if (timer->interval > 0 && timer->interval < MS_PER_TICK) {
- MS_PER_TICK = timer->interval;
- STEP_MS = 1;
- STEP_MIC = 1000;
- TICK_PER_SEC = 10000;
- switch_time_sync();
- }
-
- switch_mutex_lock(globals.mutex);
- globals.timer_count++;
- if (globals.timer_count == (runtime.tipping_point + 1)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Crossed tipping point of %u, shifting into high-gear.\n", runtime.tipping_point);
- }
- switch_mutex_unlock(globals.mutex);
-
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_MEMERR;
-}
-
-#define check_roll() if (private_info->roll < TIMER_MATRIX[timer->interval].roll) { \
- private_info->roll++; \
- private_info->reference = private_info->start = TIMER_MATRIX[timer->interval].tick; \
- } \
-
-
-static switch_status_t timer_step(switch_timer_t *timer)
-{
- timer_private_t *private_info = timer->private_info;
- uint64_t samples;
-
- if (globals.RUNNING != 1 || private_info->ready == 0) {
- return SWITCH_STATUS_FALSE;
- }
-
- check_roll();
- samples = timer->samples * (private_info->reference - private_info->start);
-
- if (samples > UINT32_MAX) {
- private_info->start = private_info->reference;
- samples = timer->samples;
- }
-
- timer->samplecount = (uint32_t) samples;
- private_info->reference++;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t timer_sync(switch_timer_t *timer)
-{
- timer_private_t *private_info = timer->private_info;
-
- if (globals.RUNNING != 1 || private_info->ready == 0) {
- return SWITCH_STATUS_FALSE;
- }
-
- /* sync the clock */
- private_info->reference = timer->tick = TIMER_MATRIX[timer->interval].tick;
-
- /* apply timestamp */
- if (timer_step(timer) == SWITCH_STATUS_SUCCESS) {
- /* push the reference into the future to prevent collision */
- private_info->reference++;
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status_t timer_next(switch_timer_t *timer)
-{
- timer_private_t *private_info = timer->private_info;
-
-#ifdef DISABLE_1MS_COND
- int cond_index = timer->interval;
-#else
- int cond_index = 1;
-#endif
- int delta = (int) (private_info->reference - TIMER_MATRIX[timer->interval].tick);
-
- /* sync up timer if it's not been called for a while otherwise it will return instantly several times until it catches up */
- if (delta < -1) {
- private_info->reference = timer->tick = TIMER_MATRIX[timer->interval].tick;
- }
- timer_step(timer);
-
- if (!MATRIX) {
- do_sleep(1000 * timer->interval);
- goto end;
- }
-
- while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
- check_roll();
-
- if (globals.timer_count >= runtime.tipping_point) {
- os_yield();
- globals.use_cond_yield = 0;
- } else {
- if (globals.use_cond_yield == 1) {
- switch_mutex_lock(TIMER_MATRIX[cond_index].mutex);
- if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
- switch_thread_cond_wait(TIMER_MATRIX[cond_index].cond, TIMER_MATRIX[cond_index].mutex);
- }
- switch_mutex_unlock(TIMER_MATRIX[cond_index].mutex);
- } else {
- do_sleep(1000);
- }
- }
- }
-
- end:
- return globals.RUNNING == 1 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
-}
-
-static switch_status_t timer_check(switch_timer_t *timer, switch_bool_t step)
-{
- timer_private_t *private_info = timer->private_info;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
-
- if (globals.RUNNING != 1 || !private_info->ready) {
- return SWITCH_STATUS_SUCCESS;
- }
-
- check_roll();
-
- timer->tick = TIMER_MATRIX[timer->interval].tick;
-
- if (timer->tick < private_info->reference) {
- timer->diff = private_info->reference - timer->tick;
- } else {
- timer->diff = 0;
- }
-
- if (timer->diff) {
- status = SWITCH_STATUS_FALSE;
- } else if (step) {
- timer_step(timer);
- }
-
-
- return status;
-}
-
-static switch_status_t timer_destroy(switch_timer_t *timer)
-{
- timer_private_t *private_info = timer->private_info;
- if (timer->interval < MAX_ELEMENTS) {
- switch_mutex_lock(globals.mutex);
- TIMER_MATRIX[timer->interval].count--;
- if (TIMER_MATRIX[timer->interval].count == 0) {
- TIMER_MATRIX[timer->interval].tick = 0;
- }
- switch_mutex_unlock(globals.mutex);
- }
- if (private_info) {
- private_info->ready = 0;
- }
-
- switch_mutex_lock(globals.mutex);
- if (globals.timer_count) {
- globals.timer_count--;
- if (globals.timer_count == (runtime.tipping_point - 1)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Fell Below tipping point of %u, shifting into low-gear.\n", runtime.tipping_point);
- }
- }
- switch_mutex_unlock(globals.mutex);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
-{
- switch_time_t too_late = STEP_MIC * 1000;
- uint32_t current_ms = 0;
- uint32_t x, tick = 0;
- switch_time_t ts = 0, last = 0;
- int fwd_errs = 0, rev_errs = 0;
- int profile_tick = 0;
-
- runtime.profile_timer = switch_new_profile_timer();
- switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time);
-
-#ifdef HAVE_CPU_SET_MACROS
- if (runtime.timer_affinity > -1) {
- cpu_set_t set;
- CPU_ZERO(&set);
- CPU_SET(0, &set);
- sched_setaffinity(runtime.timer_affinity, sizeof(set), &set);
- }
-#endif
-
- switch_time_sync();
-
- globals.STARTED = globals.RUNNING = 1;
- switch_mutex_lock(runtime.throttle_mutex);
- runtime.sps = runtime.sps_total;
- switch_mutex_unlock(runtime.throttle_mutex);
-
- if (MONO) {
- int loops;
- for (loops = 0; loops < 3; loops++) {
- ts = time_now(0);
- /* if it returns the same value every time it won't be of much use. */
- if (ts == last) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Broken MONOTONIC Clock Detected!, Support Disabled.\n");
- MONO = 0;
- NANO = 0;
- runtime.reference = switch_time_now();
- runtime.initiated = runtime.reference;
- break;
- }
- do_sleep(STEP_MIC);
- last = ts;
- }
- }
-
- ts = 0;
- last = 0;
- fwd_errs = rev_errs = 0;
-
-#ifndef DISABLE_1MS_COND
- if (!NANO) {
- switch_mutex_init(&TIMER_MATRIX[1].mutex, SWITCH_MUTEX_NESTED, module_pool);
- switch_thread_cond_create(&TIMER_MATRIX[1].cond, module_pool);
- }
-#endif
-
-
- switch_time_sync();
-
- globals.use_cond_yield = COND;
- globals.RUNNING = 1;
-
- while (globals.RUNNING == 1) {
- runtime.reference += STEP_MIC;
- while ((ts = time_now(runtime.offset)) < runtime.reference) {
- if (ts < last) {
- if (MONO) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
- switch_time_sync();
- } else {
- int64_t diff = (int64_t) (ts - last);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Reverse Clock Skew Detected!\n");
- runtime.reference = switch_time_now();
- current_ms = 0;
- tick = 0;
- runtime.initiated += diff;
- rev_errs++;
- }
- } else {
- rev_errs = 0;
- }
-
- if (globals.timer_count >= runtime.tipping_point) {
- os_yield();
- } else {
- do_sleep(1000);
- }
-
- last = ts;
- }
-
- if (ts > (runtime.reference + too_late)) {
- if (MONO) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
- switch_time_sync();
- } else {
- switch_time_t diff = ts - runtime.reference - STEP_MIC;
-#ifndef WIN32
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Forward Clock Skew Detected!\n");
-#endif
- fwd_errs++;
- runtime.reference = switch_time_now();
- current_ms = 0;
- tick = 0;
- runtime.initiated += diff;
- }
- } else {
- fwd_errs = 0;
- }
-
- if (fwd_errs > 9 || rev_errs > 9) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Auto Re-Syncing clock.\n");
- switch_time_sync();
- fwd_errs = rev_errs = 0;
- }
-
- runtime.timestamp = ts;
- current_ms += STEP_MS;
- tick += STEP_MS;
-
- if (tick >= TICK_PER_SEC) {
- if (++profile_tick == 1) {
- switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time);
- profile_tick = 0;
- }
-
- if (runtime.sps <= 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
- }
- switch_mutex_lock(runtime.throttle_mutex);
- runtime.sps_last = runtime.sps_total - runtime.sps;
- runtime.sps = runtime.sps_total;
- switch_mutex_unlock(runtime.throttle_mutex);
- tick = 0;
- }
-#ifndef DISABLE_1MS_COND
- TIMER_MATRIX[1].tick++;
- if (switch_mutex_trylock(TIMER_MATRIX[1].mutex) == SWITCH_STATUS_SUCCESS) {
- switch_thread_cond_broadcast(TIMER_MATRIX[1].cond);
- switch_mutex_unlock(TIMER_MATRIX[1].mutex);
- }
- if (TIMER_MATRIX[1].tick == MAX_TICK) {
- TIMER_MATRIX[1].tick = 0;
- TIMER_MATRIX[1].roll++;
- }
-#endif
-
-
- if (MATRIX && (current_ms % MS_PER_TICK) == 0) {
- for (x = MS_PER_TICK; x <= MAX_ELEMENTS; x += MS_PER_TICK) {
- if ((current_ms % x) == 0) {
- if (TIMER_MATRIX[x].count) {
- TIMER_MATRIX[x].tick++;
-#ifdef DISABLE_1MS_COND
-
- if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) {
- switch_thread_cond_broadcast(TIMER_MATRIX[x].cond);
- switch_mutex_unlock(TIMER_MATRIX[x].mutex);
- }
-#endif
- if (TIMER_MATRIX[x].tick == MAX_TICK) {
- TIMER_MATRIX[x].tick = 0;
- TIMER_MATRIX[x].roll++;
- }
- }
- }
- }
- }
-
- if (current_ms == MAX_ELEMENTS) {
- current_ms = 0;
- }
- }
-
- globals.use_cond_yield = 0;
-
- for (x = MS_PER_TICK; x <= MAX_ELEMENTS; x += MS_PER_TICK) {
- if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) {
- switch_thread_cond_broadcast(TIMER_MATRIX[x].cond);
- switch_mutex_unlock(TIMER_MATRIX[x].mutex);
- }
- }
-
-
- switch_mutex_lock(globals.mutex);
- globals.RUNNING = 0;
- switch_mutex_unlock(globals.mutex);
-
- switch_delete_profile_timer(&runtime.profile_timer);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Soft timer thread exiting.\n");
-
- return SWITCH_STATUS_TERM;
-}
-
-/*
- This converts a struct tm to a switch_time_exp_t
- We have to use UNIX structures to do our exams
- and use switch_* functions for the output.
-*/
-
-static void tm2switchtime(struct tm *tm, switch_time_exp_t *xt)
-{
-
- if (!xt || !tm) {
- return;
- }
- memset(xt, 0, sizeof(xt));
-
- xt->tm_sec = tm->tm_sec;
- xt->tm_min = tm->tm_min;
- xt->tm_hour = tm->tm_hour;
- xt->tm_mday = tm->tm_mday;
- xt->tm_mon = tm->tm_mon;
- xt->tm_year = tm->tm_year;
- xt->tm_wday = tm->tm_wday;
- xt->tm_yday = tm->tm_yday;
- xt->tm_isdst = tm->tm_isdst;
-
-#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
- xt->tm_gmtoff = tm->tm_gmtoff;
-#endif
-
- return;
-}
-
-/* **************************************************************************
- LOADING OF THE XML DATA - HASH TABLE & MEMORY POOL MANAGEMENT
- ************************************************************************** */
-
-typedef struct {
- switch_memory_pool_t *pool;
- switch_hash_t *hash;
-} switch_timezones_list_t;
-
-static switch_timezones_list_t TIMEZONES_LIST = { 0 };
-static switch_event_node_t *NODE = NULL;
-
-const char *switch_lookup_timezone(const char *tz_name)
-{
- char *value = NULL;
-
- if (tz_name && (value = switch_core_hash_find(TIMEZONES_LIST.hash, tz_name)) == NULL) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timezone '%s' not found!\n", tz_name);
- }
-
- return value;
-}
-
-void switch_load_timezones(switch_bool_t reload)
-{
- switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
- unsigned total = 0;
-
- if (TIMEZONES_LIST.hash) {
- switch_core_hash_destroy(&TIMEZONES_LIST.hash);
- }
-
- if (TIMEZONES_LIST.pool) {
- switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool);
- }
-
- memset(&TIMEZONES_LIST, 0, sizeof(TIMEZONES_LIST));
- switch_core_new_memory_pool(&TIMEZONES_LIST.pool);
- switch_core_hash_init(&TIMEZONES_LIST.hash, TIMEZONES_LIST.pool);
-
- if ((xml = switch_xml_open_cfg("timezones.conf", &cfg, NULL))) {
- if ((x_lists = switch_xml_child(cfg, "timezones"))) {
- for (x_list = switch_xml_child(x_lists, "zone"); x_list; x_list = x_list->next) {
- const char *name = switch_xml_attr(x_list, "name");
- const char *value = switch_xml_attr(x_list, "value");
-
- if (zstr(name)) {
- continue;
- }
-
- if (zstr(value)) {
- continue;
- }
-
- switch_core_hash_insert(TIMEZONES_LIST.hash, name, switch_core_strdup(TIMEZONES_LIST.pool, value));
- total++;
- }
- }
-
- switch_xml_free(xml);
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Timezone %sloaded %d definitions\n", reload ? "re" : "", total);
-}
-
-static void event_handler(switch_event_t *event)
-{
- switch_mutex_lock(globals.mutex);
- switch_load_timezones(1);
- switch_mutex_unlock(globals.mutex);
-}
-
-static void tztime(const time_t *const timep, const char *tzstring, struct tm *const tmp);
-
-SWITCH_DECLARE(switch_status_t) switch_time_exp_tz_name(const char *tz, switch_time_exp_t *tm, switch_time_t thetime)
-{
- struct tm xtm = { 0 };
- const char *tz_name = tz;
- const char *tzdef;
- time_t timep;
-
- if (!thetime) {
- thetime = switch_micro_time_now();
- }
-
- timep = (thetime) / (int64_t) (1000000);
-
- if (!zstr(tz_name)) {
- tzdef = switch_lookup_timezone(tz_name);
- } else {
- /* We set the default timezone to GMT. */
- tz_name = "GMT";
- tzdef = "GMT";
- }
-
- if (tzdef) { /* The lookup of the zone may fail. */
- tztime(&timep, tzdef, &xtm);
- tm2switchtime(&xtm, tm);
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_FALSE;
-
-}
-
-SWITCH_DECLARE(switch_status_t) switch_strftime_tz(const char *tz, const char *format, char *date, size_t len, switch_time_t thetime)
-{
- time_t timep;
-
- const char *tz_name = tz;
- const char *tzdef;
-
- switch_size_t retsize;
-
- struct tm tm = { 0 };
- switch_time_exp_t stm;
-
- if (!thetime) {
- thetime = switch_micro_time_now();
- }
-
- timep = (thetime) / (int64_t) (1000000);
-
- if (!zstr(tz_name)) {
- tzdef = switch_lookup_timezone(tz_name);
- } else {
- /* We set the default timezone to GMT. */
- tz_name = "GMT";
- tzdef = "GMT";
- }
-
- if (tzdef) { /* The lookup of the zone may fail. */
- tztime(&timep, tzdef, &tm);
- tm2switchtime(&tm, &stm);
- switch_strftime_nocheck(date, &retsize, len, zstr(format) ? "%Y-%m-%d %T" : format, &stm);
- if (!zstr_buf(date)) {
- return SWITCH_STATUS_SUCCESS;
- }
- }
- return SWITCH_STATUS_FALSE;
-}
-
-SWITCH_MODULE_LOAD_FUNCTION(softtimer_load)
-{
- switch_timer_interface_t *timer_interface;
- module_pool = pool;
-
-#if defined(WIN32)
- timeBeginPeriod(1);
-#endif
-
- memset(&globals, 0, sizeof(globals));
- switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool);
-
- if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
- }
- switch_load_timezones(0);
-
- /* connect my internal structure to the blank pointer passed to me */
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
- timer_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_TIMER_INTERFACE);
- timer_interface->interface_name = "soft";
- timer_interface->timer_init = timer_init;
- timer_interface->timer_next = timer_next;
- timer_interface->timer_step = timer_step;
- timer_interface->timer_sync = timer_sync;
- timer_interface->timer_check = timer_check;
- timer_interface->timer_destroy = timer_destroy;
-
- if (!switch_test_flag((&runtime), SCF_USE_CLOCK_RT)) {
- switch_time_set_nanosleep(SWITCH_FALSE);
- }
-
- if (switch_test_flag((&runtime), SCF_USE_HEAVY_TIMING)) {
- switch_time_set_cond_yield(SWITCH_FALSE);
- }
-
- if (switch_test_flag((&runtime), SCF_CALIBRATE_CLOCK)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n");
- switch_time_calibrate_clock();
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clock calibration disabled.\n");
- }
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown)
-{
- globals.use_cond_yield = 0;
-
- if (globals.RUNNING == 1) {
- switch_mutex_lock(globals.mutex);
- globals.RUNNING = -1;
- switch_mutex_unlock(globals.mutex);
-
- while (globals.RUNNING == -1) {
- do_sleep(10000);
- }
- }
-#if defined(WIN32)
- timeEndPeriod(1);
-#endif
-
- if (TIMEZONES_LIST.hash) {
- switch_core_hash_destroy(&TIMEZONES_LIST.hash);
- }
-
- if (TIMEZONES_LIST.pool) {
- switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-
-
-/*
- * This file was originally written for NetBSD and is in the public domain,
- * so clarified as of 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
- *
- * Iw was modified by Massimo Cetra in order to be used with Callweaver and Freeswitch.
- */
-
-//#define TESTING_IT 1
-
-#include
-#include
-#include
-#include
-#include
-
-
-#ifdef TESTING_IT
-#include
-#endif
-
-
-#ifndef TRUE
-#define TRUE 1
-#endif /* !defined TRUE */
-
-#ifndef FALSE
-#define FALSE 0
-#endif /* !defined FALSE */
-
-
-
-#ifndef TZ_MAX_TIMES
-/*
-** The TZ_MAX_TIMES value below is enough to handle a bit more than a
-** year's worth of solar time (corrected daily to the nearest second) or
-** 138 years of Pacific Presidential Election time
-** (where there are three time zone transitions every fourth year).
-*/
-#define TZ_MAX_TIMES 370
-#endif /* !defined TZ_MAX_TIMES */
-
-#ifndef TZ_MAX_TYPES
-
-#ifndef NOSOLAR
-#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
-#endif /* !defined NOSOLAR */
-
-#ifdef NOSOLAR
-/*
-** Must be at least 14 for Europe/Riga as of Jan 12 1995,
-** as noted by Earl Chew .
-*/
-#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
-#endif /* !defined NOSOLAR */
-
-#endif /* !defined TZ_MAX_TYPES */
-
-#ifndef TZ_MAX_CHARS
-#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
- /* (limited by what unsigned chars can hold) */
-#endif /* !defined TZ_MAX_CHARS */
-
-#ifndef TZ_MAX_LEAPS
-#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
-#endif /* !defined TZ_MAX_LEAPS */
-
-#ifdef TZNAME_MAX
-#define MY_TZNAME_MAX TZNAME_MAX
-#endif /* defined TZNAME_MAX */
-
-#ifndef TZNAME_MAX
-#define MY_TZNAME_MAX 255
-#endif /* !defined TZNAME_MAX */
-
-
-#define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
-#define DAYSPERNYEAR 365
-#define DAYSPERLYEAR 366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
-
-#define JULIAN_DAY 0 /* Jn - Julian day */
-#define DAY_OF_YEAR 1 /* n - day of year */
-#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
-
-#define EPOCH_YEAR 1970
-#define EPOCH_WDAY TM_THURSDAY
-
-
-#ifndef TZ_MAX_TIMES
-/*
-** The TZ_MAX_TIMES value below is enough to handle a bit more than a
-** year's worth of solar time (corrected daily to the nearest second) or
-** 138 years of Pacific Presidential Election time
-** (where there are three time zone transitions every fourth year).
-*/
-#define TZ_MAX_TIMES 370
-#endif /* !defined TZ_MAX_TIMES */
-
-#ifndef TZDEFRULES
-#define TZDEFRULES "posixrules"
-#endif /* !defined TZDEFRULES */
-
-/*
-** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
-** We default to US rules as of 1999-08-17.
-** POSIX 1003.1 section 8.1.1 says that the default DST rules are
-** implementation dependent; for historical reasons, US rules are a
-** common default.
-*/
-#ifndef TZDEFRULESTRING
-#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
-#endif /* !defined TZDEFDST */
-
-/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */
-#define is_digit(c) ((unsigned)(c) - '0' <= 9)
-
-#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
-
-#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
-
-
-
-/*
-** INITIALIZE(x)
-*/
-
-#ifndef GNUC_or_lint
-#ifdef lint
-#define GNUC_or_lint
-#endif /* defined lint */
-#ifndef lint
-#ifdef __GNUC__
-#define GNUC_or_lint
-#endif /* defined __GNUC__ */
-#endif /* !defined lint */
-#endif /* !defined GNUC_or_lint */
-#ifdef WIN32
-#define GNUC_or_lint
-#endif
-
-#ifndef INITIALIZE
-#ifdef GNUC_or_lint
-#define INITIALIZE(x) ((x) = 0)
-#endif /* defined GNUC_or_lint */
-#ifndef GNUC_or_lint
-#define INITIALIZE(x)
-#endif /* !defined GNUC_or_lint */
-#endif /* !defined INITIALIZE */
-
-
-#define TM_SUNDAY 0
-#define TM_MONDAY 1
-#define TM_TUESDAY 2
-#define TM_WEDNESDAY 3
-#define TM_THURSDAY 4
-#define TM_FRIDAY 5
-#define TM_SATURDAY 6
-
-#define TM_JANUARY 0
-#define TM_FEBRUARY 1
-#define TM_MARCH 2
-#define TM_APRIL 3
-#define TM_MAY 4
-#define TM_JUNE 5
-#define TM_JULY 6
-#define TM_AUGUST 7
-#define TM_SEPTEMBER 8
-#define TM_OCTOBER 9
-#define TM_NOVEMBER 10
-#define TM_DECEMBER 11
-
-#define TM_YEAR_BASE 1900
-
-#define EPOCH_YEAR 1970
-#define EPOCH_WDAY TM_THURSDAY
-
-
-/* **************************************************************************
-
- ************************************************************************** */
-
-static const char gmt[] = "GMT";
-
-#define CHARS_DEF BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))
-
-struct rule {
- int r_type; /* type of rule--see below */
- int r_day; /* day number of rule */
- int r_week; /* week number of rule */
- int r_mon; /* month number of rule */
- long r_time; /* transition time of rule */
-};
-
-struct ttinfo { /* time type information */
- long tt_gmtoff; /* UTC offset in seconds */
- int tt_isdst; /* used to set tm_isdst */
- int tt_abbrind; /* abbreviation list index */
- int tt_ttisstd; /* TRUE if transition is std time */
- int tt_ttisgmt; /* TRUE if transition is UTC */
-};
-
-struct lsinfo { /* leap second information */
- time_t ls_trans; /* transition time */
- long ls_corr; /* correction to apply */
-};
-
-
-struct state {
- int leapcnt;
- int timecnt;
- int typecnt;
- int charcnt;
- time_t ats[TZ_MAX_TIMES];
- unsigned char types[TZ_MAX_TIMES];
- struct ttinfo ttis[TZ_MAX_TYPES];
- char chars[ /* LINTED constant */ CHARS_DEF];
- struct lsinfo lsis[TZ_MAX_LEAPS];
-};
-
-
-static const int mon_lengths[2][MONSPERYEAR] = {
- {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
- {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
-};
-
-static const int year_lengths[2] = {
- DAYSPERNYEAR, DAYSPERLYEAR
-};
-
-
-/* **************************************************************************
-
- ************************************************************************** */
-
-
-/*
- Given a pointer into a time zone string, scan until a character that is not
- a valid character in a zone name is found. Return a pointer to that
- character.
-*/
-
-static const char *getzname(register const char *strp)
-{
- register char c;
-
- while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && c != '+')
- ++strp;
- return strp;
-}
-
-
-/*
- Given a pointer into a time zone string, extract a number from that string.
- Check that the number is within a specified range; if it is not, return
- NULL.
- Otherwise, return a pointer to the first character not part of the number.
-*/
-
-static const char *getnum(register const char *strp, int *const nump, const int min, const int max)
-{
- register char c;
- register int num;
-
- if (strp == NULL || !is_digit(c = *strp))
- return NULL;
- num = 0;
- do {
- num = num * 10 + (c - '0');
- if (num > max)
- return NULL; /* illegal value */
- c = *++strp;
- } while (is_digit(c));
- if (num < min)
- return NULL; /* illegal value */
- *nump = num;
- return strp;
-}
-
-/*
- Given a pointer into a time zone string, extract a number of seconds,
- in hh[:mm[:ss]] form, from the string.
- If any error occurs, return NULL.
- Otherwise, return a pointer to the first character not part of the number
- of seconds.
-*/
-
-static const char *getsecs(register const char *strp, long *const secsp)
-{
- int num;
-
- /*
- ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
- ** "M10.4.6/26", which does not conform to Posix,
- ** but which specifies the equivalent of
- ** ``02:00 on the first Sunday on or after 23 Oct''.
- */
- strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
- if (strp == NULL)
- return NULL;
- *secsp = num * (long) SECSPERHOUR;
- if (*strp == ':') {
- ++strp;
- strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
- if (strp == NULL)
- return NULL;
- *secsp += num * SECSPERMIN;
- if (*strp == ':') {
- ++strp;
- /* `SECSPERMIN' allows for leap seconds. */
- strp = getnum(strp, &num, 0, SECSPERMIN);
- if (strp == NULL)
- return NULL;
- *secsp += num;
- }
- }
- return strp;
-}
-
-/*
- Given a pointer into a time zone string, extract an offset, in
- [+-]hh[:mm[:ss]] form, from the string.
- If any error occurs, return NULL.
- Otherwise, return a pointer to the first character not part of the time.
-*/
-
-static const char *getoffset(register const char *strp, long *const offsetp)
-{
- register int neg = 0;
-
- if (*strp == '-') {
- neg = 1;
- ++strp;
- } else if (*strp == '+')
- ++strp;
- strp = getsecs(strp, offsetp);
- if (strp == NULL)
- return NULL; /* illegal time */
- if (neg)
- *offsetp = -*offsetp;
- return strp;
-}
-
-/*
- Given a pointer into a time zone string, extract a rule in the form
- date[/time]. See POSIX section 8 for the format of "date" and "time".
- If a valid rule is not found, return NULL.
- Otherwise, return a pointer to the first character not part of the rule.
-*/
-
-static const char *getrule(const char *strp, register struct rule *const rulep)
-{
- if (*strp == 'J') {
- /*
- ** Julian day.
- */
- rulep->r_type = JULIAN_DAY;
- ++strp;
- strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
- } else if (*strp == 'M') {
- /*
- ** Month, week, day.
- */
- rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
- ++strp;
- strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
- if (strp == NULL)
- return NULL;
- if (*strp++ != '.')
- return NULL;
- strp = getnum(strp, &rulep->r_week, 1, 5);
- if (strp == NULL)
- return NULL;
- if (*strp++ != '.')
- return NULL;
- strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
- } else if (is_digit(*strp)) {
- /*
- ** Day of year.
- */
- rulep->r_type = DAY_OF_YEAR;
- strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
- } else
- return NULL; /* invalid format */
- if (strp == NULL)
- return NULL;
- if (*strp == '/') {
- /*
- ** Time specified.
- */
- ++strp;
- strp = getsecs(strp, &rulep->r_time);
- } else
- rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
- return strp;
-}
-
-
-/*
- Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
- year, a rule, and the offset from UTC at the time that rule takes effect,
- calculate the Epoch-relative time that rule takes effect.
-*/
-
-static time_t transtime(const time_t janfirst, const int year, register const struct rule *const rulep, const long offset)
-{
- register int leapyear;
- register time_t value;
- register int i;
- int d, m1, yy0, yy1, yy2, dow;
-
- INITIALIZE(value);
- leapyear = isleap(year);
- switch (rulep->r_type) {
-
- case JULIAN_DAY:
- /*
- ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
- ** years.
- ** In non-leap years, or if the day number is 59 or less, just
- ** add SECSPERDAY times the day number-1 to the time of
- ** January 1, midnight, to get the day.
- */
- value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
- if (leapyear && rulep->r_day >= 60)
- value += SECSPERDAY;
- break;
-
- case DAY_OF_YEAR:
- /*
- ** n - day of year.
- ** Just add SECSPERDAY times the day number to the time of
- ** January 1, midnight, to get the day.
- */
- value = janfirst + rulep->r_day * SECSPERDAY;
- break;
-
- case MONTH_NTH_DAY_OF_WEEK:
- /*
- ** Mm.n.d - nth "dth day" of month m.
- */
- value = janfirst;
- for (i = 0; i < rulep->r_mon - 1; ++i)
- value += mon_lengths[leapyear][i] * SECSPERDAY;
-
- /*
- ** Use Zeller's Congruence to get day-of-week of first day of
- ** month.
- */
- m1 = (rulep->r_mon + 9) % 12 + 1;
- yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
- yy1 = yy0 / 100;
- yy2 = yy0 % 100;
- dow = ((26 * m1 - 2) / 10 + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
- if (dow < 0)
- dow += DAYSPERWEEK;
-
- /*
- ** "dow" is the day-of-week of the first day of the month. Get
- ** the day-of-month (zero-origin) of the first "dow" day of the
- ** month.
- */
- d = rulep->r_day - dow;
- if (d < 0)
- d += DAYSPERWEEK;
- for (i = 1; i < rulep->r_week; ++i) {
- if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1])
- break;
- d += DAYSPERWEEK;
- }
-
- /*
- ** "d" is the day-of-month (zero-origin) of the day we want.
- */
- value += d * SECSPERDAY;
- break;
- }
-
- /*
- ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
- ** question. To get the Epoch-relative time of the specified local
- ** time on that day, add the transition time and the current offset
- ** from UTC.
- */
- return value + rulep->r_time + offset;
-}
-
-
-
-/*
- Given a POSIX section 8-style TZ string, fill in the rule tables as
- appropriate.
-*/
-
-static int tzparse(const char *name, register struct state *const sp, const int lastditch)
-{
- const char *stdname;
- const char *dstname;
- size_t stdlen;
- size_t dstlen;
- long stdoffset;
- long dstoffset;
- register time_t *atp;
- register unsigned char *typep;
- register char *cp;
-
-
- INITIALIZE(dstname);
- stdname = name;
-
- if (lastditch) {
- stdlen = strlen(name); /* length of standard zone name */
- name += stdlen;
- if (stdlen >= sizeof sp->chars)
- stdlen = (sizeof sp->chars) - 1;
- stdoffset = 0;
- } else {
- name = getzname(name);
- stdlen = name - stdname;
- if (stdlen < 3)
- return -1;
- if (*name == '\0')
- return -1;
- name = getoffset(name, &stdoffset);
- if (name == NULL)
- return -1;
- }
-
- sp->leapcnt = 0; /* so, we're off a little */
-
- if (*name != '\0') {
- dstname = name;
- name = getzname(name);
- dstlen = name - dstname; /* length of DST zone name */
- if (dstlen < 3)
- return -1;
- if (*name != '\0' && *name != ',' && *name != ';') {
- name = getoffset(name, &dstoffset);
- if (name == NULL)
- return -1;
- } else
- dstoffset = stdoffset - SECSPERHOUR;
-
- /* Go parsing the daylight saving stuff */
- if (*name == ',' || *name == ';') {
- struct rule start;
- struct rule end;
- register int year;
- register time_t janfirst;
- time_t starttime;
- time_t endtime;
-
- ++name;
- if ((name = getrule(name, &start)) == NULL)
- return -1;
- if (*name++ != ',')
- return -1;
- if ((name = getrule(name, &end)) == NULL)
- return -1;
- if (*name != '\0')
- return -1;
-
- sp->typecnt = 2; /* standard time and DST */
-
- /*
- ** Two transitions per year, from EPOCH_YEAR to 2037.
- */
- sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
-
- if (sp->timecnt > TZ_MAX_TIMES)
- return -1;
-
- sp->ttis[0].tt_gmtoff = -dstoffset;
- sp->ttis[0].tt_isdst = 1;
- sp->ttis[0].tt_abbrind = (int) (stdlen + 1);
- sp->ttis[1].tt_gmtoff = -stdoffset;
- sp->ttis[1].tt_isdst = 0;
- sp->ttis[1].tt_abbrind = 0;
-
- atp = sp->ats;
- typep = sp->types;
- janfirst = 0;
-
- for (year = EPOCH_YEAR; year <= 2037; ++year) {
- starttime = transtime(janfirst, year, &start, stdoffset);
- endtime = transtime(janfirst, year, &end, dstoffset);
- if (starttime > endtime) {
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- } else {
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- }
-
- janfirst += year_lengths[isleap(year)] * SECSPERDAY;
- }
-
- } else {
- register long theirstdoffset;
- register long theirdstoffset;
- register long theiroffset;
- register int isdst;
- register int i;
- register int j;
-
- if (*name != '\0')
- return -1;
- /*
- Initial values of theirstdoffset and theirdstoffset.
- */
- theirstdoffset = 0;
- for (i = 0; i < sp->timecnt; ++i) {
- j = sp->types[i];
- if (!sp->ttis[j].tt_isdst) {
- theirstdoffset = -sp->ttis[j].tt_gmtoff;
- break;
- }
- }
- theirdstoffset = 0;
- for (i = 0; i < sp->timecnt; ++i) {
- j = sp->types[i];
- if (sp->ttis[j].tt_isdst) {
- theirdstoffset = -sp->ttis[j].tt_gmtoff;
- break;
- }
- }
- /*
- ** Initially we're assumed to be in standard time.
- */
- isdst = FALSE;
- theiroffset = theirstdoffset;
- /*
- ** Now juggle transition times and types
- ** tracking offsets as you do.
- */
- for (i = 0; i < sp->timecnt; ++i) {
- j = sp->types[i];
- sp->types[i] = (unsigned char) sp->ttis[j].tt_isdst;
- if (sp->ttis[j].tt_ttisgmt) {
- /* No adjustment to transition time */
- } else {
- /*
- ** If summer time is in effect, and the
- ** transition time was not specified as
- ** standard time, add the summer time
- ** offset to the transition time;
- ** otherwise, add the standard time
- ** offset to the transition time.
- */
- /*
- ** Transitions from DST to DDST
- ** will effectively disappear since
- ** POSIX provides for only one DST
- ** offset.
- */
- if (isdst && !sp->ttis[j].tt_ttisstd) {
- sp->ats[i] += dstoffset - theirdstoffset;
- } else {
- sp->ats[i] += stdoffset - theirstdoffset;
- }
- }
- theiroffset = -sp->ttis[j].tt_gmtoff;
- if (sp->ttis[j].tt_isdst)
- theirdstoffset = theiroffset;
- else
- theirstdoffset = theiroffset;
- }
- /*
- ** Finally, fill in ttis.
- ** ttisstd and ttisgmt need not be handled.
- */
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = FALSE;
- sp->ttis[0].tt_abbrind = 0;
- sp->ttis[1].tt_gmtoff = -dstoffset;
- sp->ttis[1].tt_isdst = TRUE;
- sp->ttis[1].tt_abbrind = (int) (stdlen + 1);
- sp->typecnt = 2;
- }
- } else {
- dstlen = 0;
- sp->typecnt = 1; /* only standard time */
- sp->timecnt = 0;
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = 0;
- sp->ttis[0].tt_abbrind = 0;
- }
-
- sp->charcnt = (int) (stdlen + 1);
- if (dstlen != 0)
- sp->charcnt += (int) (dstlen + 1);
- if ((size_t) sp->charcnt > sizeof sp->chars)
- return -1;
- cp = sp->chars;
- (void) strncpy(cp, stdname, stdlen);
- cp += stdlen;
- *cp++ = '\0';
- if (dstlen != 0) {
- (void) strncpy(cp, dstname, dstlen);
- *(cp + dstlen) = '\0';
- }
- return 0;
-}
-
-/* **************************************************************************
-
- ************************************************************************** */
-#if (_MSC_VER >= 1400) // VC8+
-#define switch_assert(expr) assert(expr);__analysis_assume( expr )
-#else
-#define switch_assert(expr) assert(expr)
-#endif
-
-static void timesub(const time_t *const timep, const long offset, register const struct state *const sp, register struct tm *const tmp)
-{
- register const struct lsinfo *lp;
- register long days;
- register time_t rem;
- register int y;
- register int yleap;
- register const int *ip;
- register long corr;
- register int hit;
- register int i;
-
- switch_assert(timep != NULL);
- switch_assert(sp != NULL);
- switch_assert(tmp != NULL);
-
- corr = 0;
- hit = 0;
- i = (sp == NULL) ? 0 : sp->leapcnt;
-
- while (--i >= 0) {
- lp = &sp->lsis[i];
- if (*timep >= lp->ls_trans) {
- if (*timep == lp->ls_trans) {
- hit = ((i == 0 && lp->ls_corr > 0) || (i > 0 && lp->ls_corr > sp->lsis[i - 1].ls_corr));
- if (hit)
- while (i > 0 && sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 && sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1) {
- ++hit;
- --i;
- }
- }
- corr = lp->ls_corr;
- break;
- }
- }
- days = (long) (*timep / SECSPERDAY);
- rem = *timep % SECSPERDAY;
-
-
-#ifdef mc68k
- /* If this is for CPU bugs workarounds, i would remove this anyway. Who would use it on an old mc68k ? */
- if (*timep == 0x80000000) {
- /*
- ** A 3B1 muffs the division on the most negative number.
- */
- days = -24855;
- rem = -11648;
- }
-#endif
-
- rem += (offset - corr);
- while (rem < 0) {
- rem += SECSPERDAY;
- --days;
- }
- while (rem >= SECSPERDAY) {
- rem -= SECSPERDAY;
- ++days;
- }
- tmp->tm_hour = (int) (rem / SECSPERHOUR);
- rem = rem % SECSPERHOUR;
- tmp->tm_min = (int) (rem / SECSPERMIN);
-
- /*
- ** A positive leap second requires a special
- ** representation. This uses "... ??:59:60" et seq.
- */
- tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
- tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
-
- if (tmp->tm_wday < 0)
- tmp->tm_wday += DAYSPERWEEK;
-
- y = EPOCH_YEAR;
-
-#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
-
- while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
- register int newy;
-
- newy = (int) (y + days / DAYSPERNYEAR);
- if (days < 0)
- --newy;
- days -= (newy - y) * DAYSPERNYEAR + LEAPS_THRU_END_OF(newy - 1) - LEAPS_THRU_END_OF(y - 1);
- y = newy;
- }
-
- tmp->tm_year = y - TM_YEAR_BASE;
- tmp->tm_yday = (int) days;
-
- ip = mon_lengths[yleap];
-
- for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
- days = days - (long) ip[tmp->tm_mon];
-
- tmp->tm_mday = (int) (days + 1);
- tmp->tm_isdst = 0;
-#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
- tmp->tm_gmtoff = offset;
-#endif
-}
-
-/* **************************************************************************
-
- ************************************************************************** */
-
-static void tztime(const time_t *const timep, const char *tzstring, struct tm *const tmp)
-{
- struct state *tzptr, *sp;
- const time_t t = *timep;
- register int i;
- register const struct ttinfo *ttisp;
-
- if (tzstring == NULL)
- tzstring = gmt;
-
- tzptr = (struct state *) malloc(sizeof(struct state));
- sp = tzptr;
-
- if (tzptr != NULL) {
-
- memset(tzptr, 0, sizeof(struct state));
-
- (void) tzparse(tzstring, tzptr, FALSE);
-
- if (sp->timecnt == 0 || t < sp->ats[0]) {
- i = 0;
- while (sp->ttis[i].tt_isdst)
- if (++i >= sp->typecnt) {
- i = 0;
- break;
- }
- } else {
- for (i = 1; i < sp->timecnt; ++i)
- if (t < sp->ats[i])
- break;
- i = sp->types[i - 1]; // DST begin or DST end
- }
- ttisp = &sp->ttis[i];
-
- /*
- To get (wrong) behavior that's compatible with System V Release 2.0
- you'd replace the statement below with
- t += ttisp->tt_gmtoff;
- timesub(&t, 0L, sp, tmp);
- */
- if (tmp != NULL) { /* Just a check not to assert */
- timesub(&t, ttisp->tt_gmtoff, sp, tmp);
- tmp->tm_isdst = ttisp->tt_isdst;
-#if defined(HAVE_STRUCT_TM_TM_ZONE)
- tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
-#endif
- }
-
- free(tzptr);
- }
-
-}
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
- */
diff --git a/src/switch_utils.c b/src/switch_utils.c
index e059d6ca08..842977acf9 100644
--- a/src/switch_utils.c
+++ b/src/switch_utils.c
@@ -1331,7 +1331,7 @@ static const char *switch_inet_ntop4(const unsigned char *src, char *dst, size_t
return strcpy(dst, tmp);
}
-#if HAVE_SIN6 || (defined(NTDDI_VERSION) && (NTDDI_VERSION < NTDDI_VISTA))
+#if HAVE_SIN6 || defined(NTDDI_VERSION)
/* const char *
* inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
@@ -1488,7 +1488,7 @@ SWITCH_DECLARE(char *) get_addr6(char *buf, switch_size_t len, struct sockaddr_i
*buf = '\0';
if (sa) {
-#if defined(NTDDI_VERSION) && (NTDDI_VERSION < NTDDI_VISTA)
+#if defined(NTDDI_VERSION)
switch_inet_ntop6((unsigned char*)sa, buf, len);
#else
inet_ntop(AF_INET6, sa, buf, len);