trace Bluetooth status in daemon

This commit is contained in:
matthias.ringwald 2009-08-15 21:31:23 +00:00
parent 901368b879
commit 43bfb1bd9c
10 changed files with 91 additions and 11 deletions

View File

@ -3,11 +3,9 @@
Last milestone reached: Restart client app without restarting BTdaemon possible
NEXT:
- client/server part using unix domain sockets (portable and fast)
- iPhone status icon support
- create BTstack icon. Flipped B in red, or blue on orange
- bt_control_iphone.c -> bt_control_iphone.m // or objcSendMsg
- call SpringBoard on/off BT
- client/server part using unix domain sockets (portable and fast)
- automatic start/stop of BTdaemon
- start BTdaemon by client lib
- e.g. use popen and wait for initial "I'm ready" message

View File

@ -9,6 +9,7 @@ AC_ARG_WITH(hci-transport, [AS_HELP_STRING([--with-hci-transport=transportType],
AC_ARG_WITH(uart-device, [AS_HELP_STRING([--with-uart-device=uartDevice], [Specify BT UART device to use])], UART_DEVICE=$withval, UART_DEVICE="DEFAULT")
AC_ARG_WITH(uart-speed, [AS_HELP_STRING([--with-uart-speed=uartSpeed], [Specify BT UART speed to use])], UART_SPEED=$withval, UART_SPEED="115200")
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_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(product-id, [AS_HELP_STRING([--with-product-id=productID], [Specify USB BT Dongle productID])], USB_PRODUCT_ID=$withval, USB_PRODUCT_ID="")
@ -21,6 +22,7 @@ AC_CANONICAL_HOST
# Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_OBJC
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
@ -90,6 +92,10 @@ if test "x$target" = xiphone; then
USE_BLUETOOL="yes"
echo "USE_BLUETOOL=$USE_BLUETOOL"
fi
if test "x$USE_SPRINGBOARD" = xDEFAULT ; then
USE_SPRINGBOARD="yes"
echo "USE_SPRINGBOARD=$USE_SPRINGBOARD"
fi
else
if test "x$UART_DEVICE" = xDEFAULT ; then
UART_DEVICE=/dev/ttyS0
@ -121,6 +127,9 @@ else
if test "x$USE_BLUETOOL" = xyes; then
echo "#define USE_BLUETOOL" >> config.h
fi
if test "x$USE_SPRINGBOARD" = xyes; then
echo "#define USE_SPRINGBOARD" >> config.h
fi
fi
AC_SUBST(IPHONE_IP)

View File

@ -17,6 +17,7 @@
9C1F0E9A0FDAE023008F472F /* run_loop.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C1F0E980FDAE023008F472F /* run_loop.c */; };
9C2071F310014D3200A07EA4 /* hci_transport_usb.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */; };
9C46FC3A0FA906F700ABEF05 /* hci_transport_h4.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C46FC360FA906F700ABEF05 /* hci_transport_h4.c */; };
9C6459E01037554B0081A00B /* platform_iphone.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6459DF1037554B0081A00B /* platform_iphone.m */; };
9C7B5AC0100BD3340065D87E /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7B5ABF100BD3340065D87E /* linked_list.c */; };
9C7B5D01100FC9AE0065D87E /* btstack.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A10FFC0774002816F9 /* btstack.c */; };
9C7B5D03100FC9BB0065D87E /* test.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7B5B7E100D04450065D87E /* test.c */; };
@ -60,6 +61,8 @@
9C46FC360FA906F700ABEF05 /* hci_transport_h4.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = hci_transport_h4.c; path = src/hci_transport_h4.c; sourceTree = "<group>"; };
9C46FC370FA906F700ABEF05 /* hci_transport_h4.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = hci_transport_h4.h; path = src/hci_transport_h4.h; sourceTree = "<group>"; };
9C46FC380FA906F700ABEF05 /* hci_transport.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = hci_transport.h; path = src/hci_transport.h; sourceTree = "<group>"; };
9C6459DE1037554B0081A00B /* platform_iphone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform_iphone.h; path = src/platform_iphone.h; sourceTree = "<group>"; };
9C6459DF1037554B0081A00B /* platform_iphone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = platform_iphone.m; path = src/platform_iphone.m; sourceTree = "<group>"; };
9C7B5ABE100BD3340065D87E /* linked_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = linked_list.h; path = src/linked_list.h; sourceTree = "<group>"; };
9C7B5ABF100BD3340065D87E /* linked_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = linked_list.c; path = src/linked_list.c; sourceTree = "<group>"; };
9C7B5B7E100D04450065D87E /* test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = test.c; path = example/test.c; sourceTree = "<group>"; };
@ -142,6 +145,8 @@
9C00F7311017ACC3008DAB17 /* socket_connection.h */,
9C00F86210191097008DAB17 /* utils.c */,
9C00F86310191097008DAB17 /* utils.h */,
9C6459DE1037554B0081A00B /* platform_iphone.h */,
9C6459DF1037554B0081A00B /* platform_iphone.m */,
);
name = Source;
sourceTree = "<group>";
@ -245,6 +250,7 @@
9C00F86510191097008DAB17 /* utils.c in Sources */,
9C00F87410191130008DAB17 /* l2cap_signaling.c in Sources */,
9CCE6CEA1025BD0000FCE9F4 /* hci.c in Sources */,
9C6459E01037554B0081A00B /* platform_iphone.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -15,6 +15,7 @@ BTdaemon_SOURCES = \
l2cap.c \
l2cap_signaling.c \
linked_list.c \
platform_iphone.m \
run_loop.c \
socket_connection.c \
utils.c
@ -31,6 +32,7 @@ include_HEADERS = \
linked_list.h \
l2cap.h \
l2cap_signaling.h \
platform_iphone.h \
run_loop.h \
socket_connection.h \
utils.h

View File

@ -42,8 +42,13 @@ static hci_uart_config_t config;
static timer_t timeout;
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state){
printf("Bluetooth status: %u\n", state);
};
static void (*bluetooth_status_handler)(BLUETOOTH_STATE state) = dummy_bluetooth_status_handler;
static void daemon_no_connections_timeout(){
printf("No connection for %u secondes -> POWER OFF\n", DAEMON_NO_CONNECTION_TIMEOUT);
printf("No connection for %u seconds -> POWER OFF\n", DAEMON_NO_CONNECTION_TIMEOUT);
hci_power_control( HCI_POWER_OFF);
}
@ -111,13 +116,37 @@ static int daemon_client_handler(connection_t *connection, uint16_t packet_type,
default:
break;
}
// only one event so far: client connection died
break;
}
return 0;
}
void daemon_sigint_handler(int param){
static void daemon_event_handler(uint8_t *packet, uint16_t size){
// handle state event
if (packet[0] == HCI_EVENT_BTSTACK_WORKING){
bluetooth_status_handler(BLUETOOTH_ON);
}
if (packet[0] == HCI_EVENT_BTSTACK_STATE){
if (packet[2] == HCI_STATE_WORKING) {
bluetooth_status_handler(BLUETOOTH_ON);
}
if (packet[2] == HCI_STATE_OFF) {
bluetooth_status_handler(BLUETOOTH_OFF);
}
}
if (packet[0] == HCI_EVENT_NR_CONNECTIONS_CHANGED){
if (packet[2]) {
bluetooth_status_handler(BLUETOOTH_ACTIVE);
} else {
bluetooth_status_handler(BLUETOOTH_ON);
}
}
// forward event to clients
socket_connection_send_packet_all(HCI_EVENT_PACKET, 0, packet, size);
}
static void daemon_sigint_handler(int param){
printf(" <= SIGINT received, shutting down..\n");
hci_power_control( HCI_POWER_OFF);
printf("Good bye, see you.\n");
@ -142,7 +171,11 @@ int main (int argc, const char * argv[]){
#ifdef USE_BLUETOOL
control = &bt_control_iphone;
#endif
#ifdef USE_SPRINGBOARD
bluetooth_status_handler = platform_iphone_status_handler
#endif
// @TODO: allow configuration per HCI CMD
// use logger: format HCI_DUMP_PACKETLOGGER, HCI_DUMP_BLUEZ or HCI_DUMP_STDOUT
@ -154,7 +187,7 @@ int main (int argc, const char * argv[]){
// init L2CAP
l2cap_init();
l2cap_register_event_packet_handler(daemon_event_handler);
timeout.process = daemon_no_connections_timeout;
// @TODO: make choice of socket server configurable (TCP and/or Unix Domain Socket)

View File

@ -94,6 +94,15 @@ static hci_connection_t * connection_for_address(bd_addr_t address){
return NULL;
}
/**
* count connections
*/
static int nr_hci_connections(){
int count;
linked_item_t *it;
for (it = (linked_item_t *) hci_stack.connections; it ; it = it->next, count++);
return count;
}
/**
* Dummy handler called by HCI
@ -159,6 +168,8 @@ static void event_handler(uint8_t *packet, int size){
printf("New connection: handle %u, ", conn->con_handle);
print_bd_addr( conn->address );
printf("\n");
hci_emit_nr_connections_changed();
}
}
}
@ -174,6 +185,7 @@ static void event_handler(uint8_t *packet, int size){
run_loop_remove_timer(&conn->timeout);
linked_list_remove(&hci_stack.connections, (linked_item_t *) conn);
free( conn );
hci_emit_nr_connections_changed();
}
}
}
@ -273,6 +285,9 @@ int hci_power_control(HCI_POWER_MODE power_mode){
// power off
hci_stack.control->off(hci_stack.config);
// we're off now
hci_stack.state = HCI_STATE_OFF;
}
hci_emit_state();
@ -411,3 +426,13 @@ void hci_emit_l2cap_check_timeout(hci_connection_t *conn){
hci_dump_packet( HCI_EVENT_PACKET, 0, event, len);
hci_stack.event_packet_handler(event, len);
}
void hci_emit_nr_connections_changed(){
uint8_t len = 3;
uint8_t event[len];
event[0] = HCI_EVENT_NR_CONNECTIONS_CHANGED;
event[1] = 1;
event[2] = nr_hci_connections();
hci_dump_packet( HCI_EVENT_PACKET, 0, event, len);
hci_stack.event_packet_handler(event, len);
}

View File

@ -33,6 +33,12 @@ typedef enum {
SENT_DISCONNECT
} CONNECTION_STATE;
typedef enum {
BLUETOOTH_OFF = 1,
BLUETOOTH_ON,
BLUETOOTH_ACTIVE
} BLUETOOTH_STATE;
typedef struct {
// linked list - assert: first field
linked_item_t item;
@ -115,3 +121,4 @@ int hci_send_acl_packet(uint8_t *packet, int size);
void hci_emit_state();
void hci_emit_connection_complete(hci_connection_t *conn);
void hci_emit_l2cap_check_timeout(hci_connection_t *conn);
void hci_emit_nr_connections_changed();

View File

@ -89,6 +89,8 @@
// data: event(8), len(8), handle(16)
#define HCI_EVENT_L2CAP_TIMEOUT_CHECK 0x84
// data: event(8), len(8), nr hci connections
#define HCI_EVENT_NR_CONNECTIONS_CHANGED 0x85
// data: event(8)
#define DAEMON_CONNECTION_CLOSED 0xc0

View File

@ -158,9 +158,6 @@ void l2cap_event_handler( uint8_t *packet, uint16_t size ){
// forward to higher layers
(*event_packet_handler)(packet, size);
// forward event to clients
socket_connection_send_packet_all(HCI_EVENT_PACKET, 0, packet, size);
}
void l2cap_signaling_handler(l2cap_channel_t *channel, uint8_t *packet, uint16_t size){

View File

@ -48,6 +48,7 @@ typedef struct {
} l2cap_service_t;
void l2cap_init();
void l2cap_register_event_packet_handler(void (*handler)(uint8_t *packet, uint16_t size));
void l2cap_create_channel_internal(connection_t * connection, bd_addr_t address, uint16_t psm);
void l2cap_disconnect_internal(uint16_t source_cid, uint8_t reason);
void l2cap_send_internal(uint16_t source_cid, uint8_t *data, uint16_t len);