SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, switch_scheduler_func_t func, const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags) { switch_scheduler_task_container_t *container, *tp; switch_event_t *event; switch_time_t now = switch_epoch_time_now(NULL); switch_mutex_lock(globals.task_mutex); switch_zmalloc(container, sizeof(*container)); switch_assert(func); if (task_runtime < now) { container->task.repeat = (uint32_t)task_runtime; task_runtime += now; } container->func = func; container->task.created = switch_epoch_time_now(NULL); container->task.runtime = task_runtime; container->task.group = strdup(group ? group : "none"); container->task.cmd_id = cmd_id; container->task.cmd_arg = cmd_arg; container->flags = flags; container->desc = strdup(desc ? desc : "none"); for (tp = globals.task_list; tp && tp->next; tp = tp->next); if (tp) { tp->next = container; } else { globals.task_list = container; } for (container->task.task_id = 0; !container->task.task_id; container->task.task_id = ++globals.task_id); switch_mutex_unlock(globals.task_mutex); tp = container; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Added task %u %s (%s) to run at %" SWITCH_INT64_T_FMT "\n", tp->task.task_id, tp->desc, switch_str_nil(tp->task.group), tp->task.runtime); if (switch_event_create(&event, SWITCH_EVENT_ADD_SCHEDULE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Desc", tp->desc); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Group", switch_str_nil(tp->task.group)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" SWITCH_INT64_T_FMT, tp->task.runtime); switch_event_fire(&event); } return container->task.task_id; }
static void switch_scheduler_execute(switch_scheduler_task_container_t *tp) { switch_event_t *event; //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing task %u %s (%s)\n", tp->task.task_id, tp->desc, switch_str_nil(tp->task.group)); tp->func(&tp->task); if (tp->task.repeat) { tp->task.runtime = switch_epoch_time_now(NULL) + tp->task.repeat; } if (tp->task.runtime > tp->executed) { tp->executed = 0; if (switch_event_create(&event, SWITCH_EVENT_RE_SCHEDULE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Desc", tp->desc); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Group", switch_str_nil(tp->task.group)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" SWITCH_INT64_T_FMT, tp->task.runtime); switch_queue_push(globals.event_queue, event); event = NULL; } } else { tp->destroyed = 1; } }
static int find_longest(valet_lot_t *lot, int min, int max) { switch_hash_index_t *i_hi; const void *i_var; void *i_val; valet_token_t *token; int longest = 0, cur = 0, longest_ext = 0; time_t now = switch_epoch_time_now(NULL); switch_mutex_lock(lot->mutex); for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) { int i; switch_hash_this(i_hi, &i_var, NULL, &i_val); token = (valet_token_t *) i_val; cur = (now - token->start_time); i = atoi(token->ext); if (cur > longest && i >= min && i <= max) { longest = cur; longest_ext = i; } } switch_mutex_unlock(lot->mutex); return longest_ext; }
static valet_token_t *next_id(switch_core_session_t *session, valet_lot_t *lot, int min, int max, int in) { int i, r = 0; char buf[256] = ""; valet_token_t *token; if (!min) { min = 1; } switch_mutex_lock(globals.mutex); if (!in) { int longest = find_longest(lot, min, max); if (longest > 0) { switch_snprintf(buf, sizeof(buf), "%d", longest); switch_mutex_lock(lot->mutex); token = (valet_token_t *) switch_core_hash_find(lot->hash, buf); switch_mutex_unlock(lot->mutex); if (token) { goto end; } } } for (i = min; (i < max || max == 0); i++) { switch_snprintf(buf, sizeof(buf), "%d", i); switch_mutex_lock(lot->mutex); token = (valet_token_t *) switch_core_hash_find(lot->hash, buf); switch_mutex_unlock(lot->mutex); if ((!in && token && !token->timeout)) { goto end; } if (in && !token) { r = i; break; } } token = NULL; if (r) { switch_snprintf(buf, sizeof(buf), "%d", r); switch_zmalloc(token, sizeof(*token)); switch_set_string(token->uuid, switch_core_session_get_uuid(session)); switch_set_string(token->ext, buf); token->start_time = switch_epoch_time_now(NULL); switch_mutex_lock(lot->mutex); switch_core_hash_insert(lot->hash, buf, token); switch_mutex_unlock(lot->mutex); } end: switch_mutex_unlock(globals.mutex); return token; }
SWITCH_DECLARE(void) switch_nat_late_init(void) { if (nat_globals_perm.running == 1) { switch_scheduler_add_task(switch_epoch_time_now(NULL) + NAT_REFRESH_INTERVAL, switch_nat_republish_sched, "nat_republish", "core", 0, NULL, SSHF_OWN_THREAD); } }
static switch_status_t do_snap(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_media_bug_t *bug = switch_channel_get_private(channel, "snapshot"); char *file; switch_file_handle_t fh = { 0 }; switch_codec_implementation_t read_impl = { 0 }; switch_size_t bytes_read; int16_t pdata[4096] = { 0 }; if (bug) { switch_time_exp_t tm; switch_size_t retsize; char date[80] = ""; struct cap_cb *cb = (struct cap_cb *) switch_core_media_bug_get_user_data(bug); if (!cb) { return SWITCH_STATUS_FALSE; } switch_time_exp_lt(&tm, switch_time_make(switch_epoch_time_now(NULL), 0)); switch_strftime(date, &retsize, sizeof(date), "%Y_%m_%d_%H_%M_%S", &tm); file = switch_core_session_sprintf(session, "%s%s%s_%s.wav", SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_PATH_SEPARATOR, cb->base, date); switch_core_session_get_read_impl(session, &read_impl); fh.channels = 0; fh.native_rate = read_impl.actual_samples_per_second; if (switch_core_file_open(&fh, file, 0, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", file); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); return SWITCH_STATUS_FALSE; } switch_mutex_lock(cb->mutex); while ((bytes_read = switch_buffer_read(cb->buffer, pdata, sizeof(pdata)))) { switch_size_t samples = bytes_read / 2; if (switch_core_file_write(&fh, pdata, &samples) != SWITCH_STATUS_SUCCESS) { break; } } switch_mutex_unlock(cb->mutex); switch_core_file_close(&fh); switch_core_set_variable("file", file); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Wrote %s\n", file); return SWITCH_STATUS_SUCCESS; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Bug is not attached.\n", switch_channel_get_name(channel)); return SWITCH_STATUS_FALSE; }
static void check_timeouts(void) { switch_hash_index_t *hi; const void *var; void *val; time_t now; valet_lot_t *lot; switch_console_callback_match_t *matches = NULL; switch_console_callback_match_node_t *m; switch_hash_index_t *i_hi; const void *i_var; void *i_val; char *i_ext; valet_token_t *token; now = switch_epoch_time_now(NULL); switch_mutex_lock(globals.mutex); if (now - globals.last_timeout_check < TOKEN_FREQ) { switch_mutex_unlock(globals.mutex); return; } globals.last_timeout_check = now; for (hi = switch_hash_first(NULL, globals.hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); switch_console_push_match(&matches, (const char *) var); } switch_mutex_unlock(globals.mutex); if (matches) { for (m = matches->head; m; m = m->next) { lot = valet_find_lot(m->val, SWITCH_FALSE); switch_mutex_lock(lot->mutex); top: for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) { switch_hash_this(i_hi, &i_var, NULL, &i_val); i_ext = (char *) i_var; token = (valet_token_t *) i_val; if (token->timeout > 0 && (token->timeout < now || token->timeout == 1)) { switch_core_hash_delete(lot->hash, i_ext); switch_safe_free(token); goto top; } } switch_mutex_unlock(lot->mutex); } switch_console_free_matches(&matches); } }
void *SWITCH_THREAD_FUNC monitor_thread_run(switch_thread_t *thread, void *obj) { xml_binding_t *binding = (xml_binding_t *) obj; time_t st; int diff; while(globals.running) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Running server command: %s\n", binding->server); st = switch_epoch_time_now(NULL); switch_system(binding->server, SWITCH_TRUE); diff = (int) switch_epoch_time_now(NULL) - st; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Server command complete: %s\n", binding->server); if (globals.running && diff < 5) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Server command had short run duration, sleeping: %s\n", binding->server); switch_yield(10000000); } } return NULL; }
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_recordings(switch_core_session_t *orig_session, switch_core_session_t *new_session) { switch_media_bug_t *bp; char *list[100] = { 0 }; int stop_times[100] = { 0 }; int i = 0, x = 0; if (orig_session->bugs) { switch_channel_t *new_channel = switch_core_session_get_channel(new_session); switch_channel_t *orig_channel = switch_core_session_get_channel(orig_session); const char *save_append = switch_channel_get_variable(new_channel, "record_append"); const char *save_stereo = switch_channel_get_variable(new_channel, "record_stereo"); const char *orig_stereo = switch_channel_get_variable(orig_channel, "record_stereo"); const char *new_stereo = orig_stereo; switch_thread_rwlock_wrlock(orig_session->bug_rwlock); switch_channel_set_variable(new_channel, "RECORD_MIN_SEC", "0"); switch_channel_set_variable(new_channel, "record_append", "true"); switch_channel_set_variable(new_channel, "record_stereo", new_stereo); for (bp = orig_session->bugs; bp; bp = bp->next) { if (!strcmp(bp->function, "session_record")) { list[x] = switch_core_session_strdup(new_session, bp->target); if (bp->stop_time > 0) { stop_times[x] = (int)(bp->stop_time - switch_epoch_time_now(NULL)); } x++; } } switch_thread_rwlock_unlock(orig_session->bug_rwlock); for(i = 0; i < x; i++) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(orig_session), SWITCH_LOG_DEBUG, "Transfering %s from %s to %s\n", list[i], switch_core_session_get_name(orig_session), switch_core_session_get_name(new_session)); switch_ivr_stop_record_session(orig_session, list[i]); switch_ivr_record_session(new_session, list[i], stop_times[i], NULL); } switch_channel_set_variable(new_channel, "record_append", save_append); switch_channel_set_variable(new_channel, "record_stereo", save_stereo); } return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; }
static int valet_lot_count(valet_lot_t *lot) { switch_hash_index_t *i_hi; const void *i_var; void *i_val; valet_token_t *token; int count = 0; time_t now; now = switch_epoch_time_now(NULL); switch_mutex_lock(lot->mutex); for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) { switch_hash_this(i_hi, &i_var, NULL, &i_val); token = (valet_token_t *) i_val; if (token->timeout > 0 && (token->timeout < now || token->timeout == 1)) { continue; } count++; } switch_mutex_unlock(lot->mutex); return count; }
static switch_status_t hr_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) { int32_t t; switch_time_t target = 0, target_now = 0; switch_time_exp_t tm, tm_now; uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0; switch_channel_t *channel = switch_core_session_get_channel(session); const char *tz = switch_channel_get_variable(channel, "timezone"); int sat_desetinka = 0; int sat_jedinica = 0; int minuta_desetinka = 0; int minuta_jedinica = 0; int sekunda_desetinka = 0; int sekunda_jedinica = 0; if (say_args->type == SST_TIME_MEASUREMENT) { int64_t hours = 0; int64_t minutes = 0; int64_t seconds = 0; int64_t r = 0; if (strchr(tosay, ':')) { char *tme = switch_core_session_strdup(session, tosay); char *p; if ((p = strrchr(tme, ':'))) { *p++ = '\0'; seconds = atoi(p); if ((p = strchr(tme, ':'))) { *p++ = '\0'; minutes = atoi(p); if (tme) { hours = atoi(tme); } } else { minutes = atoi(tme); } } } else { if ((seconds = atol(tosay)) <= 0) { seconds = (int64_t) switch_epoch_time_now(NULL); } if (seconds >= 60) { minutes = seconds / 60; r = seconds % 60; seconds = r; } if (minutes >= 60) { hours = minutes / 60; r = minutes % 60; minutes = r; } } sat_jedinica = hours % 10; if (hours > 10) sat_desetinka = (int) (hours / 10); if (hours) { say_num(hours, SSM_PRONOUNCED, ""); if (sat_desetinka == 0 && sat_jedinica == 0) { nop; } else if (sat_desetinka == 1) { say_file("time/sati.wav"); } else { switch(sat_jedinica) { case 1: say_file("time/sat.wav"); break; case 2: case 3: case 4: say_file("time/sata.wav"); break; case 0: case 5: case 6: case 7: case 8: case 9: say_file("time/sati.wav"); break; } } } minuta_jedinica = minutes % 10; if (minutes > 10) minuta_desetinka = (int) (minutes / 10); if (minutes) { if (minuta_desetinka == 1) { say_num(minutes, SSM_PRONOUNCED, ""); say_file("time/minuta.wav"); } else { switch(minuta_jedinica) { case 2: say_num(minutes, SSM_PRONOUNCED, "je"); say_file("time/minute.wav"); break; case 3: case 4: say_num(minutes, SSM_PRONOUNCED, ""); say_file("time/minute.wav"); break; case 1: say_num(minutes, SSM_PRONOUNCED, "a"); say_file("time/minuta.wav"); break; case 0: case 5: case 6: case 7: case 8: case 9: say_num(minutes, SSM_PRONOUNCED, ""); say_file("time/minuta.wav"); break; } } } sekunda_jedinica = seconds % 10; if (seconds > 10) sekunda_desetinka = (int) (seconds / 10); if (seconds) { if (sekunda_desetinka == 1) { say_num(seconds, SSM_PRONOUNCED, ""); say_file("time/sekundi.wav"); } else if (sekunda_desetinka == 0) { switch(sekunda_jedinica) { case 1: say_num(seconds, SSM_PRONOUNCED, "a"); say_file("time/sekunda.wav"); break; case 2: say_num(seconds, SSM_PRONOUNCED, "je"); say_file("time/sekunde.wav"); break; case 3: case 4: say_num(seconds, SSM_PRONOUNCED, ""); say_file("time/sekunde.wav"); break; case 0: case 5: case 6: case 7: case 8: case 9: say_file("time/sekundi.wav"); break; } } else { switch(sekunda_jedinica) { case 1: say_num(seconds, SSM_PRONOUNCED, "a"); say_file("time/sekunda.wav"); break; case 2: say_num(seconds, SSM_PRONOUNCED, "je"); say_file("time/sekunde.wav"); break; case 3: case 4: say_num(seconds, SSM_PRONOUNCED, ""); say_file("time/sekunde.wav"); break; case 0: case 5: case 6: case 7: case 8: case 9: say_num(seconds, SSM_PRONOUNCED, ""); say_file("time/sekundi.wav"); break; } } } return SWITCH_STATUS_SUCCESS; } if ((t = atol(tosay)) > 0) { target = switch_time_make(t, 0); target_now = switch_micro_time_now(); } else { target = switch_micro_time_now(); target_now = switch_micro_time_now(); } if (tz) { int check = atoi(tz); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz); if (check) { switch_time_exp_tz(&tm, target, check); switch_time_exp_tz(&tm_now, target_now, check); } else { switch_time_exp_tz_name(tz, &tm, target); switch_time_exp_tz_name(tz, &tm_now, target_now); } } else { switch_time_exp_lt(&tm, target); switch_time_exp_lt(&tm_now, target_now); } switch (say_args->type) { case SST_CURRENT_DATE_TIME: say_date = say_time = 1; break; case SST_CURRENT_DATE: say_date = 1; break; case SST_CURRENT_TIME: say_time = 1; break; case SST_SHORT_DATE_TIME: say_time = 1; if (tm.tm_year != tm_now.tm_year) { say_date = 1; break; } if (tm.tm_yday == tm_now.tm_yday) { say_today = 1; break; } if (tm.tm_yday == tm_now.tm_yday - 1) { say_yesterday = 1; break; } if (tm.tm_yday >= tm_now.tm_yday - 5) { say_dow = 1; break; } if (tm.tm_mon != tm_now.tm_mon) { say_month = say_day = say_dow = 1; break; } say_month = say_day = say_dow = 1; break; default: break; } if (say_today) { say_file("time/today.wav"); } if (say_yesterday) { say_file("time/yesterday.wav"); } if (say_dow) { say_file("time/day-%d.wav", tm.tm_wday); } if (say_date) { say_year = say_month = say_day = say_dow = 1; say_today = say_yesterday = 0; } if (say_day) { say_num(tm.tm_mday, SSM_COUNTED, ""); } if (say_month) { say_file("time/mon-%d.wav", tm.tm_mon); } if (say_year) { int y = tm.tm_year + 1900; int tis = 0; //say_num(tm.tm_year + 1900, SSM_PRONOUNCED, ""); //1 - 99 => h-1a.wav - h-99a.wav if (y >= 1 && y <= 99) { say_file("digits/h-%da.wav", y); } // [1-9]00 => h-[1-9]00a.wav else if (y >= 100 && y <= 900 && y % 100 == 0) { say_file("digits/h-%da.wav", y); } //[1-9]01 - [1-9]99 => [1-9]00.wav + (h-1a.wav - h-99a.wav) else if (y >= 100 && y <= 900 && y % 100 != 0) { say_file("digits/h-%da.wav", (int) y - (y % 100)); say_file("digits/h-%da.wav", (int) y % 100); } // 1000 => thousand-ta.wav else if (y == 1000) { say_file("digits/thousand-ta.wav"); } // 1001 - 1999 => thousand-u.wav + [1-9]00.wav + (h-1a.wav - h-99a.wav) else if (y >= 1001 && y <= 1999) { say_file("digits/thousand-u.wav"); if (0 != (int) ((y - 1000) - ((y - 1000) % 100))) say_file("digits/h-%da.wav", (int) ((y - 1000) - ((y - 1000) % 100))); say_file("digits/h-%da.wav", (int) y % 100); } //2000 => 2je.wav + thousand-ta.wav else if (y == 2000) { say_file("digits/2je.wav"); say_file("digits/thousand-ta.wav"); } // 2001 - 2999 => 2je.wav + thousands-e.wav + [1-9]00.wav + (h-1a.wav - h-99a.wav) else if (y >= 2001 && y <= 2999) { say_file("digits/2je.wav"); say_file("digits/thousands-e.wav"); if (0 != (int) ((y - 2000) - ((y - 2000) % 100))) say_file("digits/h-%da.wav", (int) ((y - 2000) - ((y - 2000) % 100))); say_file("digits/h-%da.wav", (int) y % 100); } // 3000 => [3-9].wav + thousand-ta.wav else if (y >= 3000 && y <= 9000 && y % 1000 == 0) { say_file("digits/%d.wav", (int) (y / 1000)); say_file("digits/thousand-ta.wav"); } // [3-9]001 - [3-9]999 => [3-9].wav + thousands-e.wav + [1-9]00.wav + (h-1a.wav - h-99a.wav) else if (y >= 3000 && y <= 9000 && y % 1000 != 0) { say_file("digits/%d.wav", (int) (y / 1000)); say_file("digits/thousands-e.wav"); tis = y - (y % 1000); if (0 != (int) ((y - tis) - ((y - tis) % 100))) say_file("digits/h-%da.wav", (int) ((y - tis) - ((y - tis) % 100))); say_file("digits/h-%da.wav", (int) y % 100); } //say_num(tm.tm_year + 1900, SSM_COUNTED, "a"); } if (say_time) { say_num(tm.tm_hour, SSM_PRONOUNCED, ""); sat_jedinica = tm.tm_hour % 10; if (tm.tm_hour >= 10) sat_desetinka = (int) (tm.tm_hour / 10); if (tm.tm_hour) { if (sat_desetinka == 0 && sat_jedinica == 0) { nop; } else if (sat_desetinka == 1) { say_file("time/sati.wav"); } else { switch(sat_jedinica) { case 1: say_file("time/sat.wav"); break; case 2: case 3: case 4: say_file("time/sata.wav"); break; case 0: case 5: case 6: case 7: case 8: case 9: say_file("time/sati.wav"); break; } } } minuta_jedinica = tm.tm_min % 10; if (tm.tm_min >= 10) minuta_desetinka = (int) (tm.tm_min / 10); if (tm.tm_min) { if (minuta_desetinka == 1) { say_num(tm.tm_min, SSM_PRONOUNCED, ""); say_file("time/minuta.wav"); } else { switch(minuta_jedinica) { case 2: say_num(tm.tm_min, SSM_PRONOUNCED, "je"); say_file("time/minute.wav"); break; case 3: case 4: say_num(tm.tm_min, SSM_PRONOUNCED, ""); say_file("time/minute.wav"); break; case 1: say_num(tm.tm_min, SSM_PRONOUNCED, "a"); say_file("time/minuta.wav"); break; case 0: case 5: case 6: case 7: case 8: case 9: say_num(tm.tm_min, SSM_PRONOUNCED, ""); say_file("time/minuta.wav"); break; } } } sekunda_jedinica = tm.tm_sec % 10; if (tm.tm_sec >= 10) sekunda_desetinka = (int) (tm.tm_sec / 10); if (tm.tm_sec) { if (sekunda_desetinka == 1) { say_num(tm.tm_sec, SSM_PRONOUNCED, ""); say_file("time/sekundi.wav"); } else if (sekunda_desetinka == 0) { switch(sekunda_jedinica) { case 1: say_num(tm.tm_sec, SSM_PRONOUNCED, "a"); say_file("time/sekunda.wav"); break; case 2: say_num(tm.tm_sec, SSM_PRONOUNCED, "je"); say_file("time/sekunde.wav"); break; case 3: case 4: say_num(tm.tm_sec, SSM_PRONOUNCED, ""); say_file("time/sekunde.wav"); break; case 0: case 5: case 6: case 7: case 8: case 9: say_file("time/sekundi.wav"); break; } } else { switch(sekunda_jedinica) { case 1: say_num(tm.tm_sec, SSM_PRONOUNCED, "a"); say_file("time/sekunda.wav"); break; case 2: say_num(tm.tm_sec, SSM_PRONOUNCED, "je"); say_file("time/sekunde.wav"); break; case 3: case 4: say_num(tm.tm_sec, SSM_PRONOUNCED, ""); say_file("time/sekunde.wav"); break; case 0: case 5: case 6: case 7: case 8: case 9: say_num(tm.tm_sec, SSM_PRONOUNCED, ""); say_file("time/sekundi.wav"); break; } } } } return SWITCH_STATUS_SUCCESS; }
static switch_status_t fa_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) { int32_t t; switch_time_t target = 0, target_now = 0; switch_time_exp_t tm, tm_now; uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0; switch_channel_t *channel = switch_core_session_get_channel(session); const char *tz = switch_channel_get_variable(channel, "timezone"); int jalali_year = 1, jalali_month = 0, jalali_day = 0; if (say_args->type == SST_TIME_MEASUREMENT) { int64_t hours = 0; int64_t minutes = 0; int64_t seconds = 0; int64_t r = 0; if (strchr(tosay, ':')) { char *tme = switch_core_session_strdup(session, tosay); char *p; if ((p = strrchr(tme, ':'))) { *p++ = '\0'; seconds = atoi(p); if ((p = strchr(tme, ':'))) { *p++ = '\0'; minutes = atoi(p); if (tme) { hours = atoi(tme); } } else { minutes = atoi(tme); } } } else { if ((seconds = atol(tosay)) <= 0) { seconds = (int64_t) switch_epoch_time_now(NULL); } if (seconds >= 60) { minutes = seconds / 60; r = seconds % 60; seconds = r; } if (minutes >= 60) { hours = minutes / 60; r = minutes % 60; minutes = r; } } if (hours) { say_num(hours, SSM_PRONOUNCED); if(minutes || seconds) { say_file("time/hour+.wav"); } else say_file("time/hour.wav"); } if (minutes) { say_num(minutes, SSM_PRONOUNCED); if( seconds ) { say_file("time/minutes+.wav"); } else say_file("time/minutes.wav"); } if (seconds) { say_num(seconds, SSM_PRONOUNCED); say_file("time/seconds.wav"); } return SWITCH_STATUS_SUCCESS; } if ((t = atol(tosay)) > 0) { target = switch_time_make(t, 0); target_now = switch_micro_time_now(); } else { target = switch_micro_time_now(); target_now = switch_micro_time_now(); } if (tz) { int check = atoi(tz); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz); if (check) { switch_time_exp_tz(&tm, target, check); switch_time_exp_tz(&tm_now, target_now, check); } else { switch_time_exp_tz_name(tz, &tm, target); switch_time_exp_tz_name(tz, &tm_now, target_now); } } else { switch_time_exp_lt(&tm, target); switch_time_exp_lt(&tm_now, target_now); } switch (say_args->type) { case SST_CURRENT_DATE_TIME: say_date = say_time = 1; break; case SST_CURRENT_DATE: say_date = 1; break; case SST_CURRENT_TIME: say_time = 1; break; case SST_SHORT_DATE_TIME: say_time = 1; if (tm.tm_year != tm_now.tm_year) { say_date = 1; break; } if (tm.tm_yday == tm_now.tm_yday) { say_today = 1; break; } if (tm.tm_yday == tm_now.tm_yday - 1) { say_yesterday = 1; break; } if (tm.tm_yday >= tm_now.tm_yday - 5) { say_dow = 1; break; } if (tm.tm_mon != tm_now.tm_mon) { say_month = say_day = say_dow = 1; break; } say_month = say_day = say_dow = 1; break; default: break; } if (say_today) { say_file("time/today.wav"); } if (say_yesterday) { say_file("time/yesterday.wav"); } if (say_dow) { say_file("time/day-%d.wav", tm.tm_wday); } if (say_date) { say_year = say_month = say_day = say_dow = 1; say_today = say_yesterday = 0; } gregorian_to_jalali(&jalali_year,&jalali_month,&jalali_day,tm.tm_year + 1900,tm.tm_mon + 1,tm.tm_mday); if (say_day) { if(jalali_day > 20 && jalali_day != 30) { say_file("digits/%d+.wav", (jalali_day - jalali_day % 10)); say_file("digits/%de.wav", jalali_day % 10); } else say_file("digits/%de.wav", jalali_day); } if (say_month) { say_file("time/mon-%d.wav", jalali_month - 1); } if (say_year) { say_num(jalali_year, SSM_PRONOUNCED); } if (say_time) { int32_t hour = tm.tm_hour, pm = 0; if (say_date || say_today || say_yesterday || say_dow) { say_file("time/at.wav"); } if (hour > 12) { hour -= 12; pm = 1; } else if (hour == 12) { pm = 1; } else if (hour == 0) { hour = 12; pm = 0; } say_file("time/hour-e.wav"); say_file("digits/%do.wav",hour); play_group(SSM_PRONOUNCED, 0, (tm.tm_min - tm.tm_min % 10) / 10, tm.tm_min % 10, "time/minutes-e.wav", session, args); say_file("time/%s.wav", pm ? "p-m" : "a-m"); } return SWITCH_STATUS_SUCCESS; }
static switch_status_t hu_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) { int32_t t; switch_time_t target = 0, target_now = 0; switch_time_exp_t tm, tm_now; uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0; switch_channel_t *channel = switch_core_session_get_channel(session); const char *tz = switch_channel_get_variable(channel, "timezone"); if (say_args->type == SST_TIME_MEASUREMENT) { int64_t hours = 0; int64_t minutes = 0; int64_t seconds = 0; int64_t r = 0; if (strchr(tosay, ':')) { char *tme = switch_core_session_strdup(session, tosay); char *p; if ((p = strrchr(tme, ':'))) { *p++ = '\0'; seconds = atoi(p); if ((p = strchr(tme, ':'))) { *p++ = '\0'; minutes = atoi(p); if (tme) { hours = atoi(tme); } } else { minutes = atoi(tme); } } } else { if ((seconds = atol(tosay)) <= 0) { seconds = (int64_t) switch_epoch_time_now(NULL); } if (seconds >= 60) { minutes = seconds / 60; r = seconds % 60; seconds = r; } if (minutes >= 60) { hours = minutes / 60; r = minutes % 60; minutes = r; } } if (hours) { say_num(hours, SSM_PRONOUNCED); say_file("time/hour.wav"); } else { say_file("digits/0.wav"); say_file("time/hour.wav"); } if (minutes) { say_num(minutes, SSM_PRONOUNCED); say_file("time/minute.wav"); } else { say_file("digits/0.wav"); say_file("time/minute.wav"); } if (seconds) { say_num(seconds, SSM_PRONOUNCED); say_file("time/second.wav"); } else { say_file("digits/0.wav"); say_file("time/second.wav"); } return SWITCH_STATUS_SUCCESS; } if ((t = atol(tosay)) > 0) { target = switch_time_make(t, 0); target_now = switch_micro_time_now(); } else { target = switch_micro_time_now(); target_now = switch_micro_time_now(); } if (tz) { int check = atoi(tz); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz); if (check) { switch_time_exp_tz(&tm, target, check); switch_time_exp_tz(&tm_now, target_now, check); } else { switch_time_exp_tz_name(tz, &tm, target); switch_time_exp_tz_name(tz, &tm_now, target_now); } } else { switch_time_exp_lt(&tm, target); switch_time_exp_lt(&tm_now, target_now); } switch (say_args->type) { case SST_CURRENT_DATE_TIME: say_date = say_time = 1; break; case SST_CURRENT_DATE: say_date = 1; break; case SST_CURRENT_TIME: say_time = 1; break; case SST_SHORT_DATE_TIME: say_time = 1; if (tm.tm_year != tm_now.tm_year) { say_date = 1; break; } if (tm.tm_yday == tm_now.tm_yday) { say_today = 1; break; } if (tm.tm_yday == tm_now.tm_yday - 1) { say_yesterday = 1; break; } if (tm.tm_yday >= tm_now.tm_yday - 5) { say_dow = 1; break; } if (tm.tm_mon != tm_now.tm_mon) { say_month = say_day = say_dow = 1; break; } say_month = say_day = say_dow = 1; break; default: break; } if (say_today) { say_file("time/today.wav"); } if (say_yesterday) { say_file("time/yesterday.wav"); } if (say_dow) { say_file("time/day-%d.wav", tm.tm_wday); } if (say_date) { say_year = say_month = say_day = say_dow = 1; say_today = say_yesterday = 0; } if (say_year) { say_num(tm.tm_year + 1900, SSM_PRONOUNCED); } if (say_month) { say_file("time/mon-%d.wav", tm.tm_mon); } if (say_day) { say_num(tm.tm_mday, SSM_PRONOUNCED); } if (say_time) { say_num(tm.tm_hour, SSM_PRONOUNCED); say_file("time/hour.wav"); say_num(tm.tm_min, SSM_PRONOUNCED); say_file("time/minute.wav"); } return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) { switch_status_t status = SWITCH_STATUS_FALSE; switch_frame_t *enc_frame = NULL, *write_frame = frame; unsigned int flag = 0, need_codec = 0, perfect = 0, do_bugs = 0, do_write = 0, do_resample = 0, ptime_mismatch = 0, pass_cng = 0, resample = 0; int did_write_resample = 0; switch_assert(session != NULL); switch_assert(frame != NULL); if (!switch_channel_ready(session->channel)) { return SWITCH_STATUS_FALSE; } if (switch_mutex_trylock(session->codec_write_mutex) == SWITCH_STATUS_SUCCESS) { switch_mutex_unlock(session->codec_write_mutex); } else { return SWITCH_STATUS_SUCCESS; } if (switch_test_flag(frame, SFF_CNG)) { if (switch_channel_test_flag(session->channel, CF_ACCEPT_CNG)) { pass_cng = 1; } else { return SWITCH_STATUS_SUCCESS; } } if (!(session->write_codec && switch_core_codec_ready(session->write_codec)) && !pass_cng) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no write codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); return SWITCH_STATUS_FALSE; } if (switch_channel_test_flag(session->channel, CF_HOLD)) { return SWITCH_STATUS_SUCCESS; } if (switch_test_flag(frame, SFF_PROXY_PACKET) || pass_cng) { /* Fast PASS! */ switch_mutex_lock(session->codec_write_mutex); status = perform_write(session, frame, flag, stream_id); switch_mutex_unlock(session->codec_write_mutex); return status; } switch_mutex_lock(session->codec_write_mutex); if (!(frame->codec && frame->codec->implementation)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has received a bad frame with no codec!\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_mutex_unlock(session->codec_write_mutex); return SWITCH_STATUS_FALSE; } switch_assert(frame->codec != NULL); switch_assert(frame->codec->implementation != NULL); if (!(switch_core_codec_ready(session->write_codec) && frame->codec) || !switch_channel_ready(session->channel) || !switch_channel_media_ready(session->channel)) { switch_mutex_unlock(session->codec_write_mutex); return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->write_codec->mutex); switch_mutex_lock(frame->codec->mutex); if (!(switch_core_codec_ready(session->write_codec) && switch_core_codec_ready(frame->codec))) goto error; if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) { if (session->write_impl.codec_id == frame->codec->implementation->codec_id || session->write_impl.microseconds_per_packet != frame->codec->implementation->microseconds_per_packet) { ptime_mismatch = TRUE; if ((switch_test_flag(frame->codec, SWITCH_CODEC_FLAG_PASSTHROUGH) || switch_test_flag(session->read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)) || switch_channel_test_flag(session->channel, CF_PASSTHRU_PTIME_MISMATCH)) { status = perform_write(session, frame, flags, stream_id); goto error; } } need_codec = TRUE; } if (session->write_codec && !frame->codec) { need_codec = TRUE; } if (session->bugs && !need_codec) { do_bugs = TRUE; need_codec = TRUE; } if (frame->codec->implementation->actual_samples_per_second != session->write_impl.actual_samples_per_second) { need_codec = TRUE; do_resample = TRUE; } if (switch_test_flag(session, SSF_WRITE_TRANSCODE) && !need_codec && switch_core_codec_ready(session->write_codec)) { switch_core_session_t *other_session; const char *uuid = switch_channel_get_variable(switch_core_session_get_channel(session), SWITCH_SIGNAL_BOND_VARIABLE); if (uuid && (other_session = switch_core_session_locate(uuid))) { switch_set_flag(other_session, SSF_READ_CODEC_RESET); switch_set_flag(other_session, SSF_READ_CODEC_RESET); switch_set_flag(other_session, SSF_WRITE_CODEC_RESET); switch_core_session_rwunlock(other_session); } switch_clear_flag(session, SSF_WRITE_TRANSCODE); } if (switch_test_flag(session, SSF_WRITE_CODEC_RESET)) { switch_core_codec_reset(session->write_codec); switch_clear_flag(session, SSF_WRITE_CODEC_RESET); } if (!need_codec) { do_write = TRUE; write_frame = frame; goto done; } if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) { switch_core_session_message_t msg = { 0 }; msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY; switch_core_session_receive_message(session, &msg); switch_set_flag(session, SSF_WARN_TRANSCODE); } if (frame->codec) { session->raw_write_frame.datalen = session->raw_write_frame.buflen; status = switch_core_codec_decode(frame->codec, session->write_codec, frame->data, frame->datalen, session->write_impl.actual_samples_per_second, session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &frame->flags); if (do_resample && status == SWITCH_STATUS_SUCCESS) { status = SWITCH_STATUS_RESAMPLE; } switch (status) { case SWITCH_STATUS_RESAMPLE: resample++; write_frame = &session->raw_write_frame; write_frame->rate = frame->codec->implementation->actual_samples_per_second; if (!session->write_resampler) { switch_mutex_lock(session->resample_mutex); status = switch_resample_create(&session->write_resampler, frame->codec->implementation->actual_samples_per_second, session->write_impl.actual_samples_per_second, session->write_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, 1); switch_mutex_unlock(session->resample_mutex); if (status != SWITCH_STATUS_SUCCESS) { goto done; } } break; case SWITCH_STATUS_SUCCESS: session->raw_write_frame.samples = session->raw_write_frame.datalen / sizeof(int16_t); session->raw_write_frame.timestamp = frame->timestamp; session->raw_write_frame.rate = frame->rate; session->raw_write_frame.m = frame->m; session->raw_write_frame.ssrc = frame->ssrc; session->raw_write_frame.seq = frame->seq; session->raw_write_frame.payload = frame->payload; session->raw_write_frame.flags = 0; if (switch_test_flag(frame, SFF_PLC)) { session->raw_write_frame.flags |= SFF_PLC; } write_frame = &session->raw_write_frame; break; case SWITCH_STATUS_BREAK: status = SWITCH_STATUS_SUCCESS; goto error; case SWITCH_STATUS_NOOP: if (session->write_resampler) { switch_mutex_lock(session->resample_mutex); switch_resample_destroy(&session->write_resampler); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n"); switch_mutex_unlock(session->resample_mutex); } write_frame = frame; status = SWITCH_STATUS_SUCCESS; break; default: if (status == SWITCH_STATUS_NOT_INITALIZED) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n"); goto error; } if (ptime_mismatch) { status = perform_write(session, frame, flags, stream_id); status = SWITCH_STATUS_SUCCESS; goto error; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error!\n", frame->codec->codec_interface->interface_name); goto error; } } if (session->write_resampler) { short *data = write_frame->data; switch_mutex_lock(session->resample_mutex); if (session->write_resampler) { switch_resample_process(session->write_resampler, data, write_frame->datalen / 2); memcpy(data, session->write_resampler->to, session->write_resampler->to_len * 2); write_frame->samples = session->write_resampler->to_len; write_frame->datalen = write_frame->samples * 2; write_frame->rate = session->write_resampler->to_rate; did_write_resample = 1; } switch_mutex_unlock(session->resample_mutex); } if (session->bugs) { switch_media_bug_t *bp; int prune = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { switch_bool_t ok = SWITCH_TRUE; if (!bp->ready) { continue; } if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { continue; } if (switch_test_flag(bp, SMBF_PRUNE)) { prune++; continue; } if (switch_test_flag(bp, SMBF_WRITE_STREAM)) { switch_mutex_lock(bp->write_mutex); switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen); switch_mutex_unlock(bp->write_mutex); if (bp->callback) { ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE); } } if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) { do_bugs = 0; if (bp->callback) { bp->write_replace_frame_in = write_frame; bp->write_replace_frame_out = write_frame; if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) { write_frame = bp->write_replace_frame_out; } } } if (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) { ok = SWITCH_FALSE; } if (ok == SWITCH_FALSE) { switch_set_flag(bp, SMBF_PRUNE); prune++; } } switch_thread_rwlock_unlock(session->bug_rwlock); if (prune) { switch_core_media_bug_prune(session); } } if (do_bugs) { do_write = TRUE; write_frame = frame; goto done; } if (session->write_codec) { if (!ptime_mismatch && write_frame->codec && write_frame->codec->implementation && write_frame->codec->implementation->decoded_bytes_per_packet == session->write_impl.decoded_bytes_per_packet) { perfect = TRUE; } if (perfect) { if (write_frame->datalen < session->write_impl.decoded_bytes_per_packet) { memset(write_frame->data, 255, session->write_impl.decoded_bytes_per_packet - write_frame->datalen); write_frame->datalen = session->write_impl.decoded_bytes_per_packet; } enc_frame = write_frame; session->enc_write_frame.datalen = session->enc_write_frame.buflen; status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, enc_frame->datalen, session->write_impl.actual_samples_per_second, session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); switch (status) { case SWITCH_STATUS_RESAMPLE: resample++; /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 2\n"); */ case SWITCH_STATUS_SUCCESS: session->enc_write_frame.codec = session->write_codec; session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t); if (frame->codec->implementation->samples_per_packet != session->write_impl.samples_per_packet) { session->enc_write_frame.timestamp = 0; } else { session->enc_write_frame.timestamp = frame->timestamp; } session->enc_write_frame.payload = session->write_impl.ianacode; session->enc_write_frame.m = frame->m; session->enc_write_frame.ssrc = frame->ssrc; session->enc_write_frame.seq = frame->seq; write_frame = &session->enc_write_frame; break; case SWITCH_STATUS_NOOP: enc_frame->codec = session->write_codec; enc_frame->samples = enc_frame->datalen / sizeof(int16_t); enc_frame->timestamp = frame->timestamp; enc_frame->m = frame->m; enc_frame->seq = frame->seq; enc_frame->ssrc = frame->ssrc; enc_frame->payload = enc_frame->codec->implementation->ianacode; write_frame = enc_frame; status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n"); write_frame = NULL; goto error; default: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n", session->read_codec->codec_interface->interface_name); write_frame = NULL; goto error; } if (flag & SFF_CNG) { switch_set_flag(write_frame, SFF_CNG); } status = perform_write(session, write_frame, flags, stream_id); goto error; } else { if (!session->raw_write_buffer) { switch_size_t bytes_per_packet = session->write_impl.decoded_bytes_per_packet; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Engaging Write Buffer at %u bytes to accommodate %u->%u\n", (uint32_t) bytes_per_packet, write_frame->datalen, session->write_impl.decoded_bytes_per_packet); if ((status = switch_buffer_create_dynamic(&session->raw_write_buffer, bytes_per_packet * SWITCH_BUFFER_BLOCK_FRAMES, bytes_per_packet * SWITCH_BUFFER_START_FRAMES, 0)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Write Buffer Failed!\n"); goto error; } } if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen); status = SWITCH_STATUS_MEMERR; goto error; } status = SWITCH_STATUS_SUCCESS; while (switch_buffer_inuse(session->raw_write_buffer) >= session->write_impl.decoded_bytes_per_packet) { int rate; if (switch_channel_down(session->channel) || !session->raw_write_buffer) { goto error; } if ((session->raw_write_frame.datalen = (uint32_t) switch_buffer_read(session->raw_write_buffer, session->raw_write_frame.data, session->write_impl.decoded_bytes_per_packet)) == 0) { goto error; } enc_frame = &session->raw_write_frame; session->raw_write_frame.rate = session->write_impl.actual_samples_per_second; session->enc_write_frame.datalen = session->enc_write_frame.buflen; session->enc_write_frame.timestamp = 0; if (frame->codec && frame->codec->implementation && switch_core_codec_ready(frame->codec)) { rate = frame->codec->implementation->actual_samples_per_second; } else { rate = session->write_impl.actual_samples_per_second; } status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, enc_frame->datalen, rate, session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); switch (status) { case SWITCH_STATUS_RESAMPLE: resample++; session->enc_write_frame.codec = session->write_codec; session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t); session->enc_write_frame.m = frame->m; session->enc_write_frame.ssrc = frame->ssrc; session->enc_write_frame.payload = session->write_impl.ianacode; write_frame = &session->enc_write_frame; if (!session->write_resampler) { switch_mutex_lock(session->resample_mutex); if (!session->write_resampler) { status = switch_resample_create(&session->write_resampler, frame->codec->implementation->actual_samples_per_second, session->write_impl.actual_samples_per_second, session->write_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, 1); } switch_mutex_unlock(session->resample_mutex); if (status != SWITCH_STATUS_SUCCESS) { goto done; } } break; case SWITCH_STATUS_SUCCESS: session->enc_write_frame.codec = session->write_codec; session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t); session->enc_write_frame.m = frame->m; session->enc_write_frame.ssrc = frame->ssrc; session->enc_write_frame.payload = session->write_impl.ianacode; write_frame = &session->enc_write_frame; break; case SWITCH_STATUS_NOOP: if (session->write_resampler) { switch_mutex_lock(session->resample_mutex); if (session->write_resampler) { switch_resample_destroy(&session->write_resampler); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n"); } switch_mutex_unlock(session->resample_mutex); } enc_frame->codec = session->write_codec; enc_frame->samples = enc_frame->datalen / sizeof(int16_t); enc_frame->m = frame->m; enc_frame->ssrc = frame->ssrc; enc_frame->payload = enc_frame->codec->implementation->ianacode; write_frame = enc_frame; status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n"); write_frame = NULL; goto error; default: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n", session->read_codec->codec_interface->interface_name, status); write_frame = NULL; goto error; } if (!did_write_resample && session->read_resampler) { short *data = write_frame->data; switch_mutex_lock(session->resample_mutex); if (session->read_resampler) { switch_resample_process(session->read_resampler, data, write_frame->datalen / 2); memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2); write_frame->samples = session->read_resampler->to_len; write_frame->datalen = session->read_resampler->to_len * 2; write_frame->rate = session->read_resampler->to_rate; } switch_mutex_unlock(session->resample_mutex); } if (flag & SFF_CNG) { switch_set_flag(write_frame, SFF_CNG); } if (ptime_mismatch || resample) { write_frame->timestamp = 0; } if ((status = perform_write(session, write_frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) { break; } } goto error; } } done: if (ptime_mismatch || resample) { write_frame->timestamp = 0; } if (do_write) { status = perform_write(session, write_frame, flags, stream_id); } error: switch_mutex_unlock(session->write_codec->mutex); switch_mutex_unlock(frame->codec->mutex); switch_mutex_unlock(session->codec_write_mutex); return status; }
SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { switch_io_event_hook_read_frame_t *ptr; switch_status_t status = SWITCH_STATUS_FALSE; int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0; switch_codec_implementation_t codec_impl; unsigned int flag = 0; switch_assert(session != NULL); if (switch_mutex_trylock(session->codec_read_mutex) == SWITCH_STATUS_SUCCESS) { switch_mutex_unlock(session->codec_read_mutex); } else { switch_cond_next(); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_SUCCESS; } if (!(session->read_codec && session->read_codec->implementation && switch_core_codec_ready(session->read_codec))) { if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_get_state(session->channel) == CS_HIBERNATE) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s reading on a session with no media!\n", switch_channel_get_name(session->channel)); switch_cond_next(); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_SUCCESS; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->codec_read_mutex); if (!switch_core_codec_ready(session->read_codec)) { switch_mutex_unlock(session->codec_read_mutex); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->read_codec->mutex); top: if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) { switch_ivr_dmachine_ping(session->dmachine, NULL); } if (switch_channel_down(session->channel) || !switch_core_codec_ready(session->read_codec)) { *frame = NULL; status = SWITCH_STATUS_FALSE; goto even_more_done; } status = SWITCH_STATUS_FALSE; need_codec = perfect = 0; *frame = NULL; if (session->read_codec && !session->track_id && session->track_duration) { if (session->read_frame_count == 0) { switch_event_t *event; session->read_frame_count = (session->read_impl.actual_samples_per_second / session->read_impl.samples_per_packet) * session->track_duration; switch_event_create(&event, SWITCH_EVENT_SESSION_HEARTBEAT); switch_channel_event_set_data(session->channel, event); switch_event_fire(&event); } else { session->read_frame_count--; } } if (switch_channel_test_flag(session->channel, CF_HOLD)) { switch_yield(session->read_impl.microseconds_per_packet); status = SWITCH_STATUS_BREAK; goto even_more_done; } if (session->endpoint_interface->io_routines->read_frame) { switch_mutex_unlock(session->read_codec->mutex); switch_mutex_unlock(session->codec_read_mutex); if ((status = session->endpoint_interface->io_routines->read_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) { for (ptr = session->event_hooks.read_frame; ptr; ptr = ptr->next) { if ((status = ptr->read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) { break; } } } if (!SWITCH_READ_ACCEPTABLE(status) || !session->read_codec || !switch_core_codec_ready(session->read_codec)) { *frame = NULL; return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->codec_read_mutex); if (!switch_core_codec_ready(session->read_codec)) { switch_mutex_unlock(session->codec_read_mutex); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->read_codec->mutex); if (!switch_core_codec_ready(session->read_codec)) { *frame = NULL; status = SWITCH_STATUS_FALSE; goto even_more_done; } } if (status != SWITCH_STATUS_SUCCESS) { goto done; } if (!(*frame)) { goto done; } switch_assert(*frame != NULL); if (switch_test_flag(*frame, SFF_PROXY_PACKET)) { /* Fast PASS! */ status = SWITCH_STATUS_SUCCESS; goto done; } if (switch_test_flag(*frame, SFF_CNG)) { status = SWITCH_STATUS_SUCCESS; if (!session->bugs && !session->plc) { goto done; } is_cng = 1; } switch_assert((*frame)->codec != NULL); if (!(session->read_codec && (*frame)->codec && (*frame)->codec->implementation) && switch_core_codec_ready((*frame)->codec)) { status = SWITCH_STATUS_FALSE; goto done; } codec_impl = *(*frame)->codec->implementation; if (session->read_codec->implementation->impl_id != codec_impl.impl_id) { need_codec = TRUE; } if (codec_impl.actual_samples_per_second != session->read_impl.actual_samples_per_second) { do_resample = 1; } if (session->bugs && !need_codec) { do_bugs = 1; need_codec = 1; } if (switch_test_flag(session, SSF_READ_TRANSCODE) && !need_codec && switch_core_codec_ready(session->read_codec)) { switch_core_session_t *other_session; const char *uuid = switch_channel_get_variable(switch_core_session_get_channel(session), SWITCH_SIGNAL_BOND_VARIABLE); switch_clear_flag(session, SSF_READ_TRANSCODE); if (uuid && (other_session = switch_core_session_locate(uuid))) { switch_set_flag(other_session, SSF_READ_CODEC_RESET); switch_set_flag(other_session, SSF_READ_CODEC_RESET); switch_set_flag(other_session, SSF_WRITE_CODEC_RESET); switch_core_session_rwunlock(other_session); } } if (switch_test_flag(session, SSF_READ_CODEC_RESET)) { switch_core_codec_reset(session->read_codec); switch_clear_flag(session, SSF_READ_CODEC_RESET); } if (status == SWITCH_STATUS_SUCCESS && need_codec) { switch_frame_t *enc_frame, *read_frame = *frame; switch_set_flag(session, SSF_READ_TRANSCODE); if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) { switch_core_session_message_t msg = { 0 }; msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY; switch_core_session_receive_message(session, &msg); switch_set_flag(session, SSF_WARN_TRANSCODE); } if (read_frame->codec || is_cng) { session->raw_read_frame.datalen = session->raw_read_frame.buflen; if (is_cng) { if (session->plc) { plc_fillin(session->plc, session->raw_read_frame.data, read_frame->codec->implementation->decoded_bytes_per_packet / 2); is_cng = 0; flag &= !SFF_CNG; } else { memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); } session->raw_read_frame.timestamp = 0; session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); read_frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; } else { switch_codec_t *use_codec = read_frame->codec; if (do_bugs) { switch_thread_rwlock_wrlock(session->bug_rwlock); if (!session->bugs) { do_bugs = 0; switch_thread_rwlock_unlock(session->bug_rwlock); goto done; } if (!switch_core_codec_ready(&session->bug_codec)) { switch_core_codec_copy(read_frame->codec, &session->bug_codec, NULL); } use_codec = &session->bug_codec; switch_thread_rwlock_unlock(session->bug_rwlock); switch_thread_rwlock_wrlock(session->bug_rwlock); if (!session->bugs) { do_bugs = 0; } switch_thread_rwlock_unlock(session->bug_rwlock); if (!do_bugs) goto done; } if (switch_test_flag(read_frame, SFF_PLC)) { session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen); status = SWITCH_STATUS_SUCCESS; } else { status = switch_core_codec_decode(use_codec, session->read_codec, read_frame->data, read_frame->datalen, session->read_impl.actual_samples_per_second, session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, &read_frame->flags); } if (status == SWITCH_STATUS_SUCCESS) { if ((switch_channel_test_flag(session->channel, CF_JITTERBUFFER) || switch_channel_test_flag(session->channel, CF_CNG_PLC)) && !session->plc) { session->plc = plc_init(NULL); } if (session->plc) { if (switch_test_flag(read_frame, SFF_PLC)) { plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); switch_clear_flag(read_frame, SFF_PLC); } else { plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); } } } } if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) { status = SWITCH_STATUS_RESAMPLE; } switch (status) { case SWITCH_STATUS_RESAMPLE: if (!session->read_resampler) { switch_mutex_lock(session->resample_mutex); status = switch_resample_create(&session->read_resampler, read_frame->codec->implementation->actual_samples_per_second, session->read_impl.actual_samples_per_second, session->read_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, 1); switch_mutex_unlock(session->resample_mutex); if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n"); status = SWITCH_STATUS_FALSE; goto done; } } case SWITCH_STATUS_SUCCESS: session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); session->raw_read_frame.rate = read_frame->rate; if (read_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) { session->raw_read_frame.timestamp = 0; } else { session->raw_read_frame.timestamp = read_frame->timestamp; } session->raw_read_frame.ssrc = read_frame->ssrc; session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; session->raw_read_frame.flags = 0; if (switch_test_flag(read_frame, SFF_PLC)) { session->raw_read_frame.flags |= SFF_PLC; } read_frame = &session->raw_read_frame; break; case SWITCH_STATUS_NOOP: if (session->read_resampler) { switch_mutex_lock(session->resample_mutex); switch_resample_destroy(&session->read_resampler); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n"); switch_mutex_unlock(session->resample_mutex); } status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_BREAK: memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); session->raw_read_frame.timestamp = read_frame->timestamp; session->raw_read_frame.rate = read_frame->rate; session->raw_read_frame.ssrc = read_frame->ssrc; session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; session->raw_read_frame.flags = 0; if (switch_test_flag(read_frame, SFF_PLC)) { session->raw_read_frame.flags |= SFF_PLC; } read_frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n"); goto done; default: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error!\n", session->read_codec->codec_interface->interface_name); goto done; } } if (session->bugs) { switch_media_bug_t *bp; switch_bool_t ok = SWITCH_TRUE; int prune = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { continue; } if (switch_test_flag(bp, SMBF_PRUNE)) { prune++; continue; } if (bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) { switch_mutex_lock(bp->read_mutex); switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen); if (bp->callback) { ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ); } switch_mutex_unlock(bp->read_mutex); } if (ok && switch_test_flag(bp, SMBF_READ_REPLACE)) { do_bugs = 0; if (bp->callback) { bp->read_replace_frame_in = read_frame; bp->read_replace_frame_out = read_frame; if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) { read_frame = bp->read_replace_frame_out; } } } if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) { switch_set_flag(bp, SMBF_PRUNE); prune++; } } switch_thread_rwlock_unlock(session->bug_rwlock); if (prune) { switch_core_media_bug_prune(session); } } if (do_bugs) { goto done; } if (session->read_codec) { if (session->read_resampler) { short *data = read_frame->data; switch_mutex_lock(session->resample_mutex); switch_resample_process(session->read_resampler, data, (int) read_frame->datalen / 2); memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2); read_frame->samples = session->read_resampler->to_len; read_frame->datalen = session->read_resampler->to_len * 2; read_frame->rate = session->read_resampler->to_rate; switch_mutex_unlock(session->resample_mutex); } if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) { perfect = TRUE; } else { if (!session->raw_read_buffer) { switch_size_t bytes = session->read_impl.decoded_bytes_per_packet; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes vs %u\n", (uint32_t) bytes, (uint32_t) (*frame)->datalen); switch_buffer_create_dynamic(&session->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, 0); } if (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen)) { status = SWITCH_STATUS_MEMERR; goto done; } } if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) { if (perfect) { enc_frame = read_frame; session->raw_read_frame.rate = read_frame->rate; } else { session->raw_read_frame.datalen = (uint32_t) switch_buffer_read(session->raw_read_buffer, session->raw_read_frame.data, session->read_impl.decoded_bytes_per_packet); session->raw_read_frame.rate = session->read_impl.actual_samples_per_second; enc_frame = &session->raw_read_frame; } session->enc_read_frame.datalen = session->enc_read_frame.buflen; switch_assert(session->read_codec != NULL); switch_assert(enc_frame != NULL); switch_assert(enc_frame->data != NULL); status = switch_core_codec_encode(session->read_codec, enc_frame->codec, enc_frame->data, enc_frame->datalen, session->read_impl.actual_samples_per_second, session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag); switch (status) { case SWITCH_STATUS_RESAMPLE: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 1\n"); case SWITCH_STATUS_SUCCESS: session->enc_read_frame.samples = session->read_impl.decoded_bytes_per_packet / sizeof(int16_t); if (perfect) { if (enc_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) { session->enc_read_frame.timestamp = 0; } else { session->enc_read_frame.timestamp = read_frame->timestamp; } session->enc_read_frame.rate = read_frame->rate; session->enc_read_frame.ssrc = read_frame->ssrc; session->enc_read_frame.seq = read_frame->seq; session->enc_read_frame.m = read_frame->m; session->enc_read_frame.payload = session->read_impl.ianacode; } *frame = &session->enc_read_frame; break; case SWITCH_STATUS_NOOP: session->raw_read_frame.samples = enc_frame->codec->implementation->samples_per_packet; session->raw_read_frame.timestamp = read_frame->timestamp; session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.ssrc = read_frame->ssrc; session->raw_read_frame.seq = read_frame->seq; *frame = enc_frame; status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n"); *frame = NULL; status = SWITCH_STATUS_GENERR; break; default: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n", session->read_codec->codec_interface->interface_name); *frame = NULL; status = SWITCH_STATUS_GENERR; break; } } else { goto top; } } } done: if (!(*frame)) { status = SWITCH_STATUS_FALSE; } else { if (flag & SFF_CNG) { switch_set_flag((*frame), SFF_CNG); } if (session->bugs) { switch_media_bug_t *bp; switch_bool_t ok = SWITCH_TRUE; int prune = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { continue; } if (switch_test_flag(bp, SMBF_PRUNE)) { prune++; continue; } if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)) { switch_mutex_lock(bp->read_mutex); if (bp->callback) { if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_PING) == SWITCH_FALSE || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) { ok = SWITCH_FALSE; } } switch_mutex_unlock(bp->read_mutex); } if (ok == SWITCH_FALSE) { switch_set_flag(bp, SMBF_PRUNE); prune++; } } switch_thread_rwlock_unlock(session->bug_rwlock); if (prune) { switch_core_media_bug_prune(session); } } } even_more_done: if (!*frame || !(*frame)->codec || !(*frame)->codec->implementation || !switch_core_codec_ready((*frame)->codec)) { *frame = &runtime.dummy_cng_frame; } switch_mutex_unlock(session->read_codec->mutex); switch_mutex_unlock(session->codec_read_mutex); return status; }
static switch_status_t pl_say_time(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args) { int32_t t; switch_time_t target = 0, target_now = 0; switch_time_exp_t tm, tm_now; uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0; const char *tz = NULL; tz = switch_say_file_handle_get_variable(sh, "timezone"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SAY: %s\n", tosay); if (say_args->type == SST_TIME_MEASUREMENT) { int64_t hours = 0; int64_t minutes = 0; int64_t seconds = 0; int64_t r = 0; if (strchr(tosay, ':')) { char *tme = strdup(tosay); char *p; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse time string!\n"); if ((p = strrchr(tme, ':'))) { *p++ = '\0'; seconds = atoi(p); if ((p = strchr(tme, ':'))) { *p++ = '\0'; minutes = atoi(p); if (tme) { hours = atoi(tme); } } else { minutes = atoi(tme); } } free(tme); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse time in seconds!\n"); if ((seconds = atol(tosay)) <= 0) { seconds = (int64_t) switch_epoch_time_now(NULL); } if (seconds >= 60) { minutes = seconds / 60; r = seconds % 60; seconds = r; } if (minutes >= 60) { hours = minutes / 60; r = minutes % 60; minutes = r; } } if (hours) { int hd = 0, hj = 0; say_num(sh, hours, SSM_PRONOUNCED, SSG_FEMININE); hj = hours % 10; hd = (hours/10) % 10; if (hours == 1) { switch_say_file(sh, "time/t_godzina"); }else if (hd != 1 && ( hj == 2 || hj == 3 || hj == 4)) { switch_say_file(sh, "time/t_godziny"); } else { switch_say_file(sh, "time/t_godzin"); } } else { switch_say_file(sh, "digits/0"); switch_say_file(sh, "time/t_godzin"); } if (minutes) { int md = 0, mj = 0; say_num(sh, minutes, SSM_PRONOUNCED, SSG_FEMININE); mj = minutes % 10; md = (minutes/10) % 10; if (minutes == 1) { switch_say_file(sh, "time/minuta"); }else if (md != 1 && ( mj == 2 || mj == 3 || mj == 4)) { switch_say_file(sh, "time/t_minuty"); } else { switch_say_file(sh, "time/t_minut"); } } else { switch_say_file(sh, "digits/0"); switch_say_file(sh, "time/t_minut"); } if (seconds) { int sd = 0, sj = 0; say_num(sh, seconds, SSM_PRONOUNCED, SSG_FEMININE); sj = seconds % 10; sd = (seconds/10) % 10; if (seconds == 1) { switch_say_file(sh, "time/t_sekunda"); }else if (sd != 1 && ( sj == 2 || sj == 3 || sj == 4)) { switch_say_file(sh, "time/t_sekundy"); } else { switch_say_file(sh, "time/t_sekund"); } } else { switch_say_file(sh, "digits/0"); switch_say_file(sh, "time/t_sekund"); } return SWITCH_STATUS_SUCCESS; } if ((t = atol(tosay)) > 0) { target = switch_time_make(t, 0); target_now = switch_micro_time_now(); } else { target = switch_micro_time_now(); target_now = switch_micro_time_now(); } if (tz) { int check = atoi(tz); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz); if (check) { switch_time_exp_tz(&tm, target, check); switch_time_exp_tz(&tm_now, target_now, check); } else { switch_time_exp_tz_name(tz, &tm, target); switch_time_exp_tz_name(tz, &tm_now, target_now); } } else { switch_time_exp_lt(&tm, target); switch_time_exp_lt(&tm_now, target_now); } switch (say_args->type) { case SST_CURRENT_DATE_TIME: say_date = say_time = 1; break; case SST_CURRENT_DATE: say_date = 1; break; case SST_CURRENT_TIME: say_time = 1; break; case SST_SHORT_DATE_TIME: say_time = 1; if (tm.tm_year != tm_now.tm_year) { say_date = 1; break; } if (tm.tm_yday == tm_now.tm_yday) { say_today = 1; break; } if (tm.tm_yday == tm_now.tm_yday - 1) { say_yesterday = 1; break; } if (tm.tm_yday >= tm_now.tm_yday - 5) { say_dow = 1; break; } if (tm.tm_mon != tm_now.tm_mon) { say_month = say_day = say_dow = 1; break; } say_month = say_day = say_dow = 1; break; default: break; } if (say_today) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: today\n"); switch_say_file(sh, "time/t_dzisiaj"); } if (say_yesterday) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: yesterday\n"); switch_say_file(sh, "time/t_wczoraj"); } if (say_dow) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: dow\n"); switch_say_file(sh, "time/day-%d", tm.tm_wday); } if (say_date) { say_year = say_month = say_day = say_dow = 1; say_today = say_yesterday = 0; } if (say_day) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: day\n"); //say_num(sh, tm.tm_mday, SSM_COUNTED, SSG_MASCULINE); switch_say_file(sh, "digits/%02d_pm", tm.tm_mday); } if (say_month) { switch_say_file(sh, "time/mon-%d_D", tm.tm_mon); } if (say_year) { say_num(sh, tm.tm_year + 1900, SSM_COUNTED, SSG_MASCULINE); //switch_say_file(sh, "time/t_roku"); } if (say_time) { switch_say_file(sh, "time/t_godzina"); say_num(sh, tm.tm_hour, SSM_COUNTED, SSG_FEMININE); //switch_say_file(sh, "digits/%da", tm.tm_hour); say_num(sh, tm.tm_min, SSM_PRONOUNCED, SSG_FEMININE); /* switch_say_file(sh, "digits/t_minut");*/ } return SWITCH_STATUS_SUCCESS; }
static switch_status_t de_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) { int32_t t; switch_time_t target = 0; switch_time_exp_t tm; uint8_t say_date = 0, say_time = 0; if (say_args->type == SST_TIME_MEASUREMENT) { int64_t hours = 0; int64_t minutes = 0; int64_t seconds = 0; int64_t r = 0; if (strchr(tosay, ':')) { char *tme = switch_core_session_strdup(session, tosay); char *p; if ((p = strrchr(tme, ':'))) { *p++ = '\0'; seconds = atoi(p); if ((p = strchr(tme, ':'))) { *p++ = '\0'; minutes = atoi(p); if (tme) { hours = atoi(tme); } } else { minutes = atoi(tme); } } } else { if ((seconds = atoi(tosay)) <= 0) { seconds = (int64_t) switch_epoch_time_now(NULL); } if (seconds >= 60) { minutes = seconds / 60; r = seconds % 60; seconds = r; } if (minutes >= 60) { hours = minutes / 60; r = minutes % 60; minutes = r; } } if (hours) { say_num(hours, SSM_PRONOUNCED); if (hours == 1) { say_file("time/hour.wav"); } else { say_file("time/hours.wav"); } } else { say_file("digits/0.wav"); say_file("time/hours.wav"); } if (minutes) { say_num(minutes, SSM_PRONOUNCED); if (minutes == 1) { say_file("time/minute.wav"); } else { say_file("time/minutes.wav"); } } else { say_file("digits/0.wav"); say_file("time/minutes.wav"); } if (seconds) { say_num(seconds, SSM_PRONOUNCED); if (seconds == 1) { say_file("time/second.wav"); } else { say_file("time/seconds.wav"); } } else { say_file("digits/0.wav"); say_file("time/seconds.wav"); } return SWITCH_STATUS_SUCCESS; } if ((t = atoi(tosay)) > 0) { target = switch_time_make(t, 0); } else { target = switch_micro_time_now(); } switch_time_exp_lt(&tm, target); switch (say_args->type) { case SST_CURRENT_DATE_TIME: say_date = say_time = 1; break; case SST_CURRENT_DATE: say_date = 1; break; case SST_CURRENT_TIME: say_time = 1; break; default: break; } if (say_date) { say_file("time/day-%d.wav", tm.tm_wday); say_file("time/mon-%d.wav", tm.tm_mon); say_num(tm.tm_mday, SSM_COUNTED); say_num(tm.tm_year + 1900, SSM_PRONOUNCED); } if (say_time) { int32_t hour = tm.tm_hour, pm = 0; if (hour > 12) { hour -= 12; pm = 1; } else if (hour == 12) { pm = 1; } else if (hour == 0) { hour = 12; pm = 0; } say_num(hour, SSM_PRONOUNCED); say_file("time/oclock.wav"); if (tm.tm_min > 9) { say_num(tm.tm_min, SSM_PRONOUNCED); } else if (tm.tm_min) { say_file("time/oh.wav"); say_num(tm.tm_min, SSM_PRONOUNCED); } say_file("time/%s.wav", pm ? "p-m" : "a-m"); } return SWITCH_STATUS_SUCCESS; }
static switch_status_t sin_say_time(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args) { int32_t t; switch_time_t target = 0, target_now = 0; switch_time_exp_t tm, tm_now; uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0; const char *tz = NULL; tz = switch_say_file_handle_get_variable(sh, "timezone"); if (say_args->type == SST_TIME_MEASUREMENT) { int64_t hours = 0; int64_t minutes = 0; int64_t seconds = 0; int64_t r = 0; if (strchr(tosay, ':')) { char *tme = strdup(tosay); char *p; if ((p = strrchr(tme, ':'))) { *p++ = '\0'; seconds = atoi(p); if ((p = strchr(tme, ':'))) { *p++ = '\0'; minutes = atoi(p); if (tme) { hours = atoi(tme); } } else { minutes = atoi(tme); } } free(tme); } else { if ((seconds = atol(tosay)) <= 0) { seconds = (int64_t) switch_epoch_time_now(NULL); } if (seconds >= 60) { minutes = seconds / 60; r = seconds % 60; seconds = r; } if (minutes >= 60) { hours = minutes / 60; r = minutes % 60; minutes = r; } } if (hours) { if (hours == 1) { switch_say_file(sh, "time/payai"); } else { switch_say_file(sh, "time/paya"); say_num(sh, hours, SSM_PRONOUNCED); } } else { /*switch_say_file(sh, "time/s_hours"); switch_say_file(sh, "digits/s_i-0"); */ } if (minutes) { if (minutes == 1) { switch_say_file(sh, "time/winadiyai"); } else { switch_say_file(sh, "time/winadi"); say_num(sh, minutes, SSM_PRONOUNCED); } } else { /*switch_say_file(sh, "time/s_minutes"); switch_say_file(sh, "digits/s_i-0");*/ } if (seconds) { if (seconds == 1) { switch_say_file(sh, "time/thathparayai"); } else { switch_say_file(sh, "time/thathpara"); say_num(sh, seconds, SSM_PRONOUNCED); } } else { /* switch_say_file(sh, "time/s_seconds"); switch_say_file(sh, "digits/s_i-0");*/ } return SWITCH_STATUS_SUCCESS; } if ((t = atol(tosay)) > 0) { target = switch_time_make(t, 0); target_now = switch_micro_time_now(); } else { target = switch_micro_time_now(); target_now = switch_micro_time_now(); } if (tz) { int check = atoi(tz); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz); if (check) { switch_time_exp_tz(&tm, target, check); switch_time_exp_tz(&tm_now, target_now, check); } else { switch_time_exp_tz_name(tz, &tm, target); switch_time_exp_tz_name(tz, &tm_now, target_now); } } else { switch_time_exp_lt(&tm, target); switch_time_exp_lt(&tm_now, target_now); } switch (say_args->type) { case SST_CURRENT_DATE_TIME: say_date = say_time = 1; break; case SST_CURRENT_DATE: say_date = 1; break; case SST_CURRENT_TIME: say_time = 1; break; case SST_SHORT_DATE_TIME: say_time = 1; if (tm.tm_year != tm_now.tm_year) { say_date = 1; break; } if (tm.tm_yday == tm_now.tm_yday) { say_today = 1; break; } if (tm.tm_yday == tm_now.tm_yday - 1) { say_yesterday = 1; break; } if (tm.tm_yday >= tm_now.tm_yday - 5) { say_dow = 1; break; } if (tm.tm_mon != tm_now.tm_mon) { say_month = say_day = say_dow = 1; break; } say_month = say_day = say_dow = 1; break; default: break; } if (say_today) { switch_say_file(sh, "time/today"); } if (say_yesterday) { switch_say_file(sh, "time/yesterday"); } if (say_dow) { switch_say_file(sh, "time/day-s_%d", tm.tm_wday); } if (say_date) { say_year = say_month = say_day = say_dow = 1; say_today = say_yesterday = 0; } if (say_month) { switch_say_file(sh, "time/mon-s_%d", tm.tm_mon); } if (say_day) { say_num(sh, tm.tm_mday, SSM_COUNTED); } if (say_year) { say_num(sh, tm.tm_year + 1900, SSM_PRONOUNCED_YEAR); } if (say_time) { int32_t hour = tm.tm_hour, pm = 0; if (say_date || say_today || say_yesterday || say_dow) { switch_say_file(sh, "time/at"); } if (hour > 12) { hour -= 12; pm = 1; } else if (hour == 12) { pm = 1; } else if (hour == 0) { hour = 12; pm = 0; } say_num(sh, hour, SSM_PRONOUNCED); if (tm.tm_min > 9) { say_num(sh, tm.tm_min, SSM_PRONOUNCED); } else if (tm.tm_min) { switch_say_file(sh, "time/oh"); say_num(sh, tm.tm_min, SSM_PRONOUNCED); } else { switch_say_file(sh, "time/oclock"); } switch_say_file(sh, "time/%s", pm ? "p-m" : "a-m"); } return SWITCH_STATUS_SUCCESS; }
static int task_thread_loop(int done) { switch_scheduler_task_container_t *tofree, *tp, *last = NULL; switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp; tp = tp->next) { if (done) { tp->destroyed = 1; } else if (!tp->destroyed) { int64_t now = switch_epoch_time_now(NULL); if (now >= tp->task.runtime && !tp->in_thread) { int32_t diff = (int32_t) (now - tp->task.runtime); if (diff > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Task was executed late by %d seconds %u %s (%s)\n", diff, tp->task.task_id, tp->desc, switch_str_nil(tp->task.group)); } tp->executed = now; if (switch_test_flag(tp, SSHF_OWN_THREAD)) { switch_thread_t *thread; switch_threadattr_t *thd_attr; switch_core_new_memory_pool(&tp->pool); switch_threadattr_create(&thd_attr, tp->pool); switch_threadattr_detach_set(thd_attr, 1); tp->in_thread = 1; switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool); } else { switch_scheduler_execute(tp); } } } } switch_mutex_unlock(globals.task_mutex); switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp;) { if (tp->destroyed && !tp->in_thread) { tofree = tp; tp = tp->next; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting task %u %s (%s)\n", tofree->task.task_id, tofree->desc, switch_str_nil(tofree->task.group)); if (last) { last->next = tofree->next; } else { globals.task_list = tofree->next; } switch_safe_free(tofree->task.group); if (tofree->task.cmd_arg && switch_test_flag(tofree, SSHF_FREE_ARG)) { free(tofree->task.cmd_arg); } switch_safe_free(tofree->desc); free(tofree); } else { last = tp; tp = tp->next; } } switch_mutex_unlock(globals.task_mutex); return done; }
static void event_handler(switch_event_t *event) { uint8_t send = 0; if (globals.running != 1) { return; } if (event->subclass_name && (!strcmp(event->subclass_name, MULTICAST_EVENT) || !strcmp(event->subclass_name, MULTICAST_PEERUP) || !strcmp(event->subclass_name, MULTICAST_PEERDOWN))) { char *event_name, *sender; if ((event_name = switch_event_get_header(event, "orig-event-name")) && !strcasecmp(event_name, "HEARTBEAT") && (sender = switch_event_get_header(event, "orig-multicast-sender"))) { struct peer_status *p; time_t now = switch_epoch_time_now(NULL); if (!(p = switch_core_hash_find(globals.peer_hash, sender))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Host %s not already in hash\n", sender); p = switch_core_alloc(module_pool, sizeof(struct peer_status)); p->active = SWITCH_FALSE; p->lastseen = 0; /*} else { */ /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Host %s last seen %d seconds ago\n", sender, now - p->lastseen); */ } if (!p->active) { switch_event_t *local_event; if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_PEERUP) == SWITCH_STATUS_SUCCESS) { char lastseen[21]; switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", sender); if (p->lastseen) { switch_snprintf(lastseen, sizeof(lastseen), "%d", (int) p->lastseen); } else { switch_snprintf(lastseen, sizeof(lastseen), "%s", "Never"); } switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Lastseen", lastseen); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Peer %s has come up; last seen: %s\n", sender, lastseen); switch_event_fire(&local_event); } } p->active = SWITCH_TRUE; p->lastseen = now; switch_core_hash_insert(globals.peer_hash, sender, p); } /* ignore our own events to avoid ping pong */ return; } if (event->event_id == SWITCH_EVENT_RELOADXML) { switch_mutex_lock(globals.mutex); switch_core_hash_destroy(&globals.event_hash); globals.event_hash = NULL; if (globals.psk) { switch_safe_free(globals.psk); globals.psk = NULL; } switch_core_hash_init(&globals.event_hash, module_pool); memset(globals.event_list, 0, SWITCH_EVENT_ALL + 1); if (load_config() != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to reload config file\n"); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Event Multicast Reloaded\n"); } switch_mutex_unlock(globals.mutex); } if (event->event_id == SWITCH_EVENT_HEARTBEAT) { switch_hash_index_t *cur; switch_ssize_t keylen; const void *key; void *value; time_t now = switch_epoch_time_now(NULL); struct peer_status *last; char *host; for (cur = switch_hash_first(NULL, globals.peer_hash); cur; cur = switch_hash_next(cur)) { switch_hash_this(cur, &key, &keylen, &value); host = (char *) key; last = (struct peer_status *) value; if (last->active && (now - (last->lastseen)) > 60) { switch_event_t *local_event; last->active = SWITCH_FALSE; if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_PEERDOWN) == SWITCH_STATUS_SUCCESS) { char lastseen[21]; switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", host); switch_snprintf(lastseen, sizeof(lastseen), "%d", (int) last->lastseen); switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Lastseen", lastseen); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Peer %s has gone down; last seen: %s\n", host, lastseen); switch_event_fire(&local_event); } } } } switch_mutex_lock(globals.mutex); if (globals.event_list[(uint8_t) SWITCH_EVENT_ALL]) { send = 1; } else if ((globals.event_list[(uint8_t) event->event_id])) { if (event->event_id != SWITCH_EVENT_CUSTOM || (event->subclass_name && switch_core_hash_find(globals.event_hash, event->subclass_name))) { send = 1; } } switch_mutex_unlock(globals.mutex); if (send) { char *packet; switch (event->event_id) { case SWITCH_EVENT_LOG: return; default: switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Multicast-Sender", switch_core_get_switchname()); if (switch_event_serialize(event, &packet, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { size_t len; char *buf; #ifdef HAVE_OPENSSL int outlen, tmplen; EVP_CIPHER_CTX ctx; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; switch_uuid_t uuid; switch_uuid_get(&uuid); switch_uuid_format(uuid_str, &uuid); len = strlen(packet) + SWITCH_UUID_FORMATTED_LENGTH + EVP_MAX_IV_LENGTH + strlen((char *) MAGIC); #else len = strlen(packet) + strlen((char *) MAGIC); #endif buf = malloc(len + 1); memset(buf, 0, len + 1); switch_assert(buf); #ifdef HAVE_OPENSSL if (globals.psk) { switch_copy_string(buf, uuid_str, SWITCH_UUID_FORMATTED_LENGTH); EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit(&ctx, EVP_bf_cbc(), NULL, NULL); EVP_CIPHER_CTX_set_key_length(&ctx, strlen(globals.psk)); EVP_EncryptInit(&ctx, NULL, (unsigned char *) globals.psk, (unsigned char *) uuid_str); EVP_EncryptUpdate(&ctx, (unsigned char *) buf + SWITCH_UUID_FORMATTED_LENGTH, &outlen, (unsigned char *) packet, (int) strlen(packet)); EVP_EncryptUpdate(&ctx, (unsigned char *) buf + SWITCH_UUID_FORMATTED_LENGTH + outlen, &tmplen, (unsigned char *) MAGIC, (int) strlen((char *) MAGIC)); outlen += tmplen; EVP_EncryptFinal(&ctx, (unsigned char *) buf + SWITCH_UUID_FORMATTED_LENGTH + outlen, &tmplen); outlen += tmplen; len = (size_t) outlen + SWITCH_UUID_FORMATTED_LENGTH; *(buf + SWITCH_UUID_FORMATTED_LENGTH + outlen) = '\0'; } else { #endif switch_copy_string(buf, packet, len); switch_copy_string(buf + strlen(packet), (char *) MAGIC, strlen((char *) MAGIC) + 1); #ifdef HAVE_OPENSSL } #endif switch_socket_sendto(globals.udp_socket, globals.addr, 0, buf, &len); switch_safe_free(packet); switch_safe_free(buf); } break; } } return; }
static void *SWITCH_THREAD_FUNC limit_remote_thread(switch_thread_t *thread, void *obj) { limit_remote_t *remote = (limit_remote_t*)obj; while (remote->state > REMOTE_OFF) { if (remote->state != REMOTE_UP) { if (esl_connect_timeout(&remote->handle, remote->host, remote->port, remote->username, remote->password, 5000) == ESL_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to remote FreeSWITCH (%s) at %s:%d\n", remote->name, remote->host, remote->port); remote->state = REMOTE_UP; } else { esl_disconnect(&remote->handle); memset(&remote->handle, 0, sizeof(remote->handle)); } } else { if (esl_send_recv_timed(&remote->handle, "api hash_dump limit", 5000) != ESL_SUCCESS) { esl_disconnect(&remote->handle); memset(&remote->handle, 0, sizeof(remote->handle)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Disconnected from remote FreeSWITCH (%s) at %s:%d\n", remote->name, remote->host, remote->port); memset(&remote->handle, 0, sizeof(remote->handle)); remote->state = REMOTE_DOWN; /* Delete all remote tracking entries */ switch_thread_rwlock_wrlock(remote->rwlock); switch_core_hash_delete_multi(remote->index, limit_hash_remote_cleanup_callback, NULL); switch_thread_rwlock_unlock(remote->rwlock); } else { if (!zstr(remote->handle.last_sr_event->body)) { char *data = strdup(remote->handle.last_sr_event->body); char *p = data, *p2; switch_time_t now = switch_epoch_time_now(NULL); while (p && *p) { /* We are getting the limit data as: L/key/usage/rate/interval/last_checked */ if ((p2 = strchr(p, '\n'))) { *p2++ = '\0'; } /* Now p points at the beginning of the current line, p2 at the start of the next one */ if (*p == 'L') { /* Limit data */ char *argv[5]; int argc = switch_split(p+2, '/', argv); if (argc < 5) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "[%s] Protocol error: missing argument in line: %s\n", remote->name, p); } else { limit_hash_item_t *item; switch_thread_rwlock_wrlock(remote->rwlock); if (!(item = switch_core_hash_find(remote->index, argv[0]))) { item = malloc(sizeof(*item)); switch_core_hash_insert(remote->index, argv[0], item); } item->total_usage = atoi(argv[1]); item->rate_usage = atoi(argv[2]); item->interval = atoi(argv[3]); item->last_check = atoi(argv[4]); item->last_update = now; switch_thread_rwlock_unlock(remote->rwlock); } } p = p2; } free(data); /* Now free up anything that wasn't in this update since it means their usage is 0 */ switch_thread_rwlock_wrlock(remote->rwlock); switch_core_hash_delete_multi(remote->index, limit_hash_remote_cleanup_callback, (void*)(intptr_t)now); switch_thread_rwlock_unlock(remote->rwlock); } } } switch_yield(remote->interval * 1000); } remote->thread = NULL; return NULL; }
static switch_status_t fr_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) { int32_t t; switch_time_t target = 0, target_now = 0; switch_time_exp_t tm, tm_now; uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0; switch_channel_t *channel = switch_core_session_get_channel(session); const char *tz = switch_channel_get_variable(channel, "timezone"); if (say_args->type == SST_TIME_MEASUREMENT) { int64_t hours = 0; int64_t minutes = 0; int64_t seconds = 0; int64_t r = 0; if (strchr(tosay, ':')) { char *tme = switch_core_session_strdup(session, tosay); char *p; if ((p = strrchr(tme, ':'))) { *p++ = '\0'; seconds = atoi(p); if ((p = strchr(tme, ':'))) { *p++ = '\0'; minutes = atoi(p); if (tme) { hours = atoi(tme); } } else { minutes = atoi(tme); } } } else { if ((seconds = atol(tosay)) <= 0) { seconds = (int64_t) switch_epoch_time_now(NULL); } if (seconds >= 60) { minutes = seconds / 60; r = seconds % 60; seconds = r; } if (minutes >= 60) { hours = minutes / 60; r = minutes % 60; minutes = r; } } say_args->gender = SSG_FEMININE; if (hours) { say_num(hours, SSM_PRONOUNCED); say_file("time/hour.wav"); } else { /* TODO MINUIT */ say_file("digits/0.wav"); say_file("time/hour.wav"); } if (minutes) { say_num(minutes, SSM_PRONOUNCED); say_file("time/minute.wav"); } else { /* TODO Aucune idee quoi faire jouer icit */ say_file("digits/0.wav"); say_file("time/minute.wav"); } if (seconds) { say_num(seconds, SSM_PRONOUNCED); say_file("time/second.wav"); } else { /* TODO Aucune idee quoi faire jouer icit */ say_file("digits/0.wav"); say_file("time/second.wav"); } return SWITCH_STATUS_SUCCESS; } if ((t = atol(tosay)) > 0) { target = switch_time_make(t, 0); target_now = switch_micro_time_now(); } else { target = switch_micro_time_now(); target_now = switch_micro_time_now(); } if (tz) { int check = atoi(tz); if (check) { switch_time_exp_tz(&tm, target, check); switch_time_exp_tz(&tm_now, target_now, check); } else { switch_time_exp_tz_name(tz, &tm, target); switch_time_exp_tz_name(tz, &tm_now, target_now); } } else { switch_time_exp_lt(&tm, target); switch_time_exp_lt(&tm_now, target_now); } switch (say_args->type) { case SST_CURRENT_DATE_TIME: say_date = say_time = 1; break; case SST_CURRENT_DATE: say_date = 1; break; case SST_CURRENT_TIME: say_time = 1; break; case SST_SHORT_DATE_TIME: say_time = 1; if (tm.tm_year != tm_now.tm_year) { say_date = 1; break; } if (tm.tm_yday == tm_now.tm_yday) { say_today = 1; break; } if (tm.tm_yday == tm_now.tm_yday - 1) { say_yesterday = 1; break; } if (tm.tm_yday >= tm_now.tm_yday - 5) { say_dow = 1; break; } if (tm.tm_mon != tm_now.tm_mon) { say_month = say_day = say_dow = 1; break; } say_month = say_day = say_dow = 1; break; default: break; } if (say_today) { say_file("time/today.wav"); } if (say_yesterday) { say_file("time/yesterday.wav"); } if (say_dow) { say_file("time/day-%d.wav", tm.tm_wday); } if (say_date) { say_year = say_month = say_day = say_dow = 1; say_today = say_yesterday = 0; } if (say_day) { if (tm.tm_mday == 1) { /* 1 er Janvier,... 2 feb, 23 dec... */ say_args->gender = SSG_MASCULINE; say_num(tm.tm_mday, SSM_COUNTED); } else { say_args->gender = SSG_FEMININE; say_num(tm.tm_mday, SSM_PRONOUNCED); } } if (say_month) { say_file("time/mon-%d.wav", tm.tm_mon); } if (say_year) { say_args->gender = SSG_MASCULINE; say_num(tm.tm_year + 1900, SSM_PRONOUNCED); } if (say_time) { if (say_date || say_today || say_yesterday || say_dow) { say_file("time/at.wav"); } say_args->gender = SSG_FEMININE; say_num(tm.tm_hour, SSM_PRONOUNCED); say_file("time/hour.wav"); if (tm.tm_min) { say_num(tm.tm_min, SSM_PRONOUNCED); } } return SWITCH_STATUS_SUCCESS; }
/* marshall frames from the call leg to the conference thread for muxing to other call legs */ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *obj) { switch_event_t *event; conference_member_t *member = obj; switch_channel_t *channel; switch_status_t status; switch_frame_t *read_frame = NULL; uint32_t hangover = 40, hangunder = 5, hangover_hits = 0, hangunder_hits = 0, diff_level = 400; switch_core_session_t *session = member->session; uint32_t flush_len; switch_frame_t tmp_frame = { 0 }; if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { goto end; } switch_assert(member != NULL); conference_utils_member_clear_flag_locked(member, MFLAG_TALKING); channel = switch_core_session_get_channel(session); switch_core_session_get_read_impl(session, &member->read_impl); switch_channel_audio_sync(channel); flush_len = switch_samples_per_packet(member->conference->rate, member->conference->interval) * 2 * member->conference->channels * (500 / member->conference->interval); /* As long as we have a valid read, feed that data into an input buffer where the conference thread will take it and mux it with any audio from other channels. */ while (conference_utils_member_test_flag(member, MFLAG_RUNNING) && switch_channel_ready(channel)) { if (switch_channel_ready(channel) && switch_channel_test_app_flag(channel, CF_APP_TAGGED)) { switch_yield(100000); continue; } /* Read a frame. */ status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); switch_mutex_lock(member->read_mutex); /* end the loop, if appropriate */ if (!SWITCH_READ_ACCEPTABLE(status) || !conference_utils_member_test_flag(member, MFLAG_RUNNING)) { switch_mutex_unlock(member->read_mutex); break; } if (switch_channel_test_flag(channel, CF_VIDEO) && !conference_utils_member_test_flag(member, MFLAG_ACK_VIDEO)) { conference_utils_member_set_flag_locked(member, MFLAG_ACK_VIDEO); conference_video_check_avatar(member, SWITCH_FALSE); switch_core_session_video_reinit(member->session); conference_video_set_floor_holder(member->conference, member, SWITCH_FALSE); } else if (conference_utils_member_test_flag(member, MFLAG_ACK_VIDEO) && !switch_channel_test_flag(channel, CF_VIDEO)) { conference_video_check_avatar(member, SWITCH_FALSE); } /* if we have caller digits, feed them to the parser to find an action */ if (switch_channel_has_dtmf(channel)) { char dtmf[128] = ""; switch_channel_dequeue_dtmf_string(channel, dtmf, sizeof(dtmf)); if (conference_utils_member_test_flag(member, MFLAG_DIST_DTMF)) { conference_member_send_all_dtmf(member, member->conference, dtmf); } else if (member->dmachine) { char *p; char str[2] = ""; for (p = dtmf; p && *p; p++) { str[0] = *p; switch_ivr_dmachine_feed(member->dmachine, str, NULL); } } } else if (member->dmachine) { switch_ivr_dmachine_ping(member->dmachine, NULL); } if (switch_queue_size(member->dtmf_queue)) { switch_dtmf_t *dt; void *pop; if (switch_queue_trypop(member->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) { dt = (switch_dtmf_t *) pop; switch_core_session_send_dtmf(member->session, dt); free(dt); } } if (switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) { member->reset_media = 10; switch_channel_audio_sync(member->channel); switch_channel_clear_flag(member->channel, CF_CONFERENCE_RESET_MEDIA); } if (member->reset_media) { if (--member->reset_media > 0) { goto do_continue; } if (conference_member_setup_media(member, member->conference)) { switch_mutex_unlock(member->read_mutex); break; } member->loop_loop = 1; goto do_continue; } if (switch_test_flag(read_frame, SFF_CNG)) { if (member->conference->agc_level) { member->nt_tally++; } if (hangunder_hits) { hangunder_hits--; } if (conference_utils_member_test_flag(member, MFLAG_TALKING)) { if (++hangover_hits >= hangover) { hangover_hits = hangunder_hits = 0; conference_utils_member_clear_flag_locked(member, MFLAG_TALKING); conference_member_update_status_field(member); conference_member_check_agc_levels(member); conference_member_clear_avg(member); member->score_iir = 0; member->floor_packets = 0; if (test_eflag(member->conference, EFLAG_STOP_TALKING) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_member_add_event_data(member, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-talking"); switch_event_fire(&event); } } } goto do_continue; } if (member->nt_tally > (int32_t)(member->read_impl.actual_samples_per_second / member->read_impl.samples_per_packet) * 3) { member->agc_volume_in_level = 0; conference_member_clear_avg(member); } /* Check for input volume adjustments */ if (!member->conference->agc_level) { member->conference->agc_level = 0; conference_member_clear_avg(member); } /* if the member can speak, compute the audio energy level and */ /* generate events when the level crosses the threshold */ if ((conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) || conference_utils_member_test_flag(member, MFLAG_MUTE_DETECT))) { uint32_t energy = 0, i = 0, samples = 0, j = 0; int16_t *data; int agc_period = (member->read_impl.actual_samples_per_second / member->read_impl.samples_per_packet) / 4; data = read_frame->data; member->score = 0; if (member->volume_in_level) { switch_change_sln_volume(read_frame->data, (read_frame->datalen / 2) * member->conference->channels, member->volume_in_level); } if (member->agc_volume_in_level) { switch_change_sln_volume_granular(read_frame->data, (read_frame->datalen / 2) * member->conference->channels, member->agc_volume_in_level); } if ((samples = read_frame->datalen / sizeof(*data) / member->read_impl.number_of_channels)) { for (i = 0; i < samples; i++) { energy += abs(data[j]); j += member->read_impl.number_of_channels; } member->score = energy / samples; } if (member->vol_period) { member->vol_period--; } if (member->conference->agc_level && member->score && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && conference_member_noise_gate_check(member) ) { int last_shift = abs((int)(member->last_score - member->score)); if (member->score && member->last_score && last_shift > 900) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7, "AGC %s:%d drop anomalous shift of %d\n", member->conference->name, member->id, last_shift); } else { member->avg_tally += member->score; member->avg_itt++; if (!member->avg_itt) member->avg_itt++; member->avg_score = member->avg_tally / member->avg_itt; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7, "AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d\n", member->conference->name, member->id, member->conference->agc_level - member->avg_score, member->conference->agc_level, member->score, member->avg_score, member->agc_volume_in_level); if (++member->agc_concur >= agc_period) { if (!member->vol_period) { conference_member_check_agc_levels(member); } member->agc_concur = 0; } } else { member->nt_tally++; } member->score_iir = (int) (((1.0 - SCORE_DECAY) * (float) member->score) + (SCORE_DECAY * (float) member->score_iir)); if (member->score_iir > SCORE_MAX_IIR) { member->score_iir = SCORE_MAX_IIR; } if (conference_member_noise_gate_check(member)) { uint32_t diff = member->score - member->energy_level; if (hangover_hits) { hangover_hits--; } if (member->conference->agc_level) { member->nt_tally = 0; } if (member == member->conference->floor_holder) { member->floor_packets++; } if (diff >= diff_level || ++hangunder_hits >= hangunder) { hangover_hits = hangunder_hits = 0; member->last_talking = switch_epoch_time_now(NULL); if (!conference_utils_member_test_flag(member, MFLAG_TALKING)) { conference_utils_member_set_flag_locked(member, MFLAG_TALKING); conference_member_update_status_field(member); member->floor_packets = 0; if (test_eflag(member->conference, EFLAG_START_TALKING) && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_member_add_event_data(member, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "start-talking"); switch_event_fire(&event); } if (conference_utils_member_test_flag(member, MFLAG_MUTE_DETECT) && !conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) { if (!zstr(member->conference->mute_detect_sound)) { conference_utils_member_set_flag(member, MFLAG_INDICATE_MUTE_DETECT); } if (test_eflag(member->conference, EFLAG_MUTE_DETECT) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_member_add_event_data(member, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "mute-detect"); switch_event_fire(&event); } } } } } else { if (hangunder_hits) { hangunder_hits--; } if (member->conference->agc_level) { member->nt_tally++; } if (conference_utils_member_test_flag(member, MFLAG_TALKING) && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) { switch_event_t *event; if (++hangover_hits >= hangover) { hangover_hits = hangunder_hits = 0; conference_utils_member_clear_flag_locked(member, MFLAG_TALKING); conference_member_update_status_field(member); conference_member_check_agc_levels(member); conference_member_clear_avg(member); if (test_eflag(member->conference, EFLAG_STOP_TALKING) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_member_add_event_data(member, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-talking"); switch_event_fire(&event); } } } } member->last_score = member->score; if (member == member->conference->floor_holder) { if (member->id != member->conference->video_floor_holder && (member->floor_packets > member->conference->video_floor_packets || member->energy_level == 0)) { conference_video_set_floor_holder(member->conference, member, SWITCH_FALSE); } } } /* skip frames that are not actual media or when we are muted or silent */ if ((conference_utils_member_test_flag(member, MFLAG_TALKING) || member->energy_level == 0 || conference_utils_test_flag(member->conference, CFLAG_AUDIO_ALWAYS)) && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && !conference_utils_test_flag(member->conference, CFLAG_WAIT_MOD) && (member->conference->count > 1 || (member->conference->record_count && member->conference->count >= member->conference->min_recording_participants))) { switch_audio_resampler_t *read_resampler = member->read_resampler; void *data; uint32_t datalen; if (read_resampler) { int16_t *bptr = (int16_t *) read_frame->data; int len = (int) read_frame->datalen; switch_resample_process(read_resampler, bptr, len / 2 / member->read_impl.number_of_channels); memcpy(member->resample_out, read_resampler->to, read_resampler->to_len * 2 * member->read_impl.number_of_channels); len = read_resampler->to_len * 2 * member->read_impl.number_of_channels; datalen = len; data = member->resample_out; } else { data = read_frame->data; datalen = read_frame->datalen; } tmp_frame.data = data; tmp_frame.datalen = datalen; tmp_frame.rate = member->conference->rate; conference_member_check_channels(&tmp_frame, member, SWITCH_TRUE); if (datalen) { switch_size_t ok = 1; /* Write the audio into the input buffer */ switch_mutex_lock(member->audio_in_mutex); if (switch_buffer_inuse(member->audio_buffer) > flush_len) { switch_buffer_toss(member->audio_buffer, tmp_frame.datalen); } ok = switch_buffer_write(member->audio_buffer, tmp_frame.data, tmp_frame.datalen); switch_mutex_unlock(member->audio_in_mutex); if (!ok) { switch_mutex_unlock(member->read_mutex); break; } } } do_continue: switch_mutex_unlock(member->read_mutex); } if (switch_queue_size(member->dtmf_queue)) { switch_dtmf_t *dt; void *pop; while (switch_queue_trypop(member->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) { dt = (switch_dtmf_t *) pop; free(dt); } } switch_resample_destroy(&member->read_resampler); switch_core_session_rwunlock(session); end: conference_utils_member_clear_flag_locked(member, MFLAG_ITHREAD); return NULL; }
static switch_status_t th_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) { int32_t t; switch_time_t target = 0; switch_time_exp_t tm; #if 0 switch_time_t this_morning; switch_time_exp_t tm2; #endif uint8_t say_date = 0; uint8_t say_time = 0; if (say_args->type == SST_TIME_MEASUREMENT) { int64_t hours = 0; int64_t minutes = 0; int64_t seconds = 0; int64_t r = 0; if (strchr(tosay, ':')) { char *tme = switch_core_session_strdup(session, tosay); char *p; if ((p = strrchr(tme, ':'))) { *p++ = '\0'; seconds = atoi(p); if ((p = strchr(tme, ':'))) { *p++ = '\0'; minutes = atoi(p); if (tme) { hours = atoi(tme); } } else { minutes = atoi(tme); } } } else { if ((seconds = atoi(tosay)) <= 0) { seconds = (int64_t) switch_epoch_time_now(NULL); } if (seconds >= 60) { minutes = seconds / 60; r = seconds % 60; seconds = r; } if (minutes >= 60) { hours = minutes / 60; r = minutes % 60; minutes = r; } } if (hours) { if (hours == 2) { say_file("time/2s.wav"); } else { say_num(hours, SSM_PRONOUNCED); } say_file("time/hours.wav"); } if (minutes) { if (minutes == 2) { say_file("time/2s.wav"); } else { say_num(minutes, SSM_PRONOUNCED); } say_file("time/minute.wav"); } else { if (hours) { say_file("digits/0.wav"); say_file("time/minute.wav"); } } if (seconds) { if (seconds == 2) { say_file("time/2s.wav"); } else { say_num(hours, SSM_PRONOUNCED); } say_file("time/seconds.wav"); } else { if (hours || minutes) { say_file("digits/0.wav"); say_file("time/second.wav"); } } return SWITCH_STATUS_SUCCESS; } if ((t = atoi(tosay)) > 0) target = switch_time_make(t, 0); else target = switch_micro_time_now(); switch_time_exp_lt(&tm, target); switch (say_args->type) { case SST_CURRENT_DATE_TIME: say_date = say_time = 1; break; case SST_CURRENT_DATE: say_date = 1; break; case SST_CURRENT_TIME: say_time = 1; break; default: break; } if (say_date) { say_num(tm.tm_year + 1900, SSM_ITERATED); say_file("time/year.wav"); say_num(tm.tm_mon + 1, SSM_PRONOUNCED); say_file("time/month.wav"); say_num(tm.tm_mday, SSM_PRONOUNCED); say_file("time/day.wav"); say_file("time/day-%d.wav", tm.tm_wday); #if 0 tm = *localtime(&then); this_morning = switch_micro_time_now(); switch_time_exp_lt(&tm2, this_morning); tm2->tm_hour = 0; tm2->tm_min = 0; tm2->tm_sec = 0; this_morning = mktime(tm2); if (this_morning <= then && then < (this_morning + 86400L)) { say_file("time/today.wav"); } else if ((this_morning - 86400L) <= then && then < this_morning) { say_file("time/yesterday.wav"); } else if ((this_morning + 86400L) <= then && then < (this_morning + 2 * 86400L)) { say_file("time/tomorrow.wav"); } else if ((this_morning - 7 * 86400L) <= then && then < this_morning) { say_file("time/day-%d.wav", tm.tm_wday); } else { if (tm2->tm_year != tm.tm_year) { say_num(tm.tm_year + 1900, SSM_ITERATED); say_file("time/year.wav"); } /*endif */ if (tm2->tm_year != tm.tm_year || tm2->tm_mon != tm.tm_mon) { say_num(tm.tm_mon + 1, SSM_PRONOUNCED); say_file("time/month.wav"); } /*endif */ /* Always say the day and the day of the week */ say_num(tm.tm_mday, SSM_PRONOUNCED); say_file("time/day.wav"); say_file("time/day-%d.wav", tm.tm_wday); } #endif } if (say_time) { int32_t hour = tm.tm_hour; if (hour < 6) { say_file("time/morning.wav"); } else if (hour < 12) { say_file("time/am.wav"); } else if (tm.tm_hour < 18) { say_file("time/pm.wav"); } else { say_file("time/evening.wav"); } if (hour > 12) hour -= 12; if (hour == 0) hour = 12; if (hour == 2) { say_file("time/2s.wav"); } else { say_num(hour, SSM_PRONOUNCED); } say_file("time/hour.wav"); if (tm.tm_min == 2) { say_file("time/2s.wav"); } else { say_num(tm.tm_min, SSM_PRONOUNCED); } say_file("time/minute.wav"); } return SWITCH_STATUS_SUCCESS; }
static switch_status_t ru_say_time(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args,say_opt_t *say_opt) { int32_t t; char buf[80]; switch_time_t target = 0, target_now = 0; switch_time_exp_t tm, tm_now; uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0; const char *tz = NULL; tz = switch_say_file_handle_get_variable(sh, "timezone"); //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " ru_say_time %s type=%d method=%d\n", tosay, say_args->type, say_args->method); if (say_args->type == SST_TIME_MEASUREMENT) { int64_t hours = 0; int64_t minutes = 0; int64_t seconds = 0; int64_t r = 0; if (strchr(tosay, ':')) { char *tme = strdup(tosay); char *p; if ((p = strrchr(tme, ':'))) { *p++ = '\0'; seconds = atoi(p); if ((p = strchr(tme, ':'))) { *p++ = '\0'; minutes = atoi(p); if (tme) { hours = atoi(tme); } } else { minutes = atoi(tme); } } free(tme); } else { if ((seconds = atol(tosay)) <= 0) { seconds = (int64_t) switch_epoch_time_now(NULL); } if (seconds >= 60) { minutes = seconds / 60; r = seconds % 60; } if (minutes >= 60) { hours = minutes / 60; r = minutes % 60; minutes = r; } } switch_snprintf(buf, sizeof(buf), "%u", (unsigned) hours); ru_say_count(sh, buf, male, nominativus); if (((hours % 10) == 1) && (hours != 11)) { /* час */ switch_say_file(sh, "time/hour"); } else if (((hours % 10 > 1) && (hours % 10 < 5)) && ((hours < 12) || (hours > 14))) { switch_say_file(sh, "time/hours-a"); /* часа */ } else { switch_say_file(sh, "time/hours"); /* часов */ } switch_snprintf(buf, sizeof(buf), "%u", (unsigned) minutes); //перевести минуты в *char ru_say_count(sh, buf, female, nominativus); if (((minutes % 10) == 1) && (minutes != 11)) { switch_say_file(sh, "time/minute"); //минута } else if (((minutes % 10 > 1) && (minutes % 10 < 5)) && ((minutes < 12) || (minutes > 14))) { switch_say_file(sh, "time/minutes-i"); // минуты } else { switch_say_file(sh, "time/minutes"); //минут } if (seconds != 0) { switch_snprintf(buf, sizeof(buf), "%u", (unsigned) seconds); ru_say_count(sh, buf, female, nominativus); if (((seconds % 10) == 1) && (seconds != 11)) { switch_say_file(sh, "time/second"); // секунда } else if (((seconds % 10 > 1) && (seconds % 10 < 5)) && ((seconds < 12) || (seconds > 14))) { switch_say_file(sh, "time/seconds-i"); // секуны } else { switch_say_file(sh, "time/seconds"); //секунд } } return SWITCH_STATUS_SUCCESS; } if ((t = atol(tosay)) > 0) { target = switch_time_make(t, 0); target_now = switch_micro_time_now(); } else { target = switch_micro_time_now(); target_now = switch_micro_time_now(); } if (tz) { int check = atoi(tz); //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz); if (check) { switch_time_exp_tz(&tm, target, check); switch_time_exp_tz(&tm_now, target_now, check); } else { switch_time_exp_tz_name(tz, &tm, target); switch_time_exp_tz_name(tz, &tm_now, target_now); } } else { switch_time_exp_lt(&tm, target); switch_time_exp_lt(&tm_now, target_now); } switch (say_args->type) { case SST_CURRENT_DATE_TIME: say_date = say_time = 1; break; case SST_CURRENT_DATE: say_date = 1; break; case SST_CURRENT_TIME: say_time = 1; break; case SST_SHORT_DATE_TIME: say_time = 1; tm.tm_sec = 0; // В коротком варианте секунды не проговариваем if (tm.tm_year != tm_now.tm_year) { say_date = 1; break; } if (tm.tm_yday == tm_now.tm_yday) { say_today = 1; break; } if (tm.tm_yday == tm_now.tm_yday - 1) { say_yesterday = 1; break; } if (tm.tm_yday >= tm_now.tm_yday - 5) { say_dow = 1; break; } if (tm.tm_mon != tm_now.tm_mon) { say_month = say_day = say_dow = 1; break; } say_month = say_day = say_dow = 1; break; default: break; } if (say_today) { switch_say_file(sh, "time/today"); } if (say_yesterday) { switch_say_file(sh, "time/yesterday"); } if (say_dow) { switch_say_file(sh, "time/day-%d", tm.tm_wday); } if (say_date) { say_year = say_month = say_day = say_dow = 1; say_today = say_yesterday = 0; } if (say_day) { switch_snprintf(buf, sizeof(buf), "%u", (unsigned) tm.tm_mday); ru_say_count(sh, buf, male_h, genitivus); } if (say_month) { switch_say_file(sh, "time/mon-%d", tm.tm_mon); } if (say_year) { switch_snprintf(buf, sizeof(buf), "%u", (unsigned) (tm.tm_year + 1900)); ru_say_count(sh, buf, male_h, genitivus); switch_say_file(sh, "time/h-year"); } if (say_time) { if (say_month || say_year || say_date || say_dow) { switch_say_file(sh, "time/at"); } switch_snprintf(buf, sizeof(buf), "%d:%d:%d", tm.tm_hour, tm.tm_min, tm.tm_sec); say_args->type = SST_TIME_MEASUREMENT; ru_say_time(sh, buf, say_args,say_opt); } return SWITCH_STATUS_SUCCESS; }
static int task_thread_loop(int done) { switch_scheduler_task_container_t *tofree, *tp, *last = NULL; switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp; tp = tp->next) { if (done) { tp->destroyed = 1; } else if (!tp->destroyed) { int64_t now = switch_epoch_time_now(NULL); if (now >= tp->task.runtime && !tp->in_thread) { int32_t diff = (int32_t) (now - tp->task.runtime); if (diff > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Task was executed late by %d seconds %u %s (%s)\n", diff, tp->task.task_id, tp->desc, switch_str_nil(tp->task.group)); } tp->executed = now; if (switch_test_flag(tp, SSHF_OWN_THREAD)) { switch_thread_t *thread; switch_threadattr_t *thd_attr; switch_core_new_memory_pool(&tp->pool); switch_threadattr_create(&thd_attr, tp->pool); switch_threadattr_detach_set(thd_attr, 1); tp->in_thread = 1; switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool); } else { tp->running = 1; switch_mutex_unlock(globals.task_mutex); switch_scheduler_execute(tp); switch_mutex_lock(globals.task_mutex); tp->running = 0; } } } } switch_mutex_unlock(globals.task_mutex); switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp;) { if (tp->destroyed && !tp->in_thread) { switch_event_t *event; tofree = tp; tp = tp->next; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting task %u %s (%s)\n", tofree->task.task_id, tofree->desc, switch_str_nil(tofree->task.group)); if (switch_event_create(&event, SWITCH_EVENT_DEL_SCHEDULE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tofree->task.task_id); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Desc", tofree->desc); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Group", switch_str_nil(tofree->task.group)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" SWITCH_INT64_T_FMT, tofree->task.runtime); switch_queue_push(globals.event_queue, event); event = NULL; } if (last) { last->next = tofree->next; } else { globals.task_list = tofree->next; } switch_safe_free(tofree->task.group); if (tofree->task.cmd_arg && switch_test_flag(tofree, SSHF_FREE_ARG)) { free(tofree->task.cmd_arg); } switch_safe_free(tofree->desc); free(tofree); } else { last = tp; tp = tp->next; } } switch_mutex_unlock(globals.task_mutex); return done; }
switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req) { skinny_message_t *request; switch_size_t mlen, bytes = 0; char mbuf[SKINNY_MESSAGE_MAXSIZE] = ""; char *ptr; switch_status_t status = SWITCH_STATUS_SUCCESS; request = calloc(1,SKINNY_MESSAGE_MAXSIZE); if (!request) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate memory.\n"); return SWITCH_STATUS_MEMERR; } ptr = mbuf; while (listener_is_ready(listener)) { uint8_t do_sleep = 1; if (listener->expire_time && listener->expire_time < switch_epoch_time_now(NULL)) { switch_safe_free(request); return SWITCH_STATUS_TIMEOUT; } if(bytes < SKINNY_MESSAGE_FIELD_SIZE) { /* We have nothing yet, get length header field */ mlen = SKINNY_MESSAGE_FIELD_SIZE - bytes; } else { /* We now know the message size */ mlen = request->length + 2*SKINNY_MESSAGE_FIELD_SIZE - bytes; } status = switch_socket_recv(listener->sock, ptr, &mlen); if (listener->expire_time && listener->expire_time < switch_epoch_time_now(NULL)) { switch_safe_free(request); return SWITCH_STATUS_TIMEOUT; } if (!listener_is_ready(listener)) { switch_safe_free(request); break; } if (!switch_status_is_timeup(status) && !SWITCH_STATUS_IS_BREAK(status) && (status != SWITCH_STATUS_SUCCESS)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Socket break with status=%d.\n", status); switch_safe_free(request); return SWITCH_STATUS_FALSE; } if(mlen) { bytes += mlen; if(bytes >= SKINNY_MESSAGE_FIELD_SIZE) { do_sleep = 0; ptr += mlen; memcpy(request, mbuf, bytes); #ifdef SKINNY_MEGA_DEBUG switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got request: length=%d,version=%x,type=%x\n", request->length,request->version,request->type); #endif if(request->length < SKINNY_MESSAGE_FIELD_SIZE) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Skinny client sent invalid data. Length should be greater than 4 but got %d.\n", request->length); switch_safe_free(request); return SWITCH_STATUS_FALSE; } if(request->length + 2*SKINNY_MESSAGE_FIELD_SIZE > SKINNY_MESSAGE_MAXSIZE) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Skinny client sent too huge data. Got %d which is above threshold %d.\n", request->length, SKINNY_MESSAGE_MAXSIZE - 2*SKINNY_MESSAGE_FIELD_SIZE); switch_safe_free(request); return SWITCH_STATUS_FALSE; } if(bytes >= request->length + 2*SKINNY_MESSAGE_FIELD_SIZE) { /* Message body */ *req = request; /* Do not free here, caller needs to do it */ return SWITCH_STATUS_SUCCESS; } } } if (listener->digit_timeout_time && listener->digit_timeout_time < switch_mono_micro_time_now()) { switch_safe_free(request); return SWITCH_STATUS_TIMEOUT; } if (do_sleep) { switch_cond_next(); } } switch_safe_free(request); return SWITCH_STATUS_SUCCESS; }