Example #1
0
static void a2dp_demo_timer_stop(a2dp_media_sending_context_t * context){
    context->time_audio_data_sent = 0;
    context->acc_num_missed_samples = 0;
    context->samples_ready = 0;
    context->streaming = 1;
    context->sbc_storage_count = 0;
    context->sbc_ready_to_send = 0;
    btstack_run_loop_remove_timer(&context->audio_timer);
} 
Example #2
0
static void a2dp_demo_timer_start(a2dp_media_sending_context_t * context){
    context->max_media_payload_size = 0x290;// avdtp_max_media_payload_size(context->local_seid);
    context->sbc_storage_count = 0;
    context->sbc_ready_to_send = 0;
    context->streaming = 1;
    btstack_run_loop_remove_timer(&context->audio_timer);
    btstack_run_loop_set_timer_handler(&context->audio_timer, avdtp_audio_timeout_handler);
    btstack_run_loop_set_timer_context(&context->audio_timer, context);
    btstack_run_loop_set_timer(&context->audio_timer, AUDIO_TIMEOUT_MS); 
    btstack_run_loop_add_timer(&context->audio_timer);
}
/**
 * Execute run_loop once
 */
void btstack_run_loop_embedded_execute_once(void) {
    btstack_data_source_t *ds;

    // process data sources
    btstack_data_source_t *next;
    for (ds = (btstack_data_source_t *) data_sources; ds != NULL ; ds = next){
        next = (btstack_data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself
        if (ds->flags & DATA_SOURCE_CALLBACK_POLL){
            ds->process(ds, DATA_SOURCE_CALLBACK_POLL);
        }
    }
    
#ifdef TIMER_SUPPORT

#ifdef HAVE_EMBEDDED_TICK
    uint32_t now = system_ticks;
#endif
#ifdef HAVE_EMBEDDED_TIME_MS
    uint32_t now = hal_time_ms();
#endif

    // process timers
    while (timers) {
        btstack_timer_source_t *ts = (btstack_timer_source_t *) timers;
        uint32_t timeout_low = ts->timeout;
        int      timeout_high = btstack_run_loop_embedded_reconstruct_higher_bits(now, timeout_low);
        if (timeout_high > 0 || ((timeout_high == 0) && (timeout_low > now))) break;
        btstack_run_loop_remove_timer(ts);
        ts->process(ts);
    }
#endif
    
    // disable IRQs and check if run loop iteration has been requested. if not, go to sleep
    hal_cpu_disable_irqs();
    if (trigger_event_received){
        trigger_event_received = 0;
        hal_cpu_enable_irqs();
    } else {
        hal_cpu_enable_irqs_and_sleep();
    }
}
Example #4
0
static void a2dp_demo_timer_pause(a2dp_media_sending_context_t * context){
    btstack_run_loop_remove_timer(&context->audio_timer);
} 
Example #5
0
static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){

    att_server_t * att_server;

    switch (packet_type){

        case HCI_EVENT_PACKET:
            switch (packet[0]){
                case L2CAP_EVENT_CAN_SEND_NOW:
                    att_server_handle_can_send_now();
                    break;
                case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
                    // GATT client has negotiated the mtu for this connection
                    att_server = att_server_for_handle(handle);
                    if (!att_server) break;
                    att_server->connection.mtu = little_endian_read_16(packet, 4);
                    break;
                default:
                    break;
            }
            break;

        case ATT_DATA_PACKET:
            log_debug("ATT Packet, handle 0x%04x", handle);
            att_server = att_server_for_handle(handle);
            if (!att_server) break;

            // handle value indication confirms
            if (packet[0] == ATT_HANDLE_VALUE_CONFIRMATION && att_server->value_indication_handle){
                btstack_run_loop_remove_timer(&att_server->value_indication_timer);
                uint16_t att_handle = att_server->value_indication_handle;
                att_server->value_indication_handle = 0;    
                att_handle_value_indication_notify_client(0, att_server->connection.con_handle, att_handle);
                return;
            }

            // directly process command
            // note: signed write cannot be handled directly as authentication needs to be verified
            if (packet[0] == ATT_WRITE_COMMAND){
                att_handle_request(&att_server->connection, packet, size, 0);
                return;
            }

            // check size
            if (size > sizeof(att_server->request_buffer)) {
                log_info("att_packet_handler: dropping att pdu 0x%02x as size %u > att_server->request_buffer %u", packet[0], size, (int) sizeof(att_server->request_buffer));
                return;
            }

            // last request still in processing?
            if (att_server->state != ATT_SERVER_IDLE){
                log_info("att_packet_handler: skipping att pdu 0x%02x as server not idle (state %u)", packet[0], att_server->state);
                return;
            }

            // store request
            att_server->state = ATT_SERVER_REQUEST_RECEIVED;
            att_server->request_size = size;
            memcpy(att_server->request_buffer, packet, size);
        
            att_run_for_context(att_server);
            break;
    }
}
/**
 * Execute run_loop
 */
static void btstack_run_loop_posix_execute(void) {
    fd_set descriptors_read;
    fd_set descriptors_write;
    
    btstack_timer_source_t       *ts;
    btstack_linked_list_iterator_t it;
    struct timeval * timeout;
    struct timeval tv;
    uint32_t now_ms;

    while (1) {
        // collect FDs
        FD_ZERO(&descriptors_read);
        FD_ZERO(&descriptors_write);
        int highest_fd = -1;
        btstack_linked_list_iterator_init(&it, &data_sources);
        while (btstack_linked_list_iterator_has_next(&it)){
            btstack_data_source_t *ds = (btstack_data_source_t*) btstack_linked_list_iterator_next(&it);
            if (ds->fd < 0) continue;
            if (ds->flags & DATA_SOURCE_CALLBACK_READ){
                FD_SET(ds->fd, &descriptors_read);
                if (ds->fd > highest_fd) {
                    highest_fd = ds->fd;
                }
                log_debug("btstack_run_loop_execute adding fd %u for read", ds->fd);
            }
            if (ds->flags & DATA_SOURCE_CALLBACK_WRITE){
                FD_SET(ds->fd, &descriptors_write);
                if (ds->fd > highest_fd) {
                    highest_fd = ds->fd;
                }
                log_debug("btstack_run_loop_execute adding fd %u for write", ds->fd);
            }
        }
        
        // get next timeout
        timeout = NULL;
        if (timers) {
            ts = (btstack_timer_source_t *) timers;
            timeout = &tv;
            now_ms = btstack_run_loop_posix_get_time_ms();
            int delta = ts->timeout - now_ms;
            if (delta < 0){
                delta = 0;
            }
            tv.tv_sec  = delta / 1000;
            tv.tv_usec = (delta - (tv.tv_sec * 1000)) * 1000;
            log_debug("btstack_run_loop_execute next timeout in %u ms", delta);
        }
                
        // wait for ready FDs
        select( highest_fd+1 , &descriptors_read, &descriptors_write, NULL, timeout);
                

        data_sources_modified = 0;
        btstack_linked_list_iterator_init(&it, &data_sources);
        while (btstack_linked_list_iterator_has_next(&it) && !data_sources_modified){
            btstack_data_source_t *ds = (btstack_data_source_t*) btstack_linked_list_iterator_next(&it);
            log_debug("btstack_run_loop_posix_execute: check ds %p with fd %u\n", ds, ds->fd);
            if (FD_ISSET(ds->fd, &descriptors_read)) {
                log_debug("btstack_run_loop_posix_execute: process read ds %p with fd %u\n", ds, ds->fd);
                ds->process(ds, DATA_SOURCE_CALLBACK_READ);
            }
            if (FD_ISSET(ds->fd, &descriptors_write)) {
                log_debug("btstack_run_loop_posix_execute: process write ds %p with fd %u\n", ds, ds->fd);
                ds->process(ds, DATA_SOURCE_CALLBACK_WRITE);
            }
        }
        log_debug("btstack_run_loop_posix_execute: after ds check\n");
        
        // process timers
        now_ms = btstack_run_loop_posix_get_time_ms();
        while (timers) {
            ts = (btstack_timer_source_t *) timers;
            if (ts->timeout > now_ms) break;
            log_debug("btstack_run_loop_posix_execute: process timer %p\n", ts);
            
            // remove timer before processing it to allow handler to re-register with run loop
            btstack_run_loop_remove_timer(ts);
            ts->process(ts);
        }
    }
}