static void in_received_handler(DictionaryIterator *received, void *context) { phone_contact = true; update_in_progress = false; staleness_update(received); int msg_type = dict_find(received, APP_KEY_MSG_TYPE)->value->uint8; if (msg_type == MSG_TYPE_DATA) { uint32_t recency = dict_find(received, APP_KEY_RECENCY)->value->uint32; int32_t next_update = SGV_UPDATE_FREQUENCY - recency * 1000; int32_t delay = next_update < LATE_DATA_UPDATE_FREQUENCY ? LATE_DATA_UPDATE_FREQUENCY : next_update; schedule_update((uint32_t) delay); } if (msg_type == MSG_TYPE_ERROR) { schedule_update(ERROR_RETRY_DELAY); } else { data_callback(received); } }
void start_twi_slave(uint8_t slave_address_in, uint8_t use_sleep, void (*data_callback_in)(uint8_t input_buffer_length, const uint8_t *input_buffer, uint8_t *output_buffer_length, uint8_t *output_buffer), void (*idle_callback_in)(void)) { uint8_t call_datacallback = 0; slave_address = slave_address_in; data_callback = data_callback_in; idle_callback = idle_callback_in; input_buffer_length = 0; output_buffer_length = 0; output_buffer_current = 0; ss_state = ss_state_idle; init_twi_slave(slave_address_in); for (;;) { if(idle_callback) { idle_callback(); } if (ss_state == ss_state_new_data) { call_datacallback = 1; } if(call_datacallback) { output_buffer_length = 0; output_buffer_current = 0; data_callback(input_buffer_length, input_buffer, &output_buffer_length, output_buffer); input_buffer_length = 0; call_datacallback = 0; ss_state = ss_state_idle; } } }
void dvb_read (dvb_t *settings, bool(*data_callback)(int, unsigned char*)) { #ifdef NO_DVB_POLL int i; for (i = 0; i < settings->pids_count; i++) { int cycles, total_size, fd; struct dmx_sct_filter_params params; dmx_source_t ssource; char first[settings->buffer_size]; int first_length; bool first_ok; ssource = DMX_SOURCE_FRONT0 + settings->frontend; memset(¶ms, 0, sizeof(params)); params.pid = settings->pids[i]; params.filter.filter[0] = settings->filter; params.filter.mask[0] = settings->mask; params.timeout = 5000; params.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC; if ((fd = open(settings->demuxer, O_RDWR | O_NONBLOCK)) < 0) { log_add ("Cannot open demuxer '%s'", settings->demuxer); continue; } if (ioctl(fd, DMX_SET_SOURCE, &ssource) == -1) { log_add ("ioctl DMX_SET_SOURCE failed"); close(fd); continue; } if (ioctl(fd, DMX_SET_FILTER, ¶ms) == -1) { log_add ("ioctl DMX_SET_FILTER failed"); close(fd); continue; } log_add ("Reading pid 0x%x...", params.pid); first_length = 0; first_ok = false; total_size = 0; cycles = 0; while (cycles < MAX_OTV_LOOP_CYCLES) { int k; bool force_quit = false; unsigned char buf[settings->buffer_size]; // 4K buffer size int size = read (fd, buf, sizeof(buf)); if (size == -1) { usleep (10 * 1000); continue; } if (size < settings->min_length) continue; if (first_length == 0) { first_length = size; memcpy (first, buf, size); } else if (first_length == size) { if (memcmp (buf, first, size) == 0) { first_ok = true; } } total_size += size; //data_callback (size, buf); if (!data_callback (size, buf)) { log_add ("Forced to quit"); break; } if (first_ok) { log_add ("Done"); break; } cycles++; } close(fd); } #else struct pollfd PFD[256]; int cycles, i, total_size; struct dmx_sct_filter_params params; dmx_source_t ssource; char first[settings->pids_count][settings->buffer_size]; int first_length[settings->pids_count]; bool first_ok[settings->pids_count]; ssource = DMX_SOURCE_FRONT0 + settings->frontend; for (i = 0; i < settings->pids_count; i++) { PFD[i].fd = open (settings->demuxer, O_RDWR|O_NONBLOCK); PFD[i].events = POLLIN; PFD[i].revents = 0; memset (¶ms, 0, sizeof (params)); params.pid = settings->pids[i]; params.timeout = 5000; params.flags = DMX_CHECK_CRC|DMX_IMMEDIATE_START; params.filter.filter[0] = settings->filter; params.filter.mask[0] = settings->mask; if (ioctl(PFD[i].fd, DMX_SET_SOURCE, &ssource) < 0) { log_add ("ioctl DMX_SET_SOURCE failed"); } if (ioctl (PFD[i].fd, DMX_SET_BUFFER_SIZE, settings->buffer_size * 4) < 0) log_add ("ioctl DMX_SET_BUFFER_SIZE failed"); if (ioctl (PFD[i].fd, DMX_SET_FILTER, ¶ms) < 0) log_add ("ioctl DMX_SET_FILTER failed"); first_length[i] = 0; first_ok[i] = false; } total_size = 0; cycles = 0; while ((cycles < MAX_OTV_LOOP_CYCLES) && (poll (PFD, settings->pids_count, 5000) > 0)) { int k; bool ended = true; bool force_quit = false; for (i = 0; i < settings->pids_count; i++) { unsigned char buf[settings->buffer_size]; // 4K buffer size int size = 0; if (PFD[i].revents & POLLIN) size = read (PFD[i].fd, buf, sizeof (buf)); if (size == -1) continue; if (first_ok[i]) continue; if (size < settings->min_length) continue; if (first_length[i] == 0) { first_length[i] = size; memcpy (first[i], buf, size); } else if (first_length[i] == size) { if (memcmp (buf, first[i], size) == 0) first_ok[i] = true; } total_size += size; //data_callback (size, buf); force_quit = !data_callback (size, buf); } for (k = 0; k < settings->pids_count; k++) ended &= first_ok[k]; if (ended || force_quit) break; cycles++; } if (cycles == MAX_OTV_LOOP_CYCLES) log_add ("Maximum loop exceded"); for (i = 0; i < settings->pids_count; i++) // close filters { if (ioctl (PFD[i].fd, DMX_STOP) < 0) log_add ("Error stopping filter"); close (PFD[i].fd); } #endif }
virtual long fill(void * input_buffer, void * output_buffer, long frames_needed) { long got = data_callback(stream, user_ptr, input_buffer, output_buffer, frames_needed); assert(got <= frames_needed); return got; }
void usi_twi_slave(uint8_t slave_address_in, uint8_t use_sleep, void (*data_callback_in)(uint8_t buffer_size, volatile uint8_t input_buffer_length, volatile const uint8_t *input_buffer, volatile uint8_t *output_buffer_length, volatile uint8_t *output_buffer), void (*idle_callback_in)(void)) { slave_address = slave_address_in; data_callback = data_callback_in; idle_callback = idle_callback_in; input_buffer_length = 0; output_buffer_length = 0; output_buffer_current = 0; ss_state = ss_state_before_start; if(use_sleep) set_sleep_mode(SLEEP_MODE_IDLE); twi_init(); sei(); for(;;) { if(use_sleep && (ss_state == ss_state_before_start)) sleep_mode(); if(USISR & _BV(USIPF)) { cli(); #ifdef USE_STATS if(stats_enabled)stop_conditions_count++; #endif USISR |= _BV(USIPF); // clear stop condition flag switch(ss_state) { case(ss_state_after_start): { twi_reset(); break; } case(ss_state_data_processed): { #ifdef USE_STATS if(stats_enabled)local_frames_count++; #endif output_buffer_length = 0; output_buffer_current = 0; data_callback(buffer_size, input_buffer_length, input_buffer, &output_buffer_length, output_buffer); input_buffer_length = 0; break; } } ss_state = ss_state_before_start; sei(); } if(idle_callback) { idle_callback(); #ifdef USE_STATS if(stats_enabled)idle_call_count++; #endif } } }