From 6511fa645e3af9b711486546f3ad0b5ace5da6d8 Mon Sep 17 00:00:00 2001 From: "matthias.ringwald" Date: Wed, 1 Jul 2009 21:55:08 +0000 Subject: [PATCH] started client/server implementation --- project.xcodeproj/project.pbxproj | 12 ++ src/btstack.c | 10 ++ src/btstack.h | 9 + src/daemon.c | 287 ++++++++++++++++++++++++++++++ src/daemon.h | 10 ++ src/main.c | 198 +-------------------- 6 files changed, 333 insertions(+), 193 deletions(-) create mode 100644 src/btstack.c create mode 100644 src/btstack.h create mode 100644 src/daemon.c create mode 100644 src/daemon.h diff --git a/project.xcodeproj/project.pbxproj b/project.xcodeproj/project.pbxproj index 1709cdb0d..74bf92eed 100644 --- a/project.xcodeproj/project.pbxproj +++ b/project.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ 9C7ECB840FCC85650085DAC5 /* bt_control_iphone.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7ECB820FCC85650085DAC5 /* bt_control_iphone.c */; }; 9C7ECBB50FCC95DD0085DAC5 /* hci_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7ECBB40FCC95DD0085DAC5 /* hci_dump.c */; }; 9C88500E0FBF6702004980E4 /* l2cap.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C88500C0FBF6702004980E4 /* l2cap.c */; }; + 9CC813A20FFC0774002816F9 /* btstack.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A10FFC0774002816F9 /* btstack.c */; }; + 9CC813A50FFC0A51002816F9 /* daemon.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A40FFC0A51002816F9 /* daemon.c */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -49,6 +51,10 @@ 9C88500C0FBF6702004980E4 /* l2cap.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = l2cap.c; path = src/l2cap.c; sourceTree = ""; }; 9C88500D0FBF6702004980E4 /* l2cap.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = l2cap.h; path = src/l2cap.h; sourceTree = ""; }; 9CA3C0900FB8B3C4005F48DE /* TODO.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = TODO.txt; sourceTree = ""; }; + 9CC813A00FFC0774002816F9 /* btstack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = btstack.h; path = src/btstack.h; sourceTree = ""; }; + 9CC813A10FFC0774002816F9 /* btstack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = btstack.c; path = src/btstack.c; sourceTree = ""; }; + 9CC813A30FFC0A51002816F9 /* daemon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = daemon.h; path = src/daemon.h; sourceTree = ""; }; + 9CC813A40FFC0A51002816F9 /* daemon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = daemon.c; path = src/daemon.c; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -79,6 +85,10 @@ 9C7ECB810FCC85650085DAC5 /* bt_control.h */, 9C7ECB820FCC85650085DAC5 /* bt_control_iphone.c */, 9C7ECB830FCC85650085DAC5 /* bt_control_iphone.h */, + 9CC813A00FFC0774002816F9 /* btstack.h */, + 9CC813A10FFC0774002816F9 /* btstack.c */, + 9CC813A30FFC0A51002816F9 /* daemon.h */, + 9CC813A40FFC0A51002816F9 /* daemon.c */, 9C46FC350FA906F700ABEF05 /* hci.h */, 9C46FC340FA906F700ABEF05 /* hci.c */, 9C46FC380FA906F700ABEF05 /* hci_transport.h */, @@ -164,6 +174,8 @@ 9C7ECBB50FCC95DD0085DAC5 /* hci_dump.c in Sources */, 9C1F0E9A0FDAE023008F472F /* run_loop.c in Sources */, 9C1F0F340FDB024B008F472F /* socket_server.c in Sources */, + 9CC813A20FFC0774002816F9 /* btstack.c in Sources */, + 9CC813A50FFC0A51002816F9 /* daemon.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/btstack.c b/src/btstack.c new file mode 100644 index 000000000..fa421266e --- /dev/null +++ b/src/btstack.c @@ -0,0 +1,10 @@ +/* + * btstack.c + * + * Created by Matthias Ringwald on 7/1/09. + * + * BTstack client API + */ + +#include "btstack.h" + diff --git a/src/btstack.h b/src/btstack.h new file mode 100644 index 000000000..b736d91b6 --- /dev/null +++ b/src/btstack.h @@ -0,0 +1,9 @@ +/* + * btstack.h + * + * Created by Matthias Ringwald on 7/1/09. + * + * BTstack client API + * + */ + diff --git a/src/daemon.c b/src/daemon.c new file mode 100644 index 000000000..eab5c2066 --- /dev/null +++ b/src/daemon.c @@ -0,0 +1,287 @@ +/* + * daemon.c + * + * Created by Matthias Ringwald on 7/1/09. + * + * BTstack background daemon + * + */ + +#include "daemon.h" + +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_2_0 +#define __IPHONE__ +#endif +#endif + +#include "hci.h" +#include "hci_transport_h4.h" +#include "hci_dump.h" +#include "bt_control_iphone.h" + +#include "l2cap.h" + +#include "run_loop.h" +#include "socket_server.h" +#include "daemon.h" + + +hci_con_handle_t con_handle_out = 0; +hci_con_handle_t con_handle_in = 0; +uint16_t dest_cid; + +#define BT_HID +// #define POWER_CYCLE_TEST +// #define MITM + + +void event_handler(uint8_t *packet, int size){ + // printf("Event type: %x, opcode: %x, other %x\n", packet[0], packet[3] | packet[4] << 8); + +#if defined(BT_HID) || defined(MITM) + bd_addr_t addr = {0x00, 0x03, 0xc9, 0x3d, 0x77, 0x43 }; // Think Outside Keyboard + + // bt stack activated, get started + if (packet[0] == BTSTACK_EVENT_HCI_WORKING) { + hci_send_cmd(&hci_write_class_of_device, 0x7A020C); // used on iPhone + } + + if ( COMMAND_COMPLETE_EVENT(packet, hci_write_class_of_device) ) { + hci_send_cmd(&hci_write_local_name, "BT in the Middle"); + } + + if ( COMMAND_COMPLETE_EVENT(packet, hci_write_local_name) ) { +#if 1 + hci_send_cmd(&hci_write_authentication_enable, 1); + } + if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) { +#endif +#if 0 + hci_send_cmd(&hci_write_inquiry_mode, 2); + } + if ( COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) { +#endif +#if 0 + hci_send_cmd(&hci_set_event_mask, 0xffffffff, 0x1fffffff); + } + + uint8_t eir[] = { + 0x0d, 0x09, 0x4d, 0x69, 0x6c, 0x61, 0x73, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x0f, 0x02, + 0x00, 0x12, 0x1f, 0x11, 0x07, 0x11, 0x2f, 0x11, 0x0a, 0x11, 0x16, 0x11, 0x15, 0x11, 0x27, 0xff, + 0x00, 0x4c, 0x02, 0x24, 0x02, 0x86, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + if ( COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask) ) { +#endif +#if 0 + hci_send_cmd(&hci_write_extended_inquiry_response, 0, eir); + } + if ( COMMAND_COMPLETE_EVENT(packet, hci_write_extended_inquiry_response) ) { +#endif +#if 0 + hci_send_cmd(&hci_write_simple_pairing_mode, 1); + } + if ( COMMAND_COMPLETE_EVENT(packet, hci_write_simple_pairing_mode) ) { +#endif +#if 0 + hci_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, 15, 0); + } + if (packet[0] == HCI_EVENT_INQUIRY_COMPLETE) +#endif +#if 1 + hci_send_cmd(&hci_create_connection, &addr, 0x18, 0, 0, 0, 0); +#endif + } + if (packet[0] == HCI_EVENT_CONNECTION_REQUEST){ + bt_flip_addr(addr, &packet[2]); + hci_send_cmd(&hci_accept_connection_request, &addr, 1); + } + + if (packet[0] == HCI_EVENT_PIN_CODE_REQUEST){ + printf("Please enter PIN 1234 on remote device\n"); + } + + // connection established -> start L2CAP conection + if (packet[0] == HCI_EVENT_CONNECTION_COMPLETE){ + if (packet[2] == 0){ + // get new connection handle + if (! con_handle_out) { + con_handle_out = READ_BT_16(packet, 3); + } else { + con_handle_in = READ_BT_16(packet, 3); + } +#ifndef MITM + // request l2cap connection + printf("> CONNECTION REQUEST\n"); + l2cap_send_signaling_packet(con_handle_out, CONNECTION_REQUEST, sig_seq_nr++, 0x13, local_cid); +#else + printf("Connected to target device, please start!\n"); +#endif + + } + } +#endif + +#ifdef POWER_CYCLE_TEST + if (packet[0] == BTSTACK_EVENT_HCI_WORKING) { + hci_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, 10, 0); + } + if (packet[0] == HCI_EVENT_INQUIRY_COMPLETE){ + // power cycle + hci_power_control( HCI_POWER_OFF ); + // + printf ("Power off!\n"); + sleep(10); + printf ("Restart!\n"); + hci_power_control( HCI_POWER_ON ); + } +#endif +} + +void acl_handler(uint8_t *packet, int size){ + +#ifdef MITM + // forward packet on "other" connection + hci_con_handle_t incoming_hdl = READ_BT_16(packet, 0) & 0xfff; + hci_con_handle_t outgoing_hdl = 0; +#if 0 + if (incoming_hdl == con_handle_in){ + outgoing_hdl = con_handle_out; + } else if (incoming_hdl == con_handle_out){ + outgoing_hdl = con_handle_in; + } else { + printf("Incoming acl packet on handle %u\n!", incoming_hdl); + } +#else + outgoing_hdl = incoming_hdl; +#endif + if (outgoing_hdl){ + bt_store_16( packet, 0, (READ_BT_16(packet, 0) & 0xf000) | outgoing_hdl); + hci_send_acl_packet(packet, size); + } + +#else + uint16_t source_cid; + uint16_t result; + uint8_t config_options[] = { 1, 2, 150, 0}; // mtu = 48 + // connection response + if (packet[8] == CONNECTION_RESPONSE){ + dest_cid = READ_BT_16(packet, 12); + source_cid = READ_BT_16(packet, 14); + result = READ_BT_16(packet, 16); + uint16_t status = READ_BT_16(packet, 18); + printf("< CONNECTION_RESPONSE: id %u, dest cid %u, src cid %u, result %u, status %u\n", packet[9], dest_cid, source_cid, result, status); + if (result == 0){ + printf("> CONFIGURE_REQUEST: id %u\n", sig_seq_nr); + l2cap_send_signaling_packet(con_handle_out, CONFIGURE_REQUEST, sig_seq_nr++, dest_cid, 0, 4, &config_options); + } + } + else if (packet[8] == CONFIGURE_RESPONSE){ + source_cid = READ_BT_16(packet, 12); + uint16_t flags = READ_BT_16(packet, 14); + result = READ_BT_16(packet, 16); + printf("< CONFIGURE_RESPONSE: id %u, src cid %u, flags %u, result %u!!!\n", packet[9], source_cid, flags, result); + hexdump(&packet[18], size-18); + } + else if (packet[8] == CONFIGURE_REQUEST){ + printf("< CONFIGURE_REQUEST: id %u\n", packet[9]); + hexdump(&packet[16], size-16); + printf("> CONFIGURE_RESPONSE: id %u\n", packet[9]); + l2cap_send_signaling_packet(con_handle_out, CONFIGURE_RESPONSE, packet[9], local_cid, 0, 0, size - 16, &packet[16]); + } + else { + printf("Unknown ACL ^^^ \n"); + } +#endif +} + +static hci_transport_t * transport; +static hci_uart_config_t config; + +int daemon_main (int argc, const char * argv[]){ + +#if 0 + pid_t parent_pid = fork(); + + if (parent_pid > 0) { + // parent returns + return 0; + } +#endif + + bt_control_t * control = NULL; + +#ifndef __IPHONE__ + // + if (argc <= 1){ + printf("HCI Daemon tester. Specify device name for Ericsson ROK 101 007\n"); + return 1; + } + + // Ancient Ericsson ROK 101 007 (ca. 2001) + config.device_name = argv[1]; + config.baudrate = 57600; + config.flowcontrol = 1; +#else + // iPhone + config.device_name = "/dev/tty.bluetooth"; + config.baudrate = 115200; + // config.baudrate = 230400; // ok + // config.baudrate = 460800; // ok + // config.baudrate = 921600; // ok + // config.baudrate = 2400000; // does not work (yet) + config.flowcontrol = 1; + control = &bt_control_iphone; +#endif + + // use logger: format HCI_DUMP_PACKETLOGGER or HCI_DUMP_BLUEZ + hci_dump_open("/tmp/hci_dump.pklg", HCI_DUMP_PACKETLOGGER); + + // H4 UART + transport = hci_transport_h4_instance(); + + // init HCI + hci_init(transport, &config, control); + + // init L2CAP + l2cap_init(); + + // + // register callbacks + // + hci_register_event_packet_handler(&event_handler); + hci_register_acl_packet_handler(&acl_handler); + + // turn on + hci_power_control(HCI_POWER_ON); + + // configure run loop + run_loop_add( (data_source_t *) transport); + + // create server + data_source_t *socket_server = socket_server_create_tcp(1919); + run_loop_add( socket_server ); + + // go! + run_loop_execute(); + + return 0; +} \ No newline at end of file diff --git a/src/daemon.h b/src/daemon.h new file mode 100644 index 000000000..6e819bbe0 --- /dev/null +++ b/src/daemon.h @@ -0,0 +1,10 @@ +/* + * daemon.h + * + * Created by Matthias Ringwald on 7/1/09. + * + * BTstack background daemon + * + */ + +int daemon_main (int argc, const char * argv[]); diff --git a/src/main.c b/src/main.c index 56fd296fc..b4e49d700 100644 --- a/src/main.c +++ b/src/main.c @@ -8,204 +8,16 @@ #include #include +#include #include -#include "hci.h" -#include "hci_transport_h4.h" -#include "hci_dump.h" -#include "bt_control_iphone.h" - -#include "l2cap.h" - -#include "run_loop.h" -#include "socket_server.h" - -static hci_transport_t * transport; -static hci_uart_config_t config; - -hci_con_handle_t con_handle_out = 0; -hci_con_handle_t con_handle_in = 0; -uint16_t dest_cid; - -// #define BT_HID -// #define POWER_CYCLE_TEST -#define MITM - -void event_handler(uint8_t *packet, int size){ - // printf("Event type: %x, opcode: %x, other %x\n", packet[0], packet[3] | packet[4] << 8); - -#if defined(BT_HID) || defined(MITM) - bd_addr_t addr = {0x00, 0x03, 0xc9, 0x3d, 0x77, 0x43 }; // Think Outside Keyboard - // bd_addr_t addr = { 0x00, 0x16, 0xcb, 0x09, 0x94, 0xa9}; // MacBook Pro - - // bt stack activated, set authentication enabled - if (packet[0] == BTSTACK_EVENT_HCI_WORKING) { -#if 0 - hci_send_cmd(&hci_write_authentication_enable, 1); - // hci_send_cmd(&hci_host_buffer_size, 400, 255, 1, 0, 0); - } - - if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) { - // hci_write_authentication_enable done, send connect -#endif - hci_send_cmd(&hci_create_connection, &addr, 0x18, 0, 0, 0, 0); - } - - if (packet[0] == HCI_EVENT_CONNECTION_REQUEST){ - bt_flip_addr(addr, &packet[2]); - hci_send_cmd(&hci_accept_connection_request, &addr, 1); - } - - if (packet[0] == HCI_EVENT_PIN_CODE_REQUEST){ - printf("Please enter PIN 1234 on remote device\n"); - } - - // connection established -> start L2CAP conection - if (packet[0] == HCI_EVENT_CONNECTION_COMPLETE){ - if (packet[2] == 0){ - // get new connection handle - if (! con_handle_out) { - con_handle_out = READ_BT_16(packet, 3); - } else { - con_handle_in = READ_BT_16(packet, 3); - } -#ifndef MITM - // request l2cap connection - printf("> CONNECTION REQUEST\n"); - l2cap_send_signaling_packet(con_handle_out, CONNECTION_REQUEST, sig_seq_nr++, 0x13, local_cid); -#else - printf("Connected to target device, please start!\n"); -#endif - - } - } -#endif - -#ifdef POWER_CYCLE_TEST - if (packet[0] == BTSTACK_EVENT_HCI_WORKING) { - hci_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, 10, 0); - } - if (packet[0] == HCI_EVENT_INQUIRY_COMPLETE){ - // power cycle - hci_power_control( HCI_POWER_OFF ); - // - printf ("Power off!\n"); - sleep(10); - printf ("Restart!\n"); - hci_power_control( HCI_POWER_ON ); - } -#endif -} - -void acl_handler(uint8_t *packet, int size){ - -#ifdef MITM - // forward packet on "other" connection - hci_con_handle_t incoming_hdl = READ_BT_16(packet, 0) & 0xfff; - hci_con_handle_t outgoing_hdl = 0; - if (incoming_hdl == con_handle_in){ - outgoing_hdl = con_handle_out; - } else if (incoming_hdl == con_handle_out){ - outgoing_hdl = con_handle_in; - } else { - printf("Incoming acl packet on handle %u\n!", incoming_hdl); - } - if (outgoing_hdl){ - bt_store_16( packet, 0, (READ_BT_16(packet, 0) & 0xf000) | outgoing_hdl); - hci_send_acl_packet(packet, size); - } - -#else - uint16_t source_cid; - uint16_t result; - uint8_t config_options[] = { 1, 2, 150, 0}; // mtu = 48 - // connection response - if (packet[8] == CONNECTION_RESPONSE){ - dest_cid = READ_BT_16(packet, 12); - source_cid = READ_BT_16(packet, 14); - result = READ_BT_16(packet, 16); - uint16_t status = READ_BT_16(packet, 18); - printf("< CONNECTION_RESPONSE: id %u, dest cid %u, src cid %u, result %u, status %u\n", packet[9], dest_cid, source_cid, result, status); - if (result == 0){ - printf("> CONFIGURE_REQUEST: id %u\n", sig_seq_nr); - l2cap_send_signaling_packet(con_handle_out, CONFIGURE_REQUEST, sig_seq_nr++, dest_cid, 0, 4, &config_options); - } - } - else if (packet[8] == CONFIGURE_RESPONSE){ - source_cid = READ_BT_16(packet, 12); - uint16_t flags = READ_BT_16(packet, 14); - result = READ_BT_16(packet, 16); - printf("< CONFIGURE_RESPONSE: id %u, src cid %u, flags %u, result %u!!!\n", packet[9], source_cid, flags, result); - hexdump(&packet[18], size-18); - } - else if (packet[8] == CONFIGURE_REQUEST){ - printf("< CONFIGURE_REQUEST: id %u\n", packet[9]); - hexdump(&packet[16], size-16); - printf("> CONFIGURE_RESPONSE: id %u\n", packet[9]); - l2cap_send_signaling_packet(con_handle_out, CONFIGURE_RESPONSE, packet[9], local_cid, 0, 0, size - 16, &packet[16]); - } - else { - printf("Unknown ACL ^^^ \n"); - } -#endif -} +#include "daemon.h" int main (int argc, const char * argv[]) { - - bt_control_t * control = NULL; - -#if 1 - // - if (argc <= 1){ - printf("HCI Daemon tester. Specify device name for Ericsson ROK 101 007\n"); - exit(1); - } - // Ancient Ericsson ROK 101 007 (ca. 2001) - config.device_name = argv[1]; - config.baudrate = 57600; - config.flowcontrol = 1; -#else - // iPhone - config.device_name = "/dev/tty.bluetooth"; - config.baudrate = 115200; -// config.baudrate = 230400; // ok -// config.baudrate = 460800; // ok -// config.baudrate = 921600; // ok -// config.baudrate = 2400000; // does not work (yet) - config.flowcontrol = 1; - control = &bt_control_iphone; -#endif - - // use logger: format HCI_DUMP_PACKETLOGGER or HCI_DUMP_BLUEZ - hci_dump_open("/tmp/hci_dump.pklg", HCI_DUMP_PACKETLOGGER); - - // H4 UART - transport = hci_transport_h4_instance(); + // start daemon + daemon_main(argc, argv); - // init HCI - hci_init(transport, &config, control); - - // - // register callbacks - // - hci_register_event_packet_handler(&event_handler); - hci_register_acl_packet_handler(&acl_handler); - - // init L2CAP - l2cap_init(); - - // turn on - hci_power_control(HCI_POWER_ON); - - // create server - data_source_t *socket_server = socket_server_create_tcp(1919); - - // configure run loop - run_loop_add( (data_source_t *) transport); - run_loop_add( socket_server ); - - // go! - run_loop_execute(); + // daemon does not returs so far return 0; }