From 7812a343cf26ff201e0295df659d885d0d741382 Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Fri, 2 Mar 2018 22:00:24 -0500 Subject: [PATCH 1/2] Allow module to pair properly with Win10 by providing ability to handle BT2.1 Secure Simple Pairing. Also (maybe?) Fixes pfalcon/blutunode#1 --- btnode.c | 34 ++++++++++++++++++++++++++++++---- btnode.h | 2 ++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/btnode.c b/btnode.c index bbe0bc6..7274237 100644 --- a/btnode.c +++ b/btnode.c @@ -1,5 +1,6 @@ /* * BluTuNode - Bluetooth sensor/actuator node software + * Copyright (c) 2018 Jacob Schmidt * Copyright (c) 2011-2012 Paul Sokolovsky * * BtNode is free software: you can redistribute it and/or modify @@ -20,6 +21,8 @@ void command_software_version(Task task); +static BtNodeCommandTask app; + static int input_echo = 1; void sink_write(Sink sink, const char *buf, int size) @@ -89,21 +92,41 @@ static void task_handler(Task task, MessageId msg_id, Message msg) case CL_INIT_CFM: ConnectionRfcommAllocateChannel(task); break; - case CL_RFCOMM_REGISTER_CFM: - ConnectionWriteScanEnable(hci_scan_enable_inq_and_page); - break; case CL_SM_PIN_CODE_IND: { CAST_TYPED_MSG(CL_SM_PIN_CODE_IND, tmsg); ConnectionSmPinCodeResponse(&tmsg->bd_addr, 4, (uint8*)"1234"); } break; + + + /* Handle BT2.1 Secure Simple Pairing */ + case CL_SM_REMOTE_IO_CAPABILITY_IND: + { + CAST_TYPED_MSG(CL_SM_REMOTE_IO_CAPABILITY_IND, tmsg); + app.dev_a.lap = tmsg->bd_addr.lap; + app.dev_a.uap = tmsg->bd_addr.uap; + app.dev_a.nap = tmsg->bd_addr.nap; + } + break; + case CL_SM_IO_CAPABILITY_REQ_IND: + { + ConnectionSmIoCapabilityResponse(&app.dev_a, cl_sm_io_cap_no_input_no_output, FALSE, TRUE, FALSE, 0, 0); + } + break; + case CL_SM_AUTHORISE_IND: { CAST_TYPED_MSG(CL_SM_AUTHORISE_IND, tmsg); ConnectionSmAuthoriseResponse(&tmsg->bd_addr, tmsg->protocol_id, tmsg->channel, tmsg->incoming, TRUE); } break; + + + /* RFCOMM setup */ + case CL_RFCOMM_REGISTER_CFM: + ConnectionWriteScanEnable(hci_scan_enable_inq_and_page); + break; case CL_RFCOMM_CONNECT_IND: { CAST_TYPED_MSG(CL_RFCOMM_CONNECT_IND, tmsg); @@ -117,6 +140,9 @@ static void task_handler(Task task, MessageId msg_id, Message msg) command_software_version(task); } break; + + + /* Handle data messages */ case MESSAGE_MORE_DATA: { MessageMoreData *tmsg = (MessageMoreData*)msg; @@ -162,9 +188,9 @@ static void task_handler(Task task, MessageId msg_id, Message msg) int main(void) { - static BtNodeCommandTask app; app.task.handler = task_handler; app.buf_ptr = app.input_buf; + ConnectionSmDeleteAllAuthDevices(0); /* Our module will not remember pairing */ MessagePioTask(&app.task); ConnectionInit(&app.task); diff --git a/btnode.h b/btnode.h index 4ff2c98..fa21d5d 100644 --- a/btnode.h +++ b/btnode.h @@ -1,5 +1,6 @@ /* * BluTuNode - Bluetooth sensor/actuator node software + * Copyright (c) 2018 Jacob Schmidt * Copyright (c) 2011-2012 Paul Sokolovsky * * BtNode is free software: you can redistribute it and/or modify @@ -47,6 +48,7 @@ typedef struct BtNodeCommandTask { char *buf_ptr; struct InputSource *poll_source; int poll_period; + bdaddr dev_a; } BtNodeCommandTask; /* Periodical poll message */ From 7910c300af3483263c93c51fed03b62d85424f24 Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Fri, 2 Mar 2018 23:37:06 -0500 Subject: [PATCH 2/2] Registered SDP record so that Windows can find SPP service so that Blutunode can be used from Windows. --- btnode.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- btnode.h | 1 + 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/btnode.c b/btnode.c index 7274237..f7068b2 100644 --- a/btnode.c +++ b/btnode.c @@ -17,12 +17,35 @@ * along with this software. If not, see . */ +#include #include "btnode.h" void command_software_version(Task task); static BtNodeCommandTask app; +static const unsigned char spp_service_record [] = +{ + 0x09, 0x00, 0x01, /* ServiceClassIDList(0x0001) */ + 0x35, 0x03, /* DataElSeq 3 bytes */ + 0x19, 0x11, 0x01, /* UUID 0x1101 for Serial Port */ + 0x09, 0x00, 0x04, /* ProtocolDescriptorList(0x0004) */ + 0x35, 0x0C, /* DataElSeq 12 bytes */ + 0x35, 0x03, /* DataElSeq 3 bytes */ + 0x19, 0x01, 0x00, /* UUID L2CAP(0x0100) */ + 0x35, 0x05, /* DataElSeq 5 bytes */ + 0x19, 0x00, 0x03, /* UUID RFCOMM(0x0003) */ + 0x08, 0x00, /* uint8 0x00 <- Service Channel - to be over-written */ + 0x09, 0x00, 0x06, /* LanguageBaseAttributeIDList(0x0006) */ + 0x35, 0x09, /* DataElSeq 9 bytes */ + 0x09, 0x65, 0x6e, /* uint16 0x656e */ + 0x09, 0x00, 0x6a, /* uint16 0x006a */ + 0x09, 0x01, 0x00, /* uint16 0x0100 */ + 0x09, 0x01, 0x00, /* ServiceName(0x0100) = "Blutunode SPP" */ + 0x25, 0x0D, /* String length 13 */ + 'B', 'l', 'u', 't', 'u', 'n', 'o', 'd', 'e', ' ', 'S', 'P', 'P' +}; + static int input_echo = 1; void sink_write(Sink sink, const char *buf, int size) @@ -90,6 +113,7 @@ static void task_handler(Task task, MessageId msg_id, Message msg) switch (msg_id) { case CL_INIT_CFM: + ConnectionWriteClassOfDevice(0x001F00); ConnectionRfcommAllocateChannel(task); break; case CL_SM_PIN_CODE_IND: @@ -125,7 +149,24 @@ static void task_handler(Task task, MessageId msg_id, Message msg) /* RFCOMM setup */ case CL_RFCOMM_REGISTER_CFM: - ConnectionWriteScanEnable(hci_scan_enable_inq_and_page); + { + CAST_TYPED_MSG(CL_RFCOMM_REGISTER_CFM, tmsg); + + uint8 *service_record = 0; + uint16 len_sr = 0; + app.rfcomm_channel = tmsg->server_channel; + + len_sr = sizeof(spp_service_record); + service_record = (uint8*)PanicUnlessMalloc(len_sr); + memcpy(service_record, spp_service_record, len_sr); + + /* Update service record with the registered server channel (just a pointer dereference?) */ + /* SdpParseInsertRfcommServerChannel(len_sr, service_record, tmsg->server_channel); */ + service_record[24] = tmsg->server_channel; + + /* Register service record with BlueStack firmware. Don't free the memory! */ + ConnectionRegisterServiceRecord(task, len_sr, service_record); + } break; case CL_RFCOMM_CONNECT_IND: { @@ -140,6 +181,19 @@ static void task_handler(Task task, MessageId msg_id, Message msg) command_software_version(task); } break; + case CL_SDP_REGISTER_CFM: + { + /* Make device discoverable */ + ConnectionWriteScanEnable(hci_scan_enable_inq_and_page); + + /* Register SDP record. Linux can handle working at the RFCOMM level, but Windows depends + on having an SDP record that it can browse to determin if SPP is available */ + ConnectionSmRegisterIncomingService(protocol_rfcomm, app.rfcomm_channel, secl_none); + + /* Turn off security for SDP browsing */ + ConnectionSmSetSdpSecurityIn(TRUE); + } + break; /* Handle data messages */ diff --git a/btnode.h b/btnode.h index fa21d5d..ea15345 100644 --- a/btnode.h +++ b/btnode.h @@ -49,6 +49,7 @@ typedef struct BtNodeCommandTask { struct InputSource *poll_source; int poll_period; bdaddr dev_a; + uint8 rfcomm_channel; } BtNodeCommandTask; /* Periodical poll message */