mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-28 08:37:22 +00:00
support for prefsbundle, bug fixes, other stuff
This commit is contained in:
parent
f6b3c2766c
commit
3c4d4b9093
@ -6,8 +6,12 @@ if USE_BLUETOOL
|
|||||||
patchbluetool = PatchBlueTool
|
patchbluetool = PatchBlueTool
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if USE_PREFSBUNDLE
|
||||||
|
patchbluetool = PrefsBundle
|
||||||
|
endif
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign
|
AUTOMAKE_OPTIONS = foreign
|
||||||
SUBDIRS = src example $(springboardaccess) $(patchbluetool)
|
SUBDIRS = src example $(springboardaccess) $(prefsbundle) $(patchbluetool)
|
||||||
|
|
||||||
iphone_ip=@IPHONE_IP@
|
iphone_ip=@IPHONE_IP@
|
||||||
install-iphone: src/BTdaemon
|
install-iphone: src/BTdaemon
|
||||||
|
@ -1 +1 @@
|
|||||||
./configure --target=iphone --enable-launchd --enable-ldid --with-uart-speed=921600
|
./configure --target=iphone --enable-launchd --enable-ldid --with-prefsbundle --with-uart-speed=921600
|
@ -12,6 +12,7 @@ AC_ARG_WITH(uart-speed, [AS_HELP_STRING([--with-uart-speed=uartSpeed], [Specify
|
|||||||
AC_ARG_ENABLE(bluetool, [AS_HELP_STRING([--disable-bluetool],[Disable init of Bluetooth module by BlueTool])], USE_BLUETOOL=$enableval, USE_BLUETOOL="DEFAULT")
|
AC_ARG_ENABLE(bluetool, [AS_HELP_STRING([--disable-bluetool],[Disable init of Bluetooth module by BlueTool])], USE_BLUETOOL=$enableval, USE_BLUETOOL="DEFAULT")
|
||||||
AC_ARG_ENABLE(springboard, [AS_HELP_STRING([--disable-springboard],[Disable display of BTstack status in SpringBoard])], USE_SPRINGBOARD=$enableval, USE_SPRINGBOARD="DEFAULT")
|
AC_ARG_ENABLE(springboard, [AS_HELP_STRING([--disable-springboard],[Disable display of BTstack status in SpringBoard])], USE_SPRINGBOARD=$enableval, USE_SPRINGBOARD="DEFAULT")
|
||||||
AC_ARG_ENABLE(launchd, [AS_HELP_STRING([--enable-launchd],[Compiles BTdaemon for use by launchd])], USE_LAUNCHD=$enableval, USE_LAUNCHD="no")
|
AC_ARG_ENABLE(launchd, [AS_HELP_STRING([--enable-launchd],[Compiles BTdaemon for use by launchd])], USE_LAUNCHD=$enableval, USE_LAUNCHD="no")
|
||||||
|
AC_ARG_WITH(prefsbundle, [AS_HELP_STRING([--with-prefsbundle],[Compiles iPhone Preferences Bundle])], USE_PREFSBUNDLE=$enableval, USE_PREFSBUNDLE="no")
|
||||||
AC_ARG_WITH(iphone-ip, [AS_HELP_STRING([--with-iphone-ip=192.168.1.5], [Specify IP address used by iPhone for installation (not supported yet)])], IPHONE_IP=$withval, IPHONE_IP="")
|
AC_ARG_WITH(iphone-ip, [AS_HELP_STRING([--with-iphone-ip=192.168.1.5], [Specify IP address used by iPhone for installation (not supported yet)])], IPHONE_IP=$withval, IPHONE_IP="")
|
||||||
AC_ARG_WITH(vendor-id, [AS_HELP_STRING([--with-vendor-id=vendorID], [Specify USB BT Dongle vendorID])], USB_VENDOR_ID=$withval, USB_VENDOR_ID="")
|
AC_ARG_WITH(vendor-id, [AS_HELP_STRING([--with-vendor-id=vendorID], [Specify USB BT Dongle vendorID])], USB_VENDOR_ID=$withval, USB_VENDOR_ID="")
|
||||||
AC_ARG_WITH(product-id, [AS_HELP_STRING([--with-product-id=productID], [Specify USB BT Dongle productID])], USB_PRODUCT_ID=$withval, USB_PRODUCT_ID="")
|
AC_ARG_WITH(product-id, [AS_HELP_STRING([--with-product-id=productID], [Specify USB BT Dongle productID])], USB_PRODUCT_ID=$withval, USB_PRODUCT_ID="")
|
||||||
@ -189,6 +190,7 @@ fi
|
|||||||
|
|
||||||
AM_CONDITIONAL(USE_SPRINGBOARD, [test "x$USE_SPRINGBOARD" == "xyes"])
|
AM_CONDITIONAL(USE_SPRINGBOARD, [test "x$USE_SPRINGBOARD" == "xyes"])
|
||||||
AM_CONDITIONAL(USE_BLUETOOL, [test "x$USE_BLUETOOL" == "xyes"])
|
AM_CONDITIONAL(USE_BLUETOOL, [test "x$USE_BLUETOOL" == "xyes"])
|
||||||
|
AM_CONDITIONAL(USE_PREFSBUNDLE, [test "x$USE_PREFSBUNDLE" == "xyes"])
|
||||||
|
|
||||||
# summary
|
# summary
|
||||||
if test "x$HCI_TRANSPORT" = xUSB; then
|
if test "x$HCI_TRANSPORT" = xUSB; then
|
||||||
@ -203,6 +205,7 @@ fi
|
|||||||
|
|
||||||
echo "USE_LAUNCHD: $USE_LAUNCHD"
|
echo "USE_LAUNCHD: $USE_LAUNCHD"
|
||||||
echo "USE_SPRINGBOARD: $USE_SPRINGBOARD"
|
echo "USE_SPRINGBOARD: $USE_SPRINGBOARD"
|
||||||
|
echo "USE_PREFSBUNDLE: $USE_PREFSBUNDLE"
|
||||||
echo "USE_COCOA_RUN_LOOP: $USE_COCOA_RUN_LOOP"
|
echo "USE_COCOA_RUN_LOOP: $USE_COCOA_RUN_LOOP"
|
||||||
echo "REMOTE_DEVICE_DB: $REMOTE_DEVICE_DB"
|
echo "REMOTE_DEVICE_DB: $REMOTE_DEVICE_DB"
|
||||||
echo
|
echo
|
||||||
|
@ -215,6 +215,7 @@ extern const hci_cmd_t btstack_get_version;
|
|||||||
extern const hci_cmd_t btstack_get_system_bluetooth_enabled;
|
extern const hci_cmd_t btstack_get_system_bluetooth_enabled;
|
||||||
extern const hci_cmd_t btstack_set_system_bluetooth_enabled;
|
extern const hci_cmd_t btstack_set_system_bluetooth_enabled;
|
||||||
extern const hci_cmd_t btstack_set_discoverable;
|
extern const hci_cmd_t btstack_set_discoverable;
|
||||||
|
extern const hci_cmd_t btstack_set_bluetooth_enabled; // only used by btstack config
|
||||||
|
|
||||||
extern const hci_cmd_t hci_accept_connection_request;
|
extern const hci_cmd_t hci_accept_connection_request;
|
||||||
extern const hci_cmd_t hci_authentication_requested;
|
extern const hci_cmd_t hci_authentication_requested;
|
||||||
|
@ -79,12 +79,33 @@ typedef enum {
|
|||||||
#define SDP_ClientExecutableURL 0x000b
|
#define SDP_ClientExecutableURL 0x000b
|
||||||
#define SDP_IconURL 0x000c
|
#define SDP_IconURL 0x000c
|
||||||
#define SDP_AdditionalProtocolDescriptorList 0x000d
|
#define SDP_AdditionalProtocolDescriptorList 0x000d
|
||||||
|
#define SDP_SupportedFormatsList 0x0303
|
||||||
|
|
||||||
|
// SERVICE CLASSES
|
||||||
|
#define SDP_OBEXObjectPush 0x1105
|
||||||
|
#define SDP_OBEXFileTransfer 0x1106
|
||||||
|
#define SDP_PublicBrowseGroup 0x1002
|
||||||
|
|
||||||
|
// PROTOCOLS
|
||||||
|
#define SDP_SDPProtocol 0x0001
|
||||||
|
#define SDP_UDPProtocol 0x0002
|
||||||
|
#define SDP_RFCOMMProtocol 0x0003
|
||||||
|
#define SDP_OBEXProtocol 0x0008
|
||||||
|
#define SDP_L2CAPProtocol 0x0100
|
||||||
|
|
||||||
// OFFSETS FOR LOCALIZED ATTRIBUTES - SDP_LanguageBaseAttributeIDList
|
// OFFSETS FOR LOCALIZED ATTRIBUTES - SDP_LanguageBaseAttributeIDList
|
||||||
#define SDP_Offest_ServiceName 0x0000
|
#define SDP_Offest_ServiceName 0x0000
|
||||||
#define SDP_Offest_ServiceDescription 0x0001
|
#define SDP_Offest_ServiceDescription 0x0001
|
||||||
#define SDP_Offest_ProviderName 0x0002
|
#define SDP_Offest_ProviderName 0x0002
|
||||||
|
|
||||||
|
// OBEX
|
||||||
|
#define SDP_vCard_2_1 0x01
|
||||||
|
#define SDP_vCard_3_0 0x02
|
||||||
|
#define SDP_vCal_1_0 0x03
|
||||||
|
#define SDP_iCal_2_0 0x04
|
||||||
|
#define SDP_vNote 0x05
|
||||||
|
#define SDP_vMessage 0x06
|
||||||
|
#define SDP_OBEXFileTypeAny 0xFF
|
||||||
|
|
||||||
#pragma mark DateElement
|
#pragma mark DateElement
|
||||||
void de_dump_data_element(uint8_t * record);
|
void de_dump_data_element(uint8_t * record);
|
||||||
|
38
src/daemon.c
38
src/daemon.c
@ -61,6 +61,7 @@
|
|||||||
|
|
||||||
#ifdef USE_BLUETOOL
|
#ifdef USE_BLUETOOL
|
||||||
#include "bt_control_iphone.h"
|
#include "bt_control_iphone.h"
|
||||||
|
#include <notify.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SPRINGBOARD
|
#ifdef USE_SPRINGBOARD
|
||||||
@ -94,6 +95,7 @@ static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state);
|
|||||||
static client_state_t * client_for_connection(connection_t *connection);
|
static client_state_t * client_for_connection(connection_t *connection);
|
||||||
static int clients_require_power_on();
|
static int clients_require_power_on();
|
||||||
static int clients_require_discoverable();
|
static int clients_require_discoverable();
|
||||||
|
static int clients_clear_power_request();
|
||||||
static void start_power_off_timer();
|
static void start_power_off_timer();
|
||||||
static void stop_power_off_timer();
|
static void stop_power_off_timer();
|
||||||
|
|
||||||
@ -106,6 +108,7 @@ static int power_management_sleep = 0;
|
|||||||
static linked_list_t clients = NULL; // list of connected clients
|
static linked_list_t clients = NULL; // list of connected clients
|
||||||
static void (*bluetooth_status_handler)(BLUETOOTH_STATE state) = dummy_bluetooth_status_handler;
|
static void (*bluetooth_status_handler)(BLUETOOTH_STATE state) = dummy_bluetooth_status_handler;
|
||||||
|
|
||||||
|
static int global_enable = 0;
|
||||||
|
|
||||||
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state){
|
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state){
|
||||||
printf("Bluetooth status: %u\n", state);
|
printf("Bluetooth status: %u\n", state);
|
||||||
@ -173,6 +176,19 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
|||||||
// merge state
|
// merge state
|
||||||
hci_discoverable_control(clients_require_discoverable());
|
hci_discoverable_control(clients_require_discoverable());
|
||||||
break;
|
break;
|
||||||
|
case BTSTACK_SET_BLUETOOTH_ENABLED:
|
||||||
|
printf("BTSTACK_SET_BLUETOOTH_ENABLED: %u\n", packet[3]);
|
||||||
|
|
||||||
|
if (packet[3]) {
|
||||||
|
// global enable
|
||||||
|
global_enable = 1;
|
||||||
|
hci_power_control(HCI_POWER_ON);
|
||||||
|
} else {
|
||||||
|
global_enable = 0;
|
||||||
|
clients_clear_power_request();
|
||||||
|
hci_power_control(HCI_POWER_OFF);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case L2CAP_CREATE_CHANNEL_MTU:
|
case L2CAP_CREATE_CHANNEL_MTU:
|
||||||
bt_flip_addr(addr, &packet[3]);
|
bt_flip_addr(addr, &packet[3]);
|
||||||
psm = READ_BT_16(packet, 9);
|
psm = READ_BT_16(packet, 9);
|
||||||
@ -359,6 +375,12 @@ static void power_notification_callback(POWER_NOTIFICATION_t notification){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void daemon_sigint_handler(int param){
|
static void daemon_sigint_handler(int param){
|
||||||
|
|
||||||
|
#ifdef USE_BLUETOOL
|
||||||
|
// hack for celeste
|
||||||
|
notify_post("ch.ringwald.btstack.stopped");
|
||||||
|
#endif
|
||||||
|
|
||||||
printf(" <= SIGINT received, shutting down..\n");
|
printf(" <= SIGINT received, shutting down..\n");
|
||||||
hci_power_control( HCI_POWER_OFF);
|
hci_power_control( HCI_POWER_OFF);
|
||||||
hci_close();
|
hci_close();
|
||||||
@ -497,6 +519,11 @@ int main (int argc, char * const * argv){
|
|||||||
#endif
|
#endif
|
||||||
socket_connection_register_packet_callback(daemon_client_handler);
|
socket_connection_register_packet_callback(daemon_client_handler);
|
||||||
|
|
||||||
|
#ifdef USE_BLUETOOL
|
||||||
|
// hack for celeste
|
||||||
|
notify_post("ch.ringwald.btstack.started");
|
||||||
|
#endif
|
||||||
|
|
||||||
// go!
|
// go!
|
||||||
run_loop_execute();
|
run_loop_execute();
|
||||||
return 0;
|
return 0;
|
||||||
@ -541,7 +568,18 @@ static client_state_t * client_for_connection(connection_t *connection) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int clients_clear_power_request(){
|
||||||
|
linked_item_t *it;
|
||||||
|
for (it = (linked_item_t *) clients; it ; it = it->next){
|
||||||
|
client_state_t * client_state = (client_state_t *) it;
|
||||||
|
client_state->power_mode = HCI_POWER_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int clients_require_power_on(){
|
static int clients_require_power_on(){
|
||||||
|
|
||||||
|
if (global_enable) return 1;
|
||||||
|
|
||||||
linked_item_t *it;
|
linked_item_t *it;
|
||||||
for (it = (linked_item_t *) clients; it ; it = it->next){
|
for (it = (linked_item_t *) clients; it ; it = it->next){
|
||||||
client_state_t * client_state = (client_state_t *) it;
|
client_state_t * client_state = (client_state_t *) it;
|
||||||
|
30
src/hci.c
30
src/hci.c
@ -309,9 +309,15 @@ static void hci_shutdown_connection(hci_connection_t *conn){
|
|||||||
log_dbg("Connection closed: handle %u, ", conn->con_handle);
|
log_dbg("Connection closed: handle %u, ", conn->con_handle);
|
||||||
print_bd_addr( conn->address );
|
print_bd_addr( conn->address );
|
||||||
log_dbg("\n");
|
log_dbg("\n");
|
||||||
|
|
||||||
|
// cancel all l2cap connections
|
||||||
|
hci_emit_disconnection_complete(conn->con_handle, 0x16); // terminated by local host
|
||||||
|
|
||||||
run_loop_remove_timer(&conn->timeout);
|
run_loop_remove_timer(&conn->timeout);
|
||||||
linked_list_remove(&hci_stack.connections, (linked_item_t *) conn);
|
linked_list_remove(&hci_stack.connections, (linked_item_t *) conn);
|
||||||
free( conn );
|
free( conn );
|
||||||
|
|
||||||
|
// now it's gone
|
||||||
hci_emit_nr_connections_changed();
|
hci_emit_nr_connections_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,6 +849,12 @@ void hci_run(){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6:
|
case 6:
|
||||||
|
#ifdef USE_BLUETOOL
|
||||||
|
hci_send_cmd(&hci_write_class_of_device, 0x007a020c); // Smartphone
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
// done.
|
// done.
|
||||||
hci_stack.state = HCI_STATE_WORKING;
|
hci_stack.state = HCI_STATE_WORKING;
|
||||||
@ -866,9 +878,6 @@ void hci_run(){
|
|||||||
|
|
||||||
// send disconnected event right away - causes higher layer connections to get closed, too.
|
// send disconnected event right away - causes higher layer connections to get closed, too.
|
||||||
hci_shutdown_connection(connection);
|
hci_shutdown_connection(connection);
|
||||||
|
|
||||||
// remove from table
|
|
||||||
hci_stack.connections = connection->item.next;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log_dbg("HCI_STATE_HALTING, calling off\n");
|
log_dbg("HCI_STATE_HALTING, calling off\n");
|
||||||
@ -892,9 +901,6 @@ void hci_run(){
|
|||||||
|
|
||||||
// send disconnected event right away - causes higher layer connections to get closed, too.
|
// send disconnected event right away - causes higher layer connections to get closed, too.
|
||||||
hci_shutdown_connection(connection);
|
hci_shutdown_connection(connection);
|
||||||
|
|
||||||
// remove from table
|
|
||||||
hci_stack.connections = connection->item.next;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1015,6 +1021,18 @@ void hci_emit_connection_complete(hci_connection_t *conn){
|
|||||||
hci_stack.packet_handler(HCI_EVENT_PACKET, event, len);
|
hci_stack.packet_handler(HCI_EVENT_PACKET, event, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hci_emit_disconnection_complete(uint16_t handle, uint8_t reason){
|
||||||
|
uint8_t len = 6;
|
||||||
|
uint8_t event[len];
|
||||||
|
event[0] = HCI_EVENT_DISCONNECTION_COMPLETE;
|
||||||
|
event[1] = len - 3;
|
||||||
|
event[2] = 0; // status = OK
|
||||||
|
bt_store_16(event, 3, handle);
|
||||||
|
event[5] = reason;
|
||||||
|
hci_dump_packet( HCI_EVENT_PACKET, 0, event, len);
|
||||||
|
hci_stack.packet_handler(HCI_EVENT_PACKET, event, len);
|
||||||
|
}
|
||||||
|
|
||||||
void hci_emit_l2cap_check_timeout(hci_connection_t *conn){
|
void hci_emit_l2cap_check_timeout(hci_connection_t *conn){
|
||||||
uint8_t len = 4;
|
uint8_t len = 4;
|
||||||
uint8_t event[len];
|
uint8_t event[len];
|
||||||
|
@ -92,6 +92,9 @@ extern "C" {
|
|||||||
// enable inquiry scan for this client
|
// enable inquiry scan for this client
|
||||||
#define BTSTACK_SET_DISCOVERABLE 0x07
|
#define BTSTACK_SET_DISCOVERABLE 0x07
|
||||||
|
|
||||||
|
// set global Bluetooth state
|
||||||
|
#define BTSTACK_SET_BLUETOOTH_ENABLED 0x08
|
||||||
|
|
||||||
// create l2cap channel: @param bd_addr(48), psm (16)
|
// create l2cap channel: @param bd_addr(48), psm (16)
|
||||||
#define L2CAP_CREATE_CHANNEL 0x20
|
#define L2CAP_CREATE_CHANNEL 0x20
|
||||||
|
|
||||||
@ -270,6 +273,7 @@ uint16_t hci_max_acl_data_packet_length();
|
|||||||
void hci_emit_state();
|
void hci_emit_state();
|
||||||
void hci_emit_connection_complete(hci_connection_t *conn);
|
void hci_emit_connection_complete(hci_connection_t *conn);
|
||||||
void hci_emit_l2cap_check_timeout(hci_connection_t *conn);
|
void hci_emit_l2cap_check_timeout(hci_connection_t *conn);
|
||||||
|
void hci_emit_disconnection_complete(uint16_t handle, uint8_t reason);
|
||||||
void hci_emit_nr_connections_changed();
|
void hci_emit_nr_connections_changed();
|
||||||
void hci_emit_hci_open_failed();
|
void hci_emit_hci_open_failed();
|
||||||
void hci_emit_btstack_version();
|
void hci_emit_btstack_version();
|
||||||
|
@ -295,7 +295,7 @@ OPCODE(OGF_CONTROLLER_BASEBAND, 0x36), "H"
|
|||||||
};
|
};
|
||||||
const hci_cmd_t hci_write_link_supervision_timeout = {
|
const hci_cmd_t hci_write_link_supervision_timeout = {
|
||||||
OPCODE(OGF_CONTROLLER_BASEBAND, 0x37), "H2"
|
OPCODE(OGF_CONTROLLER_BASEBAND, 0x37), "H2"
|
||||||
// handle, Range for N: 0x0001 – 0xFFFF Time (Range: 0.625ms – 40.9 sec)
|
// handle, Range for N: 0x0001 Ð 0xFFFF Time (Range: 0.625ms Ð 40.9 sec)
|
||||||
};
|
};
|
||||||
const hci_cmd_t hci_write_inquiry_mode = {
|
const hci_cmd_t hci_write_inquiry_mode = {
|
||||||
OPCODE(OGF_CONTROLLER_BASEBAND, 0x45), "1"
|
OPCODE(OGF_CONTROLLER_BASEBAND, 0x45), "1"
|
||||||
@ -354,7 +354,10 @@ const hci_cmd_t btstack_set_discoverable = {
|
|||||||
OPCODE(OGF_BTSTACK, BTSTACK_SET_DISCOVERABLE), "1"
|
OPCODE(OGF_BTSTACK, BTSTACK_SET_DISCOVERABLE), "1"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hci_cmd_t btstack_set_bluetooth_enabled = {
|
||||||
|
// only used by btstack config
|
||||||
|
OPCODE(OGF_BTSTACK, BTSTACK_SET_BLUETOOTH_ENABLED), "1"
|
||||||
|
};
|
||||||
|
|
||||||
const hci_cmd_t l2cap_create_channel = {
|
const hci_cmd_t l2cap_create_channel = {
|
||||||
OPCODE(OGF_BTSTACK, L2CAP_CREATE_CHANNEL), "B2"
|
OPCODE(OGF_BTSTACK, L2CAP_CREATE_CHANNEL), "B2"
|
||||||
|
@ -276,8 +276,13 @@ static void h4_statemachine(){
|
|||||||
static int h4_process(struct data_source *ds) {
|
static int h4_process(struct data_source *ds) {
|
||||||
if (hci_transport_h4->uart_fd == 0) return -1;
|
if (hci_transport_h4->uart_fd == 0) return -1;
|
||||||
|
|
||||||
|
int read_now = bytes_to_read;
|
||||||
|
// if (read_now > 100) {
|
||||||
|
// read_now = 100;
|
||||||
|
// }
|
||||||
|
|
||||||
// read up to bytes_to_read data in
|
// read up to bytes_to_read data in
|
||||||
int bytes_read = read(hci_transport_h4->uart_fd, &hci_packet[read_pos], bytes_to_read);
|
ssize_t bytes_read = read(hci_transport_h4->uart_fd, &hci_packet[read_pos], read_now);
|
||||||
// printf("h4_process: bytes read %u\n", bytes_read);
|
// printf("h4_process: bytes read %u\n", bytes_read);
|
||||||
if (bytes_read < 0) {
|
if (bytes_read < 0) {
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
|
@ -44,14 +44,19 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void posix_dump_timer();
|
||||||
|
|
||||||
// the run loop
|
// the run loop
|
||||||
static linked_list_t data_sources;
|
static linked_list_t data_sources;
|
||||||
|
static int data_sources_modified;
|
||||||
static linked_list_t timers;
|
static linked_list_t timers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add data_source to run_loop
|
* Add data_source to run_loop
|
||||||
*/
|
*/
|
||||||
void posix_add_data_source(data_source_t *ds){
|
void posix_add_data_source(data_source_t *ds){
|
||||||
|
data_sources_modified = 1;
|
||||||
|
// printf("posix_add_data_source %x with fd %u\n", (int) ds, ds->fd);
|
||||||
linked_list_add(&data_sources, (linked_item_t *) ds);
|
linked_list_add(&data_sources, (linked_item_t *) ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +64,8 @@ void posix_add_data_source(data_source_t *ds){
|
|||||||
* Remove data_source from run loop
|
* Remove data_source from run loop
|
||||||
*/
|
*/
|
||||||
int posix_remove_data_source(data_source_t *ds){
|
int posix_remove_data_source(data_source_t *ds){
|
||||||
|
data_sources_modified = 1;
|
||||||
|
// printf("posix_remove_data_source %x\n", (int) ds);
|
||||||
return linked_list_remove(&data_sources, (linked_item_t *) ds);
|
return linked_list_remove(&data_sources, (linked_item_t *) ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +75,11 @@ int posix_remove_data_source(data_source_t *ds){
|
|||||||
void posix_add_timer(timer_source_t *ts){
|
void posix_add_timer(timer_source_t *ts){
|
||||||
linked_item_t *it;
|
linked_item_t *it;
|
||||||
for (it = (linked_item_t *) &timers; it->next ; it = it->next){
|
for (it = (linked_item_t *) &timers; it->next ; it = it->next){
|
||||||
if (run_loop_timer_compare( (timer_source_t *) it->next, ts) >= 0) {
|
if ((timer_source_t *) it->next == ts){
|
||||||
|
fprintf(stderr, "run_loop_timer_add error: timer to add already in list!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (run_loop_timer_compare( (timer_source_t *) it->next, ts) > 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,6 +94,7 @@ void posix_add_timer(timer_source_t *ts){
|
|||||||
*/
|
*/
|
||||||
int posix_remove_timer(timer_source_t *ts){
|
int posix_remove_timer(timer_source_t *ts){
|
||||||
// printf("Removed timer %x at %u\n", (int) ts, (unsigned int) ts->timeout.tv_sec);
|
// printf("Removed timer %x at %u\n", (int) ts, (unsigned int) ts->timeout.tv_sec);
|
||||||
|
// posix_dump_timer();
|
||||||
return linked_list_remove(&timers, (linked_item_t *) ts);
|
return linked_list_remove(&timers, (linked_item_t *) ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,14 +153,19 @@ void posix_execute() {
|
|||||||
// wait for ready FDs
|
// wait for ready FDs
|
||||||
select( highest_fd+1 , &descriptors, NULL, NULL, timeout);
|
select( highest_fd+1 , &descriptors, NULL, NULL, timeout);
|
||||||
|
|
||||||
// process data sources
|
// process data sources very carefully
|
||||||
data_source_t *next;
|
// bt_control.close() triggered from a client can remove a different data source
|
||||||
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
|
// printf("posix_execute: before ds check\n");
|
||||||
|
data_sources_modified = 0;
|
||||||
|
for (ds = (data_source_t *) data_sources; !data_sources_modified && ds != NULL; ds = (data_source_t *) ds->item.next){
|
||||||
|
// printf("posix_execute: check %x with fd %u\n", (int) ds, ds->fd);
|
||||||
if (FD_ISSET(ds->fd, &descriptors)) {
|
if (FD_ISSET(ds->fd, &descriptors)) {
|
||||||
|
// printf("posix_execute: process %x with fd %u\n", (int) ds, ds->fd);
|
||||||
ds->process(ds);
|
ds->process(ds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// printf("posix_execute: after ds check\n");
|
||||||
|
|
||||||
// process timers
|
// process timers
|
||||||
// pre: 0 <= tv_usec < 1000000
|
// pre: 0 <= tv_usec < 1000000
|
||||||
@ -157,6 +174,9 @@ void posix_execute() {
|
|||||||
ts = (timer_source_t *) timers;
|
ts = (timer_source_t *) timers;
|
||||||
if (ts->timeout.tv_sec > current_tv.tv_sec) break;
|
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;
|
if (ts->timeout.tv_sec == current_tv.tv_sec && ts->timeout.tv_usec > current_tv.tv_usec) break;
|
||||||
|
// printf("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);
|
run_loop_remove_timer(ts);
|
||||||
ts->process(ts);
|
ts->process(ts);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user