/* * Receive a string of DTMF digits where the length of the digit string is known in advance. Do not give preferential * treatment to any digit value, and allow separate time out values to be specified for the first digit and all subsequent * digits. * * Returns 0 if all digits successfully received. * Returns 1 if a digit time out occurred * Returns -1 if the caller hung up or there was a channel error. * */ static int receive_dtmf_digits(struct ast_channel *chan, char *digit_string, int length, int fdto, int sdto) { int res = 0; int i = 0; int r; struct ast_frame *f; struct timeval lastdigittime; lastdigittime = ast_tvnow(); for (;;) { /* if outa time, leave */ if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > ((i > 0) ? sdto : fdto)) { ast_verb(4, "AlarmReceiver: DTMF Digit Timeout on %s\n", ast_channel_name(chan)); ast_debug(1,"AlarmReceiver: DTMF timeout on chan %s\n",ast_channel_name(chan)); res = 1; break; } if ((r = ast_waitfor(chan, -1)) < 0) { ast_debug(1, "Waitfor returned %d\n", r); continue; } f = ast_read(chan); if (f == NULL) { res = -1; break; } /* If they hung up, leave */ if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP)) { if (f->data.uint32) { ast_channel_hangupcause_set(chan, f->data.uint32); } ast_frfree(f); res = -1; break; } /* if not DTMF, just do it again */ if (f->frametype != AST_FRAME_DTMF) { ast_frfree(f); continue; } digit_string[i++] = f->subclass.integer; /* save digit */ ast_frfree(f); /* If we have all the digits we expect, leave */ if(i >= length) break; lastdigittime = ast_tvnow(); } digit_string[i] = '\0'; /* Nul terminate the end of the digit string */ return res; }
static int measurenoise(struct ast_channel *chan, int ms, char *who) { int res=0; int mssofar; int noise=0; int samples=0; int x; short *foo; struct timeval start; struct ast_frame *f; struct ast_format *rformat; rformat = ao2_bump(ast_channel_readformat(chan)); if (ast_set_read_format(chan, ast_format_slin)) { ast_log(LOG_NOTICE, "Unable to set to linear mode!\n"); ao2_cleanup(rformat); return -1; } start = ast_tvnow(); for(;;) { mssofar = ast_tvdiff_ms(ast_tvnow(), start); if (mssofar > ms) break; res = ast_waitfor(chan, ms - mssofar); if (res < 1) break; f = ast_read(chan); if (!f) { res = -1; break; } if ((f->frametype == AST_FRAME_VOICE) && (ast_format_cmp(f->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)) { foo = (short *)f->data.ptr; for (x=0;x<f->samples;x++) { noise += abs(foo[x]); samples++; } } ast_frfree(f); } if (rformat) { if (ast_set_read_format(chan, rformat)) { ast_log(LOG_NOTICE, "Unable to restore original format!\n"); ao2_ref(rformat, -1); return -1; } ao2_ref(rformat, -1); } if (res < 0) return res; if (!samples) { ast_log(LOG_NOTICE, "No samples were received from the other side!\n"); return -1; } ast_debug(1, "%s: Noise: %d, samples: %d, avg: %d\n", who, noise, samples, noise / samples); return (noise / samples); }
/*! * \brief Receive a fixed length DTMF string. * * \note Doesn't give preferential treatment to any digit, * \note allow different timeout values for the first and all subsequent digits * * \param chan Asterisk Channel * \param digit_string Digits String * \param buf_size The size of the Digits String buffer * \param expected Digits expected for this message type * \param received Pointer to number of digits received so far * * \retval 0 if all digits were successfully received * \retval 1 if a timeout occurred * \retval -1 if the caller hung up or on channel errors */ static int receive_dtmf_digits(struct ast_channel *chan, char *digit_string, int buf_size, int expected, int *received) { int rtn = 0; int r; struct ast_frame *f; struct timeval lastdigittime; lastdigittime = ast_tvnow(); while (*received < expected && *received < buf_size - 1) { /* If timed out, leave */ if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > ((*received > 0) ? sdtimeout : fdtimeout)) { ast_verb(4, "AlarmReceiver: DTMF Digit Timeout on %s\n", ast_channel_name(chan)); ast_debug(1, "AlarmReceiver: DTMF timeout on chan %s\n", ast_channel_name(chan)); rtn = 1; break; } if ((r = ast_waitfor(chan, -1)) < 0) { ast_debug(1, "Waitfor returned %d\n", r); continue; } if ((f = ast_read(chan)) == NULL) { rtn = -1; break; } /* If they hung up, leave */ if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP)) { if (f->data.uint32) { ast_channel_hangupcause_set(chan, f->data.uint32); } ast_frfree(f); rtn = -1; break; } /* If not DTMF, just do it again */ if (f->frametype != AST_FRAME_DTMF) { ast_frfree(f); continue; } /* Save digit */ digit_string[(*received)++] = f->subclass.integer; ast_frfree(f); lastdigittime = ast_tvnow(); } /* Null terminate the end of the digit_string */ digit_string[*received] = '\0'; return rtn; }
/* * This function is run in the context of the serializer. * It runs the task with a simple call and reschedules based on the result. */ static int run_task(void *data) { RAII_VAR(struct ast_sip_sched_task *, schtd, ao2_bump(data), ao2_cleanup); int res; int delay; ao2_lock(schtd); schtd->last_start = ast_tvnow(); schtd->is_running = 1; schtd->run_count++; ao2_unlock(schtd); res = schtd->task(schtd->task_data); ao2_lock(schtd); schtd->is_running = 0; schtd->last_end = ast_tvnow(); /* * Don't restart if the task returned 0 or if the interval * was set to 0 while the task was running */ if (!res || !schtd->interval) { schtd->interval = 0; ao2_unlock(schtd); ao2_unlink(tasks, schtd); return -1; } if (schtd->flags & AST_SIP_SCHED_TASK_VARIABLE) { schtd->interval = res; } if (schtd->flags & AST_SIP_SCHED_TASK_DELAY) { delay = schtd->interval; } else { delay = schtd->interval - (ast_tvdiff_ms(schtd->last_end, schtd->last_start) % schtd->interval); } schtd->current_scheduler_id = ast_sched_add(scheduler_context, delay, push_to_serializer, (const void *)schtd); if (schtd->current_scheduler_id < 0) { schtd->interval = 0; ao2_unlock(schtd); ao2_unlink(tasks, schtd); return -1; } ao2_unlock(schtd); return 0; }
/*! * \brief Set a dial timeout interval hook on the channel. * * The absolute time that the timeout should occur is stored on * a datastore on the channel. This time is converted into a relative * number of milliseconds in the future. Then an interval hook is set * to trigger in that number of milliseconds. * * \pre chan is locked * * \param chan The channel on which to set the interval hook */ static void set_interval_hook(struct ast_channel *chan) { struct ast_datastore *datastore; struct timeval *hangup_time; int64_t ms; struct ast_bridge_channel *bridge_channel; datastore = ast_channel_datastore_find(chan, &timeout_datastore, NULL); if (!datastore) { return; } hangup_time = datastore->data; ms = ast_tvdiff_ms(*hangup_time, ast_tvnow()); bridge_channel = ast_channel_get_bridge_channel(chan); if (!bridge_channel) { return; } if (ast_bridge_interval_hook(bridge_channel->features, 0, ms > 0 ? ms : 1, bridge_timeout, NULL, NULL, 0)) { return; } ast_queue_frame(bridge_channel->chan, &ast_null_frame); }
/*! * \brief Idle function for worker threads * * The worker waits here until it gets told by the threadpool * to wake up. * * worker is locked before entering this function. * * \param worker The idle worker * \retval 0 The thread is being woken up so that it can conclude. * \retval non-zero The thread is being woken up to do more work. */ static int worker_idle(struct worker_thread *worker) { struct timeval start = ast_tvnow(); struct timespec end = { .tv_sec = start.tv_sec + worker->options.idle_timeout, .tv_nsec = start.tv_usec * 1000, }; while (!worker->wake_up) { if (worker->options.idle_timeout <= 0) { ast_cond_wait(&worker->cond, &worker->lock); } else if (ast_cond_timedwait(&worker->cond, &worker->lock, &end) == ETIMEDOUT) { break; } } if (!worker->wake_up) { ast_debug(1, "Worker thread idle timeout reached. Dying.\n"); threadpool_idle_thread_dead(worker->pool, worker); worker->state = DEAD; } worker->wake_up = 0; return worker->state == ALIVE; } /*! * \brief Change a worker's state * * The threadpool calls into this function in order to let a worker know * how it should proceed. * * \retval -1 failure (state transition not permitted) * \retval 0 success */ static int worker_set_state(struct worker_thread *worker, enum worker_state state) { SCOPED_MUTEX(lock, &worker->lock); switch (state) { case ALIVE: /* This can occur due to a race condition between being told to go active * and an idle timeout happening. */ if (worker->state == DEAD) { return -1; } ast_assert(worker->state != ZOMBIE); break; case DEAD: break; case ZOMBIE: ast_assert(worker->state != DEAD); break; } worker->state = state; worker->wake_up = 1; ast_cond_signal(&worker->cond); return 0; }
/*! \brief Observer callback for when a contact is created */ static void contact_expiration_observer_created(const void *object) { const struct ast_sip_contact *contact = object; struct contact_expiration *expiration; int expires = MAX(0, ast_tvdiff_ms(contact->expiration_time, ast_tvnow())); if (ast_tvzero(contact->expiration_time)) { return; } expiration = ao2_alloc_options(sizeof(*expiration), contact_expiration_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!expiration) { return; } expiration->contact = (struct ast_sip_contact*)contact; ao2_ref(expiration->contact, +1); ao2_ref(expiration, +1); if ((expiration->sched = ast_sched_add(sched, expires, contact_expiration_expire, expiration)) < 0) { ao2_ref(expiration, -1); ast_log(LOG_ERROR, "Scheduled expiration for contact '%s' could not be performed, contact may persist past life\n", ast_sorcery_object_get_id(contact)); } else { ao2_link(contact_autoexpire, expiration); } ao2_ref(expiration, -1); }
static int waituntil_exec(struct ast_channel *chan, void *data) { int res; double fraction; struct timeval future = { 0, }; struct timeval tv = ast_tvnow(); int msec; if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "WaitUntil requires an argument(epoch)\n"); pbx_builtin_setvar_helper(chan, "WAITUNTILSTATUS", "FAILURE"); return 0; } if (sscanf(data, "%ld%lf", (long *)&future.tv_sec, &fraction) == 0) { ast_log(LOG_WARNING, "WaitUntil called with non-numeric argument\n"); pbx_builtin_setvar_helper(chan, "WAITUNTILSTATUS", "FAILURE"); return 0; } future.tv_usec = fraction * 1000000; if ((msec = ast_tvdiff_ms(future, tv)) < 0) { ast_log(LOG_NOTICE, "WaitUntil called in the past (now %ld, arg %ld)\n", (long)tv.tv_sec, (long)future.tv_sec); pbx_builtin_setvar_helper(chan, "WAITUNTILSTATUS", "PAST"); return 0; } if ((res = ast_safe_sleep(chan, msec))) pbx_builtin_setvar_helper(chan, "WAITUNTILSTATUS", "HANGUP"); else pbx_builtin_setvar_helper(chan, "WAITUNTILSTATUS", "OK"); return res; }
static struct ast_event *alloc_event(const struct ast_security_event_common *sec) { struct ast_str *str = ast_str_alloca(TIMESTAMP_STR_LEN); struct timeval tv = ast_tvnow(); const char *severity_str; if (check_event_type(sec->event_type)) { return NULL; } encode_timestamp(&str, &tv); severity_str = S_OR( ast_security_event_severity_get_name(sec_events[sec->event_type].severity), "Unknown" ); return ast_event_new(AST_EVENT_SECURITY, AST_EVENT_IE_SECURITY_EVENT, AST_EVENT_IE_PLTYPE_UINT, sec->event_type, AST_EVENT_IE_EVENT_VERSION, AST_EVENT_IE_PLTYPE_UINT, sec->version, AST_EVENT_IE_EVENT_TV, AST_EVENT_IE_PLTYPE_STR, ast_str_buffer(str), AST_EVENT_IE_SERVICE, AST_EVENT_IE_PLTYPE_STR, sec->service, AST_EVENT_IE_SEVERITY, AST_EVENT_IE_PLTYPE_STR, severity_str, AST_EVENT_IE_END); }
/*! \brief add an entry to the video_device table, * ignoring duplicate names. * The table is a static array of 9 elements. * The last_frame field of each entry of the table is initialized to * the current time (we need a value inside this field, on stop of the * GUI the last_frame value is not changed, to avoid checking if it is 0 we * set the initial value on current time) XXX * * PARAMETERS: * \param devices_p = pointer to the table of devices * \param device_num_p = pointer to the number of devices * \param s = name of the new device to insert * * returns 0 on success, 1 on error */ static int device_table_fill(struct video_device *devices, int *device_num_p, const char *s) { int i; struct video_device *p; /* with the current implementation, we support a maximum of 9 devices.*/ if (*device_num_p >= 9) return 0; /* more devices will be ignored */ /* ignore duplicate names */ for (i = 0; i < *device_num_p; i++) { if (!strcmp(devices[i].name, s)) return 0; } /* inserts the new video device */ p = &devices[*device_num_p]; /* XXX the string is allocated but NEVER deallocated, the good time to do that is when the module is unloaded, now we skip the problem */ p->name = ast_strdup(s); /* copy the name */ /* other fields initially NULL */ p->grabber = NULL; p->grabber_data = NULL; p->dev_buf = NULL; p->last_frame = ast_tvnow(); p->status_index = 0; (*device_num_p)++; /* one device added */ return 0; }
static int pthread_timer_set_rate(void *data, unsigned int rate) { struct pthread_timer *timer = data; if (rate > MAX_RATE) { ast_log(LOG_ERROR, "res_timing_pthread only supports timers at a " "max rate of %d / sec\n", MAX_RATE); errno = EINVAL; return -1; } ao2_lock(timer); if ((timer->rate = rate)) { timer->interval = roundf(1000.0 / ((float) rate)); timer->start = ast_tvnow(); timer->state = TIMER_STATE_TICKING; } else { timer->interval = 0; timer->start = ast_tv(0, 0); timer->state = TIMER_STATE_IDLE; } timer->tick_count = 0; ao2_unlock(timer); return 0; }
int ast_sip_sched_task_get_next_run(struct ast_sip_sched_task *schtd) { int delay; struct timeval since_when; struct timeval now; if (!ao2_ref_and_lock(schtd)) { return -1; } if (schtd->interval) { delay = schtd->interval; now = ast_tvnow(); if (schtd->flags & AST_SIP_SCHED_TASK_DELAY) { since_when = schtd->is_running ? now : schtd->last_end; } else { since_when = schtd->last_start.tv_sec ? schtd->last_start : schtd->when_queued; } delay -= ast_tvdiff_ms(now, since_when); delay = delay < 0 ? 0 : delay; } else { delay = -1; } ao2_unlock_and_unref(schtd); return delay; }
/* set defaults */ static int jb_framedata_init(struct jb_framedata *framedata, struct ast_jb_conf *jb_conf) { int jb_impl_type = DEFAULT_TYPE; /* Initialize defaults */ framedata->timer_fd = -1; memcpy(&framedata->jb_conf, jb_conf, sizeof(*jb_conf)); /* Figure out implementation type from the configuration implementation string */ if (!ast_strlen_zero(jb_conf->impl)) { if (!strcasecmp(jb_conf->impl, "fixed")) { jb_impl_type = AST_JB_FIXED; } else if (!strcasecmp(jb_conf->impl, "adaptive")) { jb_impl_type = AST_JB_ADAPTIVE; } else { ast_log(LOG_WARNING, "Unknown Jitterbuffer type %s. Failed to create jitterbuffer.\n", jb_conf->impl); return -1; } } if (!(framedata->jb_impl = ast_jb_get_impl(jb_impl_type))) { return -1; } if (!(framedata->timer = ast_timer_open())) { return -1; } framedata->timer_fd = ast_timer_fd(framedata->timer); framedata->timer_interval = DEFAULT_TIMER_INTERVAL; ast_timer_set_rate(framedata->timer, 1000 / framedata->timer_interval); framedata->start_tv = ast_tvnow(); framedata->jb_obj = framedata->jb_impl->create(&framedata->jb_conf); return 0; }
/*! * \internal * \brief Initialize the start time on a contact status so the round * trip time can be calculated upon a valid response. */ static void init_start_time(const struct ast_sip_contact *contact) { struct ast_sip_contact_status *status; struct ast_sip_contact_status *update; status = ast_res_pjsip_find_or_create_contact_status(contact); if (!status) { ast_log(LOG_ERROR, "Unable to find ast_sip_contact_status for contact %s\n", contact->uri); return; } update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(status)); if (!update) { ast_log(LOG_ERROR, "Unable to copy ast_sip_contact_status for contact %s\n", contact->uri); return; } update->status = status->status; update->last_status = status->last_status; update->rtt = status->rtt; update->rtt_start = ast_tvnow(); if (ast_sorcery_update(ast_sip_get_sorcery(), update)) { ast_log(LOG_ERROR, "Unable to update ast_sip_contact_status for contact %s\n", contact->uri); } ao2_ref(status, -1); ao2_ref(update, -1); }
void ast_sched_dump(const struct sched_context *con) { /* * Dump the contents of the scheduler to * stderr */ struct sched *q; struct timeval tv = ast_tvnow(); #ifdef SCHED_MAX_CACHE ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total, %d Cache)\n", con->schedcnt, con->eventcnt - 1, con->schedccnt); #else ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total)\n", con->schedcnt, con->eventcnt - 1); #endif ast_log(LOG_DEBUG, "=============================================================\n"); ast_log(LOG_DEBUG, "|ID Callback Data Time (sec:ms) |\n"); ast_log(LOG_DEBUG, "+-----+-----------------+-----------------+-----------------+\n"); for (q = con->schedq; q; q = q->next) { struct timeval delta = ast_tvsub(q->when, tv); ast_log(LOG_DEBUG, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n", q->id, q->callback, q->data, delta.tv_sec, (long int)delta.tv_usec); } ast_log(LOG_DEBUG, "=============================================================\n"); }
int ast_sched_runq(struct sched_context *con) { /* * Launch all events which need to be run at this time. */ struct sched *current; struct timeval tv; int x=0; int res; DEBUG(ast_log(LOG_DEBUG, "ast_sched_runq()\n")); ast_mutex_lock(&con->lock); tv = ast_tvadd(ast_tvnow(), ast_tv(0, 1000)); for(;;) { if (!con->schedq) break; /* schedule all events which are going to expire within 1ms. * We only care about millisecond accuracy anyway, so this will * help us get more than one event at one time if they are very * close together. */ if (SOONER(con->schedq->when, tv)) { current = con->schedq; con->schedq = con->schedq->next; con->schedcnt--; /* * At this point, the schedule queue is still intact. We * have removed the first event and the rest is still there, * so it's permissible for the callback to add new events, but * trying to delete itself won't work because it isn't in * the schedule queue. If that's what it wants to do, it * should return 0. */ ast_mutex_unlock(&con->lock); res = current->callback(current->data); ast_mutex_lock(&con->lock); if (res) { /* * If they return non-zero, we should schedule them to be * run again. */ if (sched_settime(¤t->when, current->variable? res : current->resched)) { sched_release(con, current); } else schedule(con, current); } else { /* No longer needed, so release it */ sched_release(con, current); } x++; } else break; } ast_mutex_unlock(&con->lock); return x; }
/*! * \internal * \brief Initialize the start time on a contact status so the round * trip time can be calculated upon a valid response. */ static void init_start_time(const struct ast_sip_contact *contact) { RAII_VAR(struct ast_sip_contact_status *, status, NULL, ao2_cleanup); RAII_VAR(struct ast_sip_contact_status *, update, NULL, ao2_cleanup); status = ast_res_pjsip_find_or_create_contact_status(contact); if (!status) { ast_log(LOG_ERROR, "Unable to find ast_sip_contact_status for contact %s\n", contact->uri); return; } update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(status)); if (!update) { ast_log(LOG_ERROR, "Unable to copy ast_sip_contact_status for contact %s\n", contact->uri); return; } ast_string_field_set(status, uri, contact->uri); update->status = status->status; update->last_status = status->last_status; update->rtt = status->rtt; update->rtt_start = ast_tvnow(); if (ast_sorcery_update(ast_sip_get_sorcery(), update)) { ast_log(LOG_ERROR, "Unable to update ast_sip_contact_status for contact %s\n", contact->uri); } }
/*! * \brief Get the next SMDI message from the queue. * \param iface a pointer to the interface to use. * * This function pulls the first unexpired message from the SMDI message queue * on the specified interface. It will purge all expired SMDI messages before * returning. * * \return the next SMDI message, or NULL if there were no pending messages. */ extern struct ast_smdi_mwi_message *ast_smdi_mwi_message_pop(struct ast_smdi_interface *iface) { struct ast_smdi_mwi_message *mwi_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q); struct timeval now; long elapsed = 0; /* purge old messages */ now = ast_tvnow(); while (mwi_msg) { elapsed = ast_tvdiff_ms(now, mwi_msg->timestamp); if (elapsed > iface->msg_expiry) { /* found an expired message */ ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); ast_log(LOG_NOTICE, "Purged expired message from %s SMDI MWI message queue. Message was %ld milliseconds too old.", iface->name, elapsed - iface->msg_expiry); mwi_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q); } else { /* good message, return it */ break; } } return mwi_msg; }
struct stasis_message *stasis_message_create_full(struct stasis_message_type *type, void *data, const struct ast_eid *eid) { struct stasis_message *message; if (type == NULL || data == NULL) { return NULL; } message = ao2_alloc(sizeof(*message), stasis_message_dtor); if (message == NULL) { return NULL; } message->timestamp = ast_tvnow(); ao2_ref(type, +1); message->type = type; ao2_ref(data, +1); message->data = data; if (eid) { message->eid_ptr = &message->eid; message->eid = *eid; } return message; }
static void evt_gen_failed_acl(void) { struct sockaddr_in sin_local = { .sin_family = AF_INET }; struct sockaddr_in sin_remote = { .sin_family = AF_INET }; struct timeval session_tv = ast_tvnow(); struct ast_security_event_failed_acl failed_acl_event = { .common.event_type = AST_SECURITY_EVENT_FAILED_ACL, .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION, .common.service = "TEST", .common.module = AST_MODULE, .common.account_id = "Username", .common.session_id = "Session123", .common.session_tv = &session_tv, .common.local_addr = { .sin = &sin_local, .transport = AST_SECURITY_EVENT_TRANSPORT_UDP, }, .common.remote_addr = { .sin = &sin_remote, .transport = AST_SECURITY_EVENT_TRANSPORT_UDP, }, .acl_name = "TEST_ACL",
static void *do_timing(void *arg) { struct timeval next_wakeup = ast_tvnow(); while (!timing_thread.stop) { struct timespec ts = { 0, }; ao2_callback(pthread_timers, OBJ_NODATA, run_timer, NULL); next_wakeup = ast_tvadd(next_wakeup, ast_tv(0, 5000)); ts.tv_sec = next_wakeup.tv_sec; ts.tv_nsec = next_wakeup.tv_usec * 1000; ast_mutex_lock(&timing_thread.lock); if (!timing_thread.stop) { if (ao2_container_count(pthread_timers)) { ast_cond_timedwait(&timing_thread.cond, &timing_thread.lock, &ts); } else { ast_cond_wait(&timing_thread.cond, &timing_thread.lock); } } ast_mutex_unlock(&timing_thread.lock); } return NULL; }
static void calc_cost(struct ast_translator *t, int samples) { int sofar=0; struct ast_translator_pvt *pvt; struct ast_frame *f, *out; struct timeval start; int cost; if(!samples) samples = 1; /* If they don't make samples, give them a terrible score */ if (!t->sample) { ast_log(LOG_WARNING, "Translator '%s' does not produce sample frames.\n", t->name); t->cost = 99999; return; } pvt = t->newpvt(); if (!pvt) { ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name); t->cost = 99999; return; } start = ast_tvnow(); /* Call the encoder until we've processed one second of time */ while(sofar < samples * 8000) { f = t->sample(); if (!f) { ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name); t->destroy(pvt); t->cost = 99999; return; } t->framein(pvt, f); ast_frfree(f); while((out = t->frameout(pvt))) { sofar += out->samples; ast_frfree(out); } } cost = ast_tvdiff_ms(ast_tvnow(), start); t->destroy(pvt); t->cost = cost / samples; if (!t->cost) t->cost = 1; }
static int task_1(void *data) { struct test_data *test = data; test->done = 0; test->task_start = ast_tvnow(); test->tid = pthread_self(); test->is_servant = ast_sip_thread_is_servant(); usleep(M2U(test->sleep)); test->task_end = ast_tvnow(); ast_mutex_lock(&test->lock); test->done = 1; ast_mutex_unlock(&test->lock); ast_cond_signal(&test->cond); return test->interval; }
/*! * \brief Get the next SMDI message from the queue. * \param iface a pointer to the interface to use. * \param timeout the time to wait before returning in milliseconds. * * This function pulls a message from the SMDI message queue on the specified * interface. If no message is available this function will wait the specified * amount of time before returning. * * \return the next SMDI message, or NULL if there were no pending messages and * the timeout has expired. */ extern struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait(struct ast_smdi_interface *iface, int timeout) { struct timeval start; long diff = 0; struct ast_smdi_mwi_message *msg; start = ast_tvnow(); while (diff < timeout) { if ((msg = ast_smdi_mwi_message_pop(iface))) return msg; /* check timeout */ diff = ast_tvdiff_ms(ast_tvnow(), start); } return (ast_smdi_mwi_message_pop(iface)); }
static int bridge_builtin_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags) { RAII_VAR(struct ast_bridge_features_limits *, feature_limits, NULL, ao2_cleanup); if (!limits->duration) { return -1; } /* Create limits hook_pvt data. */ ast_module_ref(ast_module_info->self); feature_limits = ao2_alloc_options(sizeof(*feature_limits), bridge_features_limits_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!feature_limits) { ast_module_unref(ast_module_info->self); return -1; } if (ast_bridge_features_limits_construct(feature_limits)) { return -1; } bridge_features_limits_copy(feature_limits, limits); feature_limits->quitting_time = ast_tvadd(ast_tvnow(), ast_samp2tv(feature_limits->duration, 1000)); /* Install limit hooks. */ ao2_ref(feature_limits, +1); if (ast_bridge_interval_hook(features, AST_BRIDGE_HOOK_TIMER_OPTION_MEDIA, feature_limits->duration, bridge_features_duration_callback, feature_limits, __ao2_cleanup, remove_flags)) { ast_log(LOG_ERROR, "Failed to schedule the duration limiter to the bridge channel.\n"); ao2_ref(feature_limits, -1); return -1; } if (!ast_strlen_zero(feature_limits->connect_sound)) { ao2_ref(feature_limits, +1); if (ast_bridge_interval_hook(features, AST_BRIDGE_HOOK_TIMER_OPTION_MEDIA, 1, bridge_features_connect_callback, feature_limits, __ao2_cleanup, remove_flags)) { ast_log(LOG_WARNING, "Failed to schedule connect sound to the bridge channel.\n"); ao2_ref(feature_limits, -1); } } if (feature_limits->warning && feature_limits->warning < feature_limits->duration) { ao2_ref(feature_limits, +1); if (ast_bridge_interval_hook(features, AST_BRIDGE_HOOK_TIMER_OPTION_MEDIA, feature_limits->duration - feature_limits->warning, bridge_features_warning_callback, feature_limits, __ao2_cleanup, remove_flags)) { ast_log(LOG_WARNING, "Failed to schedule warning sound playback to the bridge channel.\n"); ao2_ref(feature_limits, -1); } } return 0; }
static int is_timed_out(struct hash_test const *data) { struct timeval now = ast_tvnow(); int val = ast_tvdiff_us(data->deadline, now) < 0; if (val) { /* tv_usec is suseconds_t, which could be int or long */ ast_test_status_update(data->test, "Now: %ld.%06ld Deadline: %ld.%06ld\n", now.tv_sec, (long)now.tv_usec, data->deadline.tv_sec, (long)data->deadline.tv_usec); } return val; }
/* * Write the metadata to the log file */ static int write_metadata( FILE *logfile, char *signalling_type, struct ast_channel *chan) { int res = 0; struct timeval t; struct ast_tm now; char *cl; char *cn; char workstring[80]; char timestamp[80]; /* Extract the caller ID location */ ast_copy_string(workstring, S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""), sizeof(workstring)); ast_shrink_phone_number(workstring); if (ast_strlen_zero(workstring)) { cl = "<unknown>"; } else { cl = workstring; } cn = S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "<unknown>"); /* Get the current time */ t = ast_tvnow(); ast_localtime(&t, &now, NULL); /* Format the time */ ast_strftime(timestamp, sizeof(timestamp), time_stamp_format, &now); res = fprintf(logfile, "\n\n[metadata]\n\n"); if (res >= 0) { res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type); } if (res >= 0) { res = fprintf(logfile, "CALLINGFROM=%s\n", cl); } if (res >= 0) { res = fprintf(logfile, "CALLERNAME=%s\n", cn); } if (res >= 0) { res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp); } if (res >= 0) { res = fprintf(logfile, "[events]\n\n"); } if (res < 0) { ast_verb(3, "AlarmReceiver: can't write metadata\n"); ast_debug(1,"AlarmReceiver: can't write metadata\n"); } else { res = 0; } return res; }
static int expire_requests(void *object, void *arg, int flags) { struct unidentified_request *unid = object; int *maxage = arg; int64_t ms = ast_tvdiff_ms(ast_tvnow(), unid->first_seen); if (ms > (*maxage) * 2 * 1000) { return CMP_MATCH; } return 0; }
/*! \brief Internal callback function which deletes and unlinks any expired contacts */ static int contact_expire(void *obj, void *arg, int flags) { struct ast_sip_contact *contact = obj; /* If the contact has not yet expired it is valid */ if (ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) > 0) { return 0; } ast_sip_location_delete_contact(contact); return CMP_MATCH; }
/*! \brief Callback function which deletes a contact if it has expired or sets up auto-expiry */ static int contact_expiration_setup(void *obj, void *arg, int flags) { struct ast_sip_contact *contact = obj; int expires = MAX(0, ast_tvdiff_ms(contact->expiration_time, ast_tvnow())); if (!expires) { ast_sorcery_delete(ast_sip_get_sorcery(), contact); } else { contact_expiration_observer_created(contact); } return 0; }