static modem_t *acquire_modem(int index) { modem_t *modem = NULL; switch_time_t now = switch_time_now(); int64_t idle_debounce = 2000000; switch_mutex_lock(globals.mutex); if (index > -1 && index < globals.SOFT_MAX_MODEMS) { modem = &globals.MODEM_POOL[index]; } else { int x; for(x = 0; x < globals.SOFT_MAX_MODEMS; x++) { if (globals.MODEM_POOL[x].state == MODEM_STATE_ONHOOK && (now - globals.MODEM_POOL[x].last_event) > idle_debounce) { modem = &globals.MODEM_POOL[x]; break; } } } if (modem && (modem->state != MODEM_STATE_ONHOOK || (now - modem->last_event) < idle_debounce)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Modem %s In Use!\n", modem->devlink); modem = NULL; } if (modem) { modem_set_state(modem, MODEM_STATE_ACQUIRED); modem->last_event = switch_time_now(); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Modems Available!\n"); } switch_mutex_unlock(globals.mutex); return modem; }
static switch_time_t time_now(int64_t offset) { switch_time_t now; #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) if (MONO) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset; } else { #endif now = switch_time_now(); #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) } #endif return now; }
static switch_time_t time_now(int64_t offset) { switch_time_t now; #if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32) if (MONO) { #ifndef WIN32 struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset; #else DWORD tick_now; DWORD tick_diff; tick_now = timeGetTime(); if (win32_tick_time_since_start != -1) { EnterCriticalSection(&timer_section); /* just add diff (to make it work more than 50 days). */ tick_diff = tick_now - win32_last_get_time_tick; win32_tick_time_since_start += tick_diff; win32_last_get_time_tick = tick_now; now = (win32_tick_time_since_start * 1000) + offset; LeaveCriticalSection(&timer_section); } else { /* If someone is calling us before timer is initialized, * return the current tick + offset */ now = (tick_now * 1000) + offset; } #endif } else { #endif now = switch_time_now(); #if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32) } #endif return now; }
/** * Get a URL from the cache, add it if it does not exist * @param cache The cache * @param session the (optional) session requesting the URL * @param url The URL * @param download If true, the file will be downloaded if it does not exist in the cache. * @param pool The pool to use for allocating the filename * @return The filename or NULL if there is an error */ static char *url_cache_get(url_cache_t *cache, switch_core_session_t *session, const char *url, int download, switch_memory_pool_t *pool) { char *filename = NULL; cached_url_t *u = NULL; if (zstr(url)) { return NULL; } url_cache_lock(cache, session); u = switch_core_hash_find(cache->map, url); if (u && u->status == CACHED_URL_AVAILABLE) { if (switch_time_now() >= (u->download_time + u->max_age)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Cached URL has expired.\n"); url_cache_remove_soft(cache, session, u); /* will get permanently deleted upon replacement */ u = NULL; } else if (switch_file_exists(u->filename, pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Cached URL file is missing.\n"); url_cache_remove_soft(cache, session, u); /* will get permanently deleted upon replacement */ u = NULL; } } if (!u && download) { /* URL is not cached, let's add it.*/ /* Set up URL entry and add to map to prevent simultaneous downloads */ cache->misses++; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Cache MISS: size = %zu (%zu MB), hit ratio = %d/%d\n", cache->queue.size, cache->size / 1000000, cache->hits, cache->hits + cache->misses); u = cached_url_create(cache, url); if (url_cache_add(cache, session, u) != SWITCH_STATUS_SUCCESS) { /* This error should never happen */ url_cache_unlock(cache, session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed to add URL to cache!\n"); cached_url_destroy(u, cache->pool); return NULL; } /* download the file */ url_cache_unlock(cache, session); if (http_get(cache, u, session) == SWITCH_STATUS_SUCCESS) { /* Got the file, let the waiters know it is available */ url_cache_lock(cache, session); u->status = CACHED_URL_AVAILABLE; filename = switch_core_strdup(pool, u->filename); cache->size += u->size; } else { /* Did not get the file, flag for replacement */ url_cache_lock(cache, session); url_cache_remove_soft(cache, session, u); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Failed to download URL %s\n", url); cache->errors++; } } else if (!u) { filename = DOWNLOAD_NEEDED; } else { /* Wait until file is downloaded */ if (u->status == CACHED_URL_RX_IN_PROGRESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Waiting for URL %s to be available\n", url); u->waiters++; url_cache_unlock(cache, session); while(u->status == CACHED_URL_RX_IN_PROGRESS) { switch_sleep(10 * 1000); /* 10 ms */ } url_cache_lock(cache, session); u->waiters--; } /* grab filename if everything is OK */ if (u->status == CACHED_URL_AVAILABLE) { filename = switch_core_strdup(pool, u->filename); cache->hits++; u->used = 1; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Cache HIT: size = %zu (%zu MB), hit ratio = %d/%d\n", cache->queue.size, cache->size / 1000000, cache->hits, cache->hits + cache->misses); } } url_cache_unlock(cache, session); return filename; }
SWITCH_DECLARE(void) switch_time_sync(void) { runtime.reference = switch_time_now(); runtime.offset = runtime.reference - time_now(0); runtime.reference = time_now(runtime.offset); }
SWITCH_DECLARE(switch_time_t) switch_micro_time_now(void) { return (globals.RUNNING == 1 && runtime.timestamp) ? runtime.timestamp : switch_time_now(); }
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pgsql_result_t **result_out, int msec) { #ifdef SWITCH_HAVE_PGSQL switch_pgsql_result_t *res; switch_time_t start; switch_time_t ctime; unsigned int usec = msec * 1000; char *err_str; struct pollfd fds[2] = { {0} }; int poll_res = 0; if(!handle) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "**BUG** Null handle passed to switch_pgsql_next_result.\n"); return SWITCH_PGSQL_FAIL; } /* Try to consume input that might be waiting right away */ if (PQconsumeInput(handle->con)) { /* And check to see if we have a full result ready for reading */ if (PQisBusy(handle->con)) { /* Wait for a result to become available, up to msec milliseconds */ start = switch_time_now(); while((ctime = switch_micro_time_now()) - start <= usec) { int wait_time = (usec - (ctime - start)) / 1000; fds[0].fd = handle->sock; fds[0].events |= POLLIN; fds[0].events |= POLLERR; /* Wait for the PostgreSQL socket to be ready for data reads. */ if ((poll_res = poll(&fds[0], 1, wait_time)) > -1 ) { if (fds[0].revents & POLLIN) { /* Then try to consume any input waiting. */ if (PQconsumeInput(handle->con)) { /* And check to see if we have a full result ready for reading */ if (!PQisBusy(handle->con)) { /* If we can pull a full result without blocking, then break this loop */ break; } } else { /* If we had an error trying to consume input, report it and cancel the query. */ err_str = switch_pgsql_handle_get_error(handle); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); switch_safe_free(err_str); switch_pgsql_cancel(handle); goto error; } } else if (fds[0].revents & POLLERR) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql); goto error; } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql); goto error; } } /* If we broke the loop above because of a timeout, report that and cancel the query. */ if (ctime - start > usec) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql); switch_pgsql_cancel(handle); goto error; } } } else { /* If we had an error trying to consume input, report it and cancel the query. */ err_str = switch_pgsql_handle_get_error(handle); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); switch_safe_free(err_str); switch_pgsql_cancel(handle); goto error; } /* At this point, we know we can read a full result without blocking. */ if(!(res = malloc(sizeof(switch_pgsql_result_t)))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Malloc failed!\n"); goto error; } memset(res, 0, sizeof(switch_pgsql_result_t)); res->result = PQgetResult(handle->con); if (res->result) { *result_out = res; res->status = PQresultStatus(res->result); switch(res->status) { case PGRES_TUPLES_OK: { res->rows = PQntuples(res->result); handle->affected_rows = res->rows; res->cols = PQnfields(res->result); } break; case PGRES_COPY_OUT: case PGRES_COPY_IN: case PGRES_COMMAND_OK: break; case PGRES_EMPTY_QUERY: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_EMPTY_QUERY\n", handle->sql); case PGRES_BAD_RESPONSE: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_BAD_RESPONSE\n", handle->sql); case PGRES_NONFATAL_ERROR: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_NONFATAL_ERROR\n", handle->sql); case PGRES_FATAL_ERROR: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_FATAL_ERROR\n", handle->sql); res->err = PQresultErrorMessage(res->result); goto error; break; } } else { free(res); res = NULL; *result_out = NULL; goto error; } return SWITCH_PGSQL_SUCCESS; error: #endif return SWITCH_PGSQL_FAIL; }
static void *SWITCH_THREAD_FUNC modem_thread(switch_thread_t *thread, void *obj) { modem_t *modem = obj; int r, avail; #ifdef WIN32 DWORD readBytes; OVERLAPPED o; #endif char buf[T31_TX_BUF_LEN], tmp[80]; switch_mutex_lock(globals.mutex); modem_init(modem, control_handler); globals.THREADCOUNT++; switch_mutex_unlock(globals.mutex); if (switch_test_flag(modem, MODEM_FLAG_RUNNING)) { switch_mutex_lock(modem->cond_mutex); while (switch_test_flag(modem, MODEM_FLAG_RUNNING)) { #ifndef WIN32 r = modem_wait_sock(modem->master, -1, MODEM_POLL_READ | MODEM_POLL_ERROR); #else r = modem_wait_sock(modem, -1, MODEM_POLL_READ | MODEM_POLL_ERROR); #endif if (!switch_test_flag(modem, MODEM_FLAG_RUNNING)) { break; } if (r < 0 || !(r & MODEM_POLL_READ) || (r & MODEM_POLL_ERROR)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Read on master [%s] [%d]\n", modem->devlink, r); break; } modem->last_event = switch_time_now(); if (switch_test_flag(modem, MODEM_FLAG_XOFF)) { switch_thread_cond_wait(modem->cond, modem->cond_mutex); modem->last_event = switch_time_now(); } avail = sizeof(buf) - modem->t31_state->tx.in_bytes + modem->t31_state->tx.out_bytes - 1; if (avail == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Buffer Full, retrying....\n"); switch_yield(10000); continue; } #ifndef WIN32 r = read(modem->master, buf, avail); #else o.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* Initialize the rest of the OVERLAPPED structure to zero. */ o.Internal = 0; o.InternalHigh = 0; o.Offset = 0; o.OffsetHigh = 0; assert(o.hEvent); if (!ReadFile(modem->master, buf, avail, &readBytes, &o)) { GetOverlappedResult(modem->master,&o,&readBytes,TRUE); } CloseHandle (o.hEvent); r = readBytes; #endif t31_at_rx(modem->t31_state, buf, r); memset(tmp, 0, sizeof(tmp)); if (!strncasecmp(buf, "AT", 2)) { int x; strncpy(tmp, buf, r); for(x = 0; x < r; x++) { if(tmp[x] == '\r' || tmp[x] == '\n') { tmp[x] = '\0'; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Command on %s [%s]\n", modem->devlink, tmp); } } switch_mutex_unlock(modem->cond_mutex); if (switch_test_flag(modem, MODEM_FLAG_RUNNING)) { modem_close(modem); } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Thread ended for %s\n", modem->devlink); switch_mutex_lock(globals.mutex); globals.THREADCOUNT--; switch_mutex_unlock(globals.mutex); return NULL; }
switch_status_t mod_xml_radius_add_params(switch_core_session_t *session, switch_event_t *params, rc_handle *handle, VALUE_PAIR **send, switch_xml_t fields) { switch_xml_t param; void *av_value = NULL; if ( (param = switch_xml_child(fields, "param")) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a param under the fields section\n"); goto err; } for (; param; param = param->next) { DICT_ATTR *attribute = NULL; DICT_VENDOR *vendor = NULL; int attr_num = 0, vend_num = 0; char *var = (char *) switch_xml_attr(param, "name"); char *vend = (char *) switch_xml_attr(param, "vendor"); char *variable = (char *) switch_xml_attr(param, "variable"); char *variable_secondary = (char *) switch_xml_attr(param, "variable_secondary"); char *val_default = (char *) switch_xml_attr(param, "default"); char *format = (char *) switch_xml_attr(param, "format"); char *other_leg = (char *) switch_xml_attr(param, "other_leg"); attribute = rc_dict_findattr(handle, var); if ( attribute == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Could not locate attribute '%s' in the configured dictionary\n", var); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: dict attr '%s' value '%d' type '%d'\n", attribute->name, attribute->value, attribute->type); } attr_num = attribute->value; if ( vend ) { vendor = rc_dict_findvend(handle, vend); if ( vendor == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Could not locate vendor '%s' in the configured dictionary %p\n", vend, vend); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: dict vend name '%s' vendorpec '%d'\n", vendor->vendorname, vendor->vendorpec); } vend_num = vendor->vendorpec; } if ( var ) { if ( session ) { switch_channel_t *channel = switch_core_session_get_channel(session); /* Accounting only */ if ( strncmp( var, "h323-setup-time", 15) == 0 ) { switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); switch_time_t time = profile->times->created; switch_time_exp_t tm; if ( !time ) { goto end_loop; } switch_time_exp_lt(&tm, time); if ( GLOBAL_TIME_FORMAT == 1 ) { av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900); } else { av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); } if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); } } else if ( strncmp( var, "h323-connect-time", 17) == 0 ) { switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); switch_time_t time = profile->times->answered; switch_time_exp_t tm; if ( !time ) { goto end_loop; } switch_time_exp_lt(&tm, time); if ( GLOBAL_TIME_FORMAT == 1 ) { av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900); } else { av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); } if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); } } else if ( strncmp( var, "h323-disconnect-time", 20) == 0 ) { switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); switch_time_t time = profile->times->hungup; switch_time_exp_t tm; if ( !time ) { if ( variable_secondary != NULL && strncmp(variable_secondary, "now", 3) == 0 ) { time = switch_time_now(); } else { goto end_loop; } } switch_time_exp_lt(&tm, time); if ( GLOBAL_TIME_FORMAT == 1 ) { av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, GLOBAL_TIME_FORMAT, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900); } else { av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); } if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto err; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); } } else if ( strncmp( var, "h323-disconnect-cause", 21) == 0 ) { switch_call_cause_t cause = switch_channel_get_cause(channel); av_value = switch_mprintf("h323-disconnect-cause=%x", cause); if (rc_avpair_add(handle, send, 30, av_value, -1, 9) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add disconnect cause \n"); goto err; } } else { if ( format == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing format attribute for %s variable\n", variable); goto err; } if ( attribute->type == 0 ) { const char *val = NULL; if ( other_leg ) { val = switch_channel_get_variable_partner(channel, variable); if ( val == NULL && variable_secondary != NULL) { val = switch_channel_get_variable_partner(channel, variable_secondary); } } else { val = switch_channel_get_variable(channel, variable); if ( val == NULL && variable_secondary != NULL) { val = switch_channel_get_variable(channel, variable_secondary); } } if ( val == NULL && val_default != NULL) { av_value = switch_mprintf(format, val_default); } else { av_value = switch_mprintf(format, val); } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value); } if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option with val '%s' to handle\n", (char *) av_value); goto err; } } else if ( attribute->type == 1 ) { int number = atoi(switch_channel_get_variable(channel, variable)); if (rc_avpair_add(handle, send, attr_num, &number, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option with value '%d' to handle\n", number); goto err; } } } } else if ( params ) { /* Auth only */ char *tmp = switch_event_get_header(params, variable); if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: param var '%s' val: %s\n", variable, tmp); } if ( tmp == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Unable to locate '%s' on the event\n", variable); goto err; } av_value = switch_mprintf(format, tmp); if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto err; } } else { goto err; } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: all params must have a name attribute\n"); goto err; } end_loop: if ( av_value != NULL ) { free(av_value); av_value = NULL; } } return SWITCH_STATUS_SUCCESS; err: if ( av_value != NULL ) { free(av_value); av_value = NULL; } return SWITCH_STATUS_GENERR; }
static switch_status_t switch_vpx_encode(switch_codec_t *codec, switch_frame_t *frame) { vpx_context_t *context = (vpx_context_t *)codec->private_info; int width = 0; int height = 0; uint32_t dur; int64_t pts; vpx_enc_frame_flags_t vpx_flags = 0; switch_time_t now; int err; if (frame->flags & SFF_SAME_IMAGE) { return consume_partition(context, frame); } if (context->need_encoder_reset != 0) { reset_codec_encoder(codec); context->need_encoder_reset = 0; } if (frame->img->d_h > 1) { width = frame->img->d_w; height = frame->img->d_h; } else { width = frame->img->w; height = frame->img->h; } if (context->config.g_w != width || context->config.g_h != height) { context->codec_settings.video.width = width; context->codec_settings.video.height = height; reset_codec_encoder(codec); frame->flags |= SFF_PICTURE_RESET; context->need_key_frame = 1; } if (!context->encoder_init) { init_encoder(codec); } if (context->change_bandwidth) { context->codec_settings.video.bandwidth = context->change_bandwidth; context->change_bandwidth = 0; init_encoder(codec); } now = switch_time_now(); if (context->need_key_frame != 0) { // force generate a key frame if (!context->last_key_frame || (now - context->last_key_frame) > KEY_FRAME_MIN_FREQ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "VPX KEYFRAME GENERATED\n"); vpx_flags |= VPX_EFLAG_FORCE_KF; context->need_key_frame = 0; context->last_key_frame = now; } } context->framecount++; pts = (now - context->start_time) / 1000; dur = context->last_ms ? (now - context->last_ms) / 1000 : pts; if ((err = vpx_codec_encode(&context->encoder, (vpx_image_t *) frame->img, pts, dur, vpx_flags, VPX_DL_REALTIME)) != VPX_CODEC_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "VPX encode error %d:%s:%s\n", err, vpx_codec_error(&context->encoder), vpx_codec_error_detail(&context->encoder)); frame->datalen = 0; return SWITCH_STATUS_FALSE; } context->enc_iter = NULL; context->last_ts = frame->timestamp; context->last_ms = now; return consume_partition(context, frame); }