Example #1
0
static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
    if (packet_type != ATT_DATA_PACKET) return;

    // handle value indication confirms
    if (packet[0] == ATT_HANDLE_VALUE_CONFIRMATION && att_handle_value_indication_handle){
        run_loop_remove_timer(&att_handle_value_indication_timer);
        uint16_t att_handle = att_handle_value_indication_handle;
        att_handle_value_indication_handle = 0;    
        att_handle_value_indication_notify_client(0, att_connection.con_handle, att_handle);
        return;
    }

    // check size
    if (size > sizeof(att_request_buffer)) return;

    // last request still in processing?
    if (att_server_state != ATT_SERVER_IDLE) return;

    // store request
    att_server_state = ATT_SERVER_REQUEST_RECEIVED;
    att_request_size = size;
    memcpy(att_request_buffer, packet, size);

    att_run();
}
/**
 * Execute run_loop once
 */
void embedded_execute_once(void) {
    // refresh system_ticks
    system_ticks = btstack_get_time();

    data_source_t *ds;

    // process data sources
    data_source_t *next;
    for (ds = (data_source_t *) data_sources; ds != NULL ; ds = next){
        next = (data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself
        ds->process(ds);
    }
    
#ifdef HAVE_TICK
    // process timers
    while (timers) {
        timer_source_t *ts = (timer_source_t *) timers;
        if (ts->timeout > system_ticks) break;
        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 #3
0
/**
 * Execute run_loop once
 */
void embedded_execute_once(void) {
    data_source_t *ds;

    // process data sources
    data_source_t *next;
    for (ds = (data_source_t *) data_sources; ds != NULL ; ds = next){
        next = (data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself
        ds->process(ds);
    }
    
#ifdef HAVE_TICK
    uint32_t now = system_ticks;
#endif
#ifdef HAVE_TIME_MS
    uint32_t now = hal_time_ms();
#endif
#ifdef TIMER_SUPPORT
    // process timers
    while (timers) {
        timer_source_t *ts = (timer_source_t *) timers;
        if (ts->timeout > now) break;
        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 stop_power_off_timer(void){
#ifdef USE_POWER_OFF_TIMER
    if (timeout_active) {
        run_loop_remove_timer(&timeout);
        timeout_active = 0;
    }
#endif
}
static void h4_enforce_wake_off(void)
{
    run_loop_remove_timer(&hci_transport_h4->sleep_timer);
    
    if (enforce_wake_fd) {
        close(enforce_wake_fd);
        enforce_wake_fd = 0;
    }
}
static void h4_enforce_wake_on(void)
{
    if (!enforce_wake_device) return;
    
    if (!enforce_wake_fd) {
        enforce_wake_fd = open(enforce_wake_device, O_RDWR);
        usleep(HCI_WAKE_DURATION);  // wait until device is ready
    }
    run_loop_remove_timer(&hci_transport_h4->sleep_timer);
    run_loop_set_timer(&hci_transport_h4->sleep_timer, HCI_WAKE_TIMER_MS);
    hci_transport_h4->sleep_timer.process = h4_enforce_wake_timeout;
    run_loop_add_timer(&hci_transport_h4->sleep_timer); 
}
Example #7
0
File: hci.c Project: ajsb85/ioio
static void hci_shutdown_connection(hci_connection_t *conn){
    log_info("Connection closed: handle %u, %s\n", conn->con_handle, bd_addr_to_str(conn->address));

    // cancel all l2cap connections
    hci_emit_disconnection_complete(conn->con_handle, 0x16);    // terminated by local host

    run_loop_remove_timer(&conn->timeout);
    
    linked_list_remove(&hci_stack.connections, (linked_item_t *) conn);
    btstack_memory_hci_connection_free( conn );
    
    // now it's gone
    hci_emit_nr_connections_changed();
}
Example #8
0
/**
 * Execute run_loop
 */
void embedded_execute(void) {
    data_source_t *ds;

    while (1) {
        USBHostTasks();

        // process data sources
        data_source_t *next;
        for (ds = (data_source_t *) data_sources; ds != NULL ; ds = next){
            next = (data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself
            ds->process(ds);
        }

#ifdef HAVE_TICK
        // process timers
        while (timers) {
            timer_source_t *ts = (timer_source_t *) timers;
            if (ts->timeout > system_ticks) break;
            run_loop_remove_timer(ts);
            ts->process(ts);
        }
#endif

#if	USE_SPP_SERVER || USE_DUALSHOCK3_RUMBLE
		sendchar();
#endif

        // disable IRQs and check if run loop iteration has been requested. if not, go to sleep
#if	0
        hal_cpu_disable_irqs();
        if (trigger_event_received){
            hal_cpu_enable_irqs_and_sleep();
            continue;
        }
        hal_cpu_enable_irqs();
#else
		Idle();
#endif
#ifndef	__DEBUG
		if(!deviceAddress){
			Reset();
		}
#endif
    }
}
Example #9
0
static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
    if (packet_type != ATT_DATA_PACKET) return;

    // handle value indication confirms
    if (packet[0] == ATT_HANDLE_VALUE_CONFIRMATION && att_handle_value_indication_handle){
        run_loop_remove_timer(&att_handle_value_indication_timer);
        uint16_t att_handle = att_handle_value_indication_handle;
        att_handle_value_indication_handle = 0;    
        att_handle_value_indication_notify_client(0, att_connection.con_handle, att_handle);
        return;
    }

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

    // check size
    if (size > sizeof(att_request_buffer)) {
        log_info("att_packet_handler: dropping att pdu 0x%02x as size %u > att_request_buffer %u", packet[0], size, (int) sizeof(att_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_request_size = size;
    memcpy(att_request_buffer, packet, size);

    att_run();
}
static int usb_close(void *transport_config){
    int c;
    // @TODO: remove all run loops!

    switch (libusb_state){
        case LIB_USB_CLOSED:
            break;

        case LIB_USB_TRANSFERS_ALLOCATED:
            libusb_state = LIB_USB_INTERFACE_CLAIMED;

            if(usb_timer_active) {
                run_loop_remove_timer(&usb_timer);
                usb_timer_active = 0;
            }

            // Cancel any asynchronous transfers
            for (c = 0 ; c < ASYNC_BUFFERS ; c++) {
                libusb_cancel_transfer(event_in_transfer[c]);
                libusb_cancel_transfer(acl_in_transfer[c]);
#ifdef HAVE_SCO
                libusb_cancel_transfer(sco_in_transfer[c]);
#endif
            }

            /* TODO - find a better way to ensure that all transfers have completed */
            struct timeval tv;
            memset(&tv, 0, sizeof(struct timeval));
            libusb_handle_events_timeout(NULL, &tv);

            if (doing_pollfds){
                int r;
                for (r = 0 ; r < num_pollfds ; r++) {
                    data_source_t *ds = &pollfd_data_sources[r];
                    run_loop_remove_data_source(ds);
                }
                free(pollfd_data_sources);
                pollfd_data_sources = NULL;
                num_pollfds = 0;
                doing_pollfds = 0;
            }

        case LIB_USB_INTERFACE_CLAIMED:
            for (c = 0 ; c < ASYNC_BUFFERS ; c++) {
                if (event_in_transfer[c]) libusb_free_transfer(event_in_transfer[c]);
                if (acl_in_transfer[c])   libusb_free_transfer(acl_in_transfer[c]);
#ifdef HAVE_SCO
                if (sco_in_transfer[c])   libusb_free_transfer(sco_in_transfer[c]);
#endif
            }

            // TODO free control and acl out transfers

            libusb_release_interface(handle, 0);

        case LIB_USB_DEVICE_OPENDED:
            libusb_close(handle);

        case LIB_USB_OPENED:
            libusb_exit(NULL);
    }

    libusb_state = LIB_USB_CLOSED;
    handle = NULL;

    return 0;
}
Example #11
0
static void hsp_ringing_timer_stop(void){
    run_loop_remove_timer(&hs_timeout);
} 
Example #12
0
static void hsp_ringing_timer_start(void){
    run_loop_remove_timer(&hs_timeout);
    run_loop_set_timer_handler(&hs_timeout, hsp_ringing_timeout_handler);
    run_loop_set_timer(&hs_timeout, 2000); // 2 seconds timeout
    run_loop_add_timer(&hs_timeout);
}
Example #13
0
/**
 * Execute run_loop
 */
static void posix_execute(void) {
    fd_set descriptors;
    
    timer_source_t       *ts;
    struct timeval current_tv;
    struct timeval next_tv;
    struct timeval *timeout;
    linked_list_iterator_t it;
    
    while (1) {
        // collect FDs
        FD_ZERO(&descriptors);
        int highest_fd = 0;
        linked_list_iterator_init(&it, &data_sources);
        while (linked_list_iterator_has_next(&it)){
            data_source_t *ds = (data_source_t*) linked_list_iterator_next(&it);
            if (ds->fd >= 0) {
                FD_SET(ds->fd, &descriptors);
                if (ds->fd > highest_fd) {
                    highest_fd = ds->fd;
                }
            }
        }
        
        // get next timeout
        // pre: 0 <= tv_usec < 1000000
        timeout = NULL;
        if (timers) {
            gettimeofday(&current_tv, NULL);
            ts = (timer_source_t *) timers;
            next_tv.tv_usec = ts->timeout.tv_usec - current_tv.tv_usec;
            next_tv.tv_sec  = ts->timeout.tv_sec  - current_tv.tv_sec;
            while (next_tv.tv_usec < 0){
                next_tv.tv_usec += 1000000;
                next_tv.tv_sec--;
            }
            if (next_tv.tv_sec < 0){
                next_tv.tv_sec  = 0; 
                next_tv.tv_usec = 0;
            }
            timeout = &next_tv;
        }
                
        // wait for ready FDs
        select( highest_fd+1 , &descriptors, NULL, NULL, timeout);
        
        // process data sources very carefully
        // bt_control.close() triggered from a client can remove a different data source
        
        // log_info("posix_execute: before ds check\n");
        data_sources_modified = 0;
        linked_list_iterator_init(&it, &data_sources);
        while (linked_list_iterator_has_next(&it) && !data_sources_modified){
            data_source_t *ds = (data_source_t*) linked_list_iterator_next(&it);
            // log_info("posix_execute: check %x with fd %u\n", (int) ds, ds->fd);
            if (FD_ISSET(ds->fd, &descriptors)) {
                // log_info("posix_execute: process %x with fd %u\n", (int) ds, ds->fd);
                ds->process(ds);
            }
        }
        // log_info("posix_execute: after ds check\n");
        
        // process timers
        // pre: 0 <= tv_usec < 1000000
        while (timers) {
            gettimeofday(&current_tv, NULL);
            ts = (timer_source_t *) timers;
            if (ts->timeout.tv_sec  > current_tv.tv_sec) break;
            if (ts->timeout.tv_sec == current_tv.tv_sec && ts->timeout.tv_usec > current_tv.tv_usec) break;
            // log_info("posix_execute: process times %x\n", (int) ts);
            
            // remove timer before processing it to allow handler to re-register with run loop
            run_loop_remove_timer(ts);
            ts->process(ts);
        }
    }
}