mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-26 03:35:20 +00:00
ble client: connect functionality moved to hci
This commit is contained in:
parent
755c826fc1
commit
4f3229d8d2
@ -80,7 +80,7 @@ static void ble_packet_handler(void * connection, uint8_t packet_type, uint16_t
|
||||
|
||||
|
||||
void (*le_central_callback)(le_event_t * event);
|
||||
static void le_packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
// static void le_packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
|
||||
static void le_central_run();
|
||||
|
||||
@ -131,234 +131,9 @@ void le_central_register_packet_handler(void (*handler)(uint8_t packet_type, uin
|
||||
|
||||
|
||||
|
||||
static inline void send_le_central_connection_complete_event(le_central_t * peripheral, uint8_t type, uint8_t status){
|
||||
le_central_connection_complete_event_t event;
|
||||
event.type = type;
|
||||
event.device = peripheral;
|
||||
event.status = status;
|
||||
(*le_central_callback)((le_event_t*)&event);
|
||||
}
|
||||
|
||||
|
||||
static le_central_t * get_le_central_context_for_handle(uint16_t handle){
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) le_central_connections; it ; it = it->next){
|
||||
le_central_t * peripheral = (le_central_t *) it;
|
||||
if (peripheral->handle == handle){
|
||||
return peripheral;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static le_central_t * get_le_central_context_with_address(uint8_t addr_type, bd_addr_t addr){
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) le_central_connections; it ; it = it->next){
|
||||
le_central_t * peripheral = (le_central_t *) it;
|
||||
if (BD_ADDR_CMP(addr, peripheral->address) == 0 && peripheral->address_type == addr_type){
|
||||
return peripheral;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static le_central_t * get_le_central_context_with_state(le_central_state_t p_state){
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) le_central_connections; it ; it = it->next){
|
||||
le_central_t * peripheral = (le_central_t *) it;
|
||||
if (peripheral->le_central_state == p_state){
|
||||
return peripheral;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline le_central_t * get_le_central_w4_connect_cancelled(){
|
||||
return get_le_central_context_with_state(P_W4_CONNECT_CANCELLED);
|
||||
}
|
||||
|
||||
static inline le_central_t * get_le_central_w4_connected(){
|
||||
return get_le_central_context_with_state(P_W4_CONNECTED);
|
||||
}
|
||||
|
||||
static void le_central_handle_context_list(){
|
||||
// only one connect is allowed, wait for result
|
||||
if (get_le_central_w4_connected()) return;
|
||||
|
||||
// only one cancel connect is allowed, wait for result
|
||||
if (get_le_central_w4_connect_cancelled()) return;
|
||||
|
||||
if (!hci_can_send_packet_now_using_packet_buffer(HCI_COMMAND_DATA_PACKET)) return;
|
||||
if (!l2cap_can_send_connectionless_packet_now()) return;
|
||||
|
||||
// printf("handle_peripheral_list empty %u\n", linked_list_empty(&le_connections));
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) le_central_connections; it ; it = it->next){
|
||||
le_central_t * peripheral = (le_central_t *) it;
|
||||
// printf("handle_peripheral_list, status %u\n", peripheral->state);
|
||||
|
||||
switch (peripheral->le_central_state){
|
||||
case P_W2_CONNECT:
|
||||
peripheral->le_central_state = P_W4_CONNECTED;
|
||||
hci_send_cmd(&hci_le_create_connection,
|
||||
1000, // scan interval: 625 ms
|
||||
1000, // scan interval: 625 ms
|
||||
0, // don't use whitelist
|
||||
peripheral->address_type, // peer address type
|
||||
peripheral->address, // peer bd addr
|
||||
0, // our addr type: public
|
||||
80, // conn interval min
|
||||
80, // conn interval max (3200 * 0.625)
|
||||
0, // conn latency
|
||||
2000, // supervision timeout
|
||||
0, // min ce length
|
||||
1000 // max ce length
|
||||
);
|
||||
return;
|
||||
|
||||
case P_W2_CANCEL_CONNECT:
|
||||
peripheral->le_central_state = P_W4_CONNECT_CANCELLED;
|
||||
hci_send_cmd(&hci_le_create_connection_cancel);
|
||||
return;
|
||||
|
||||
case P_W2_DISCONNECT:
|
||||
peripheral->le_central_state = P_W4_DISCONNECTED;
|
||||
hci_send_cmd(&hci_disconnect, peripheral->handle,0x13);
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void le_central_context_init(le_central_t *context, uint8_t addr_type, bd_addr_t addr){
|
||||
memset(context, 0, sizeof(le_central_t));
|
||||
context->address_type = addr_type;
|
||||
memcpy (context->address, addr, 6);
|
||||
}
|
||||
|
||||
|
||||
le_command_status_t le_central_connect(le_central_t *context, uint8_t addr_type, bd_addr_t addr){
|
||||
//TODO: align with hci connection list capacity
|
||||
le_central_t * peripheral = get_le_central_context_with_address(addr_type, addr);
|
||||
if (!peripheral) {
|
||||
le_central_context_init(context, addr_type, addr);
|
||||
context->le_central_state = P_W2_CONNECT;
|
||||
linked_list_add(&le_central_connections, (linked_item_t *) context);
|
||||
} else if (peripheral == context) {
|
||||
if (context->le_central_state != P_W2_CONNECT) return BLE_PERIPHERAL_IN_WRONG_STATE;
|
||||
} else {
|
||||
return BLE_PERIPHERAL_DIFFERENT_CONTEXT_FOR_ADDRESS_ALREADY_EXISTS;
|
||||
}
|
||||
le_central_run();
|
||||
return BLE_PERIPHERAL_OK;
|
||||
}
|
||||
|
||||
|
||||
le_command_status_t le_central_disconnect(le_central_t *context){
|
||||
le_central_t * peripheral = get_le_central_context_with_address(context->address_type, context->address);
|
||||
if (!peripheral || (peripheral && peripheral != context)){
|
||||
return BLE_PERIPHERAL_DIFFERENT_CONTEXT_FOR_ADDRESS_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
switch(context->le_central_state){
|
||||
case P_W2_CONNECT:
|
||||
linked_list_remove(&le_central_connections, (linked_item_t *) context);
|
||||
send_le_central_connection_complete_event(peripheral, GATT_CONNECTION_COMPLETE, 0);
|
||||
break;
|
||||
case P_W4_CONNECTED:
|
||||
case P_W2_CANCEL_CONNECT:
|
||||
// trigger cancel connect
|
||||
context->le_central_state = P_W2_CANCEL_CONNECT;
|
||||
break;
|
||||
case P_W4_DISCONNECTED:
|
||||
case P_W4_CONNECT_CANCELLED:
|
||||
return BLE_PERIPHERAL_IN_WRONG_STATE;
|
||||
default:
|
||||
context->le_central_state = P_W2_DISCONNECT;
|
||||
break;
|
||||
}
|
||||
le_central_run();
|
||||
return BLE_PERIPHERAL_OK;
|
||||
}
|
||||
|
||||
|
||||
static void le_central_run(){
|
||||
// check if command is send
|
||||
le_central_handle_context_list();
|
||||
}
|
||||
|
||||
|
||||
static void le_packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
switch (packet[0]) {
|
||||
|
||||
case HCI_EVENT_COMMAND_COMPLETE:
|
||||
if (COMMAND_COMPLETE_EVENT(packet, hci_le_create_connection_cancel)){
|
||||
// printf("packet_handler:: hci_le_create_connection_cancel: cancel connect\n");
|
||||
if (packet[3] != 0x0B) break;
|
||||
|
||||
// cancel connection failed, as connection already established
|
||||
le_central_t * peripheral = get_le_central_w4_connect_cancelled();
|
||||
peripheral->le_central_state = P_W2_DISCONNECT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
{
|
||||
uint16_t handle = READ_BT_16(packet,3);
|
||||
le_central_t * peripheral = get_le_central_context_for_handle(handle);
|
||||
if (!peripheral) break;
|
||||
|
||||
peripheral->le_central_state = P_IDLE;
|
||||
linked_list_remove(&le_central_connections, (linked_item_t *) peripheral);
|
||||
|
||||
// TODO shouldn't we send some kind of disconnect complete?
|
||||
send_le_central_connection_complete_event(peripheral, GATT_CONNECTION_COMPLETE, packet[5]);
|
||||
// printf("Peripheral disconnected, and removed from list\n");
|
||||
break;
|
||||
}
|
||||
case HCI_EVENT_LE_META:
|
||||
switch (packet[2]) {
|
||||
|
||||
|
||||
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE: {
|
||||
le_central_t * peripheral = get_le_central_w4_connected();
|
||||
if (peripheral){
|
||||
if (packet[3]){
|
||||
peripheral->le_central_state = P_IDLE;
|
||||
linked_list_remove(&le_central_connections, (linked_item_t *) peripheral);
|
||||
} else {
|
||||
peripheral->le_central_state = P_CONNECTED;
|
||||
peripheral->handle = READ_BT_16(packet, 4);
|
||||
}
|
||||
send_le_central_connection_complete_event(peripheral, GATT_CONNECTION_COMPLETE, packet[3]);
|
||||
break;
|
||||
}
|
||||
// cancel success?
|
||||
peripheral = get_le_central_w4_connect_cancelled();
|
||||
if (!peripheral) break;
|
||||
linked_list_remove(&le_central_connections, (linked_item_t *) peripheral);
|
||||
send_le_central_connection_complete_event(peripheral, GATT_CONNECTION_COMPLETE, packet[3]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
le_central_run();
|
||||
}
|
||||
|
||||
|
||||
static void ble_packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
if (packet_type != HCI_EVENT_PACKET) return;
|
||||
|
||||
le_packet_handler(connection, packet_type, channel, packet, size);
|
||||
gatt_packet_handler(connection, packet_type, channel, packet, size);
|
||||
|
||||
// hexdump2(packet, size);
|
||||
@ -421,7 +196,7 @@ static void dump_descriptor(le_characteristic_descriptor_t * descriptor){
|
||||
//}
|
||||
|
||||
|
||||
le_central_t test_device;
|
||||
|
||||
gatt_client_t test_gatt_client_context;
|
||||
|
||||
le_service_t services[40];
|
||||
@ -967,21 +742,21 @@ static void handle_ble_client_event(le_event_t * event){
|
||||
handle_disconnect(event);
|
||||
|
||||
switch(tc_state){
|
||||
case TC_W4_CONNECT: {
|
||||
if (event->type != GATT_CONNECTION_COMPLETE) break;
|
||||
|
||||
tc_state = TC_W4_SERVICE_RESULT;
|
||||
printf("\n test client - CONNECTED, query ACC service\n");
|
||||
|
||||
// create gatt client context for this
|
||||
le_central_connection_complete_event_t * peripheral_event = (le_central_connection_complete_event_t *) event;
|
||||
uint16_t handle = peripheral_event->device->handle;
|
||||
gatt_client_start(&test_gatt_client_context, handle);
|
||||
|
||||
// let's start
|
||||
gatt_client_discover_primary_services_by_uuid128(&test_gatt_client_context, acc_service_uuid);
|
||||
break;
|
||||
}
|
||||
// case TC_W4_CONNECT: {
|
||||
// if (event->type != GATT_CONNECTION_COMPLETE) break;
|
||||
//
|
||||
// tc_state = TC_W4_SERVICE_RESULT;
|
||||
// printf("\n test client - CONNECTED, query ACC service\n");
|
||||
//
|
||||
// // create gatt client context for this
|
||||
// le_central_connection_complete_event_t * peripheral_event = (le_central_connection_complete_event_t *) event;
|
||||
// uint16_t handle = peripheral_event->device->handle;
|
||||
// gatt_client_start(&test_gatt_client_context, handle);
|
||||
//
|
||||
// // let's start
|
||||
// gatt_client_discover_primary_services_by_uuid128(&test_gatt_client_context, acc_service_uuid);
|
||||
// break;
|
||||
// }
|
||||
|
||||
case TC_W4_SERVICE_RESULT:
|
||||
switch(event->type){
|
||||
@ -1034,7 +809,7 @@ static void handle_ble_client_event(le_event_t * event){
|
||||
printf("DONE");
|
||||
tc_state = TC_W4_DISCONNECT;
|
||||
printf("\n\n test client - DISCONNECT ");
|
||||
le_central_disconnect(&test_device);
|
||||
// le_central_disconnect(&test_device);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1082,7 +857,7 @@ static void handle_hci_event(uint8_t packet_type, uint8_t *packet, uint16_t size
|
||||
|
||||
tc_state = TC_W4_CONNECT;
|
||||
le_central_stop_scan();
|
||||
le_central_connect(&test_device, test_device_addr_type, test_device_addr);
|
||||
le_central_connect(&test_device_addr, test_device_addr_type);
|
||||
|
||||
break;
|
||||
case BTSTACK_EVENT_STATE:
|
||||
@ -1093,6 +868,23 @@ static void handle_hci_event(uint8_t packet_type, uint8_t *packet, uint16_t size
|
||||
le_central_start_scan();
|
||||
}
|
||||
break;
|
||||
case HCI_EVENT_LE_META:
|
||||
switch (packet[2]) {
|
||||
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE: {
|
||||
if (tc_state != TC_W4_CONNECT) return;
|
||||
tc_state = TC_W4_SERVICE_RESULT;
|
||||
printf("\n test client - CONNECTED, query ACC service\n");
|
||||
gatt_client_start(&test_gatt_client_context, READ_BT_16(packet, 4));
|
||||
|
||||
// let's start
|
||||
gatt_client_discover_primary_services_by_uuid128(&test_gatt_client_context, acc_service_uuid);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DAEMON_EVENT_HCI_PACKET_SENT:
|
||||
switch(tc_state){
|
||||
case TC_W2_WRITE_WITHOUT_RESPONSE:
|
||||
@ -1109,6 +901,7 @@ static void handle_hci_event(uint8_t packet_type, uint8_t *packet, uint16_t size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
static hci_uart_config_t config;
|
||||
|
@ -55,48 +55,10 @@ extern "C" {
|
||||
#define LE_CENTRAL_MAX_INCLUDE_DEPTH 3
|
||||
|
||||
|
||||
//*************** le central client
|
||||
|
||||
typedef enum{
|
||||
P_IDLE,
|
||||
P_W2_CONNECT,
|
||||
P_W4_CONNECTED,
|
||||
P_CONNECTED,
|
||||
P_W2_CANCEL_CONNECT,
|
||||
P_W4_CONNECT_CANCELLED,
|
||||
P_W2_DISCONNECT,
|
||||
P_W4_DISCONNECTED
|
||||
} le_central_state_t;
|
||||
|
||||
typedef struct le_central{
|
||||
linked_item_t item;
|
||||
le_central_state_t le_central_state;
|
||||
|
||||
uint8_t address_type;
|
||||
bd_addr_t address;
|
||||
uint16_t handle;
|
||||
} le_central_t;
|
||||
|
||||
typedef struct le_central_connection_complete_event{
|
||||
uint8_t type;
|
||||
le_central_t * device;
|
||||
uint8_t status;
|
||||
} le_central_connection_complete_event_t;
|
||||
|
||||
|
||||
//*************** gatt client
|
||||
|
||||
|
||||
|
||||
void ble_client_init();
|
||||
void le_central_init();
|
||||
|
||||
void le_central_register_connection_handler(void (*le_callback)(le_event_t * event));
|
||||
//void ble_client_register_packet_handler(void (*le_callback)(le_event_t * event));
|
||||
|
||||
le_command_status_t le_central_connect(le_central_t *context, uint8_t addr_type, bd_addr_t addr);
|
||||
le_command_status_t le_central_disconnect(le_central_t *context);
|
||||
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
|
82
src/hci.c
82
src/hci.c
@ -80,16 +80,6 @@ static hci_stack_t hci_stack_static;
|
||||
#endif
|
||||
static hci_stack_t * hci_stack = NULL;
|
||||
|
||||
// static void (*le_central_callback)(le_event_t * event);
|
||||
|
||||
//static void dummy_notify(le_event_t* event){}
|
||||
//void le_central_register_handler(void (*le_callback)(le_event_t* event)){
|
||||
// if (le_callback == NULL){
|
||||
// le_callback = dummy_notify;
|
||||
// }
|
||||
// le_central_callback = le_callback;
|
||||
//}
|
||||
|
||||
// test helper
|
||||
static uint8_t disable_l2cap_timeouts = 0;
|
||||
|
||||
@ -1394,7 +1384,29 @@ void hci_run(){
|
||||
|
||||
if (connection->state == SEND_CREATE_CONNECTION){
|
||||
log_info("sending hci_create_connection\n");
|
||||
hci_send_cmd(&hci_create_connection, connection->address, hci_usable_acl_packet_types(), 0, 0, 0, 1);
|
||||
switch(connection->address_type){
|
||||
case BD_ADDR_TYPE_CLASSIC:
|
||||
hci_send_cmd(&hci_create_connection, connection->address, hci_usable_acl_packet_types(), 0, 0, 0, 1);
|
||||
break;
|
||||
default:
|
||||
hci_send_cmd(&hci_le_create_connection,
|
||||
1000, // scan interval: 625 ms
|
||||
1000, // scan interval: 625 ms
|
||||
0, // don't use whitelist
|
||||
connection->address_type, // peer address type
|
||||
connection->address, // peer bd addr
|
||||
0, // our addr type: public
|
||||
80, // conn interval min
|
||||
80, // conn interval max (3200 * 0.625)
|
||||
0, // conn latency
|
||||
2000, // supervision timeout
|
||||
0, // min ce length
|
||||
1000 // max ce length
|
||||
);
|
||||
|
||||
connection->state = SENT_CREATE_CONNECTION;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1863,7 +1875,25 @@ void hci_emit_connection_complete(hci_connection_t *conn, uint8_t status){
|
||||
bt_flip_addr(&event[5], conn->address);
|
||||
event[11] = 1; // ACL connection
|
||||
event[12] = 0; // encryption disabled
|
||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hci_stack->packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
|
||||
}
|
||||
|
||||
void hci_emit_le_connection_complete(hci_connection_t *conn, uint8_t status){
|
||||
uint8_t event[21];
|
||||
event[0] = HCI_EVENT_LE_META;
|
||||
event[1] = sizeof(event) - 2;
|
||||
event[2] = HCI_SUBEVENT_LE_CONNECTION_COMPLETE;
|
||||
event[3] = status;
|
||||
bt_store_16(event, 4, conn->con_handle);
|
||||
event[6] = 0; // TODO: role
|
||||
event[7] = conn->address_type;
|
||||
bt_flip_addr(&event[8], conn->address);
|
||||
bt_store_16(event, 14, 0); // interval
|
||||
bt_store_16(event, 16, 0); // latency
|
||||
bt_store_16(event, 18, 0); // supervision timeout
|
||||
event[20] = 0; // master clock accuracy
|
||||
hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hci_stack->packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
|
||||
}
|
||||
|
||||
@ -1874,7 +1904,7 @@ void hci_emit_disconnection_complete(uint16_t handle, uint8_t reason){
|
||||
event[2] = 0; // status = OK
|
||||
bt_store_16(event, 3, handle);
|
||||
event[5] = reason;
|
||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hci_stack->packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
|
||||
}
|
||||
|
||||
@ -1885,7 +1915,7 @@ void hci_emit_l2cap_check_timeout(hci_connection_t *conn){
|
||||
event[0] = L2CAP_EVENT_TIMEOUT_CHECK;
|
||||
event[1] = sizeof(event) - 2;
|
||||
bt_store_16(event, 2, conn->con_handle);
|
||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hci_stack->packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
|
||||
}
|
||||
|
||||
@ -2126,3 +2156,27 @@ le_command_status_t le_central_stop_scan(){
|
||||
hci_run();
|
||||
return BLE_PERIPHERAL_OK;
|
||||
}
|
||||
|
||||
|
||||
le_command_status_t le_central_connect(bd_addr_t * addr, bd_addr_type_t addr_type){
|
||||
hci_connection_t * conn = hci_connection_for_bd_addr_and_type(addr, addr_type);
|
||||
if (!conn){
|
||||
conn = create_connection_for_bd_addr_and_type(*addr, addr_type);
|
||||
if (!conn){
|
||||
// notify client that alloc failed
|
||||
hci_emit_le_connection_complete(conn, BTSTACK_MEMORY_ALLOC_FAILED);
|
||||
return BLE_PERIPHERAL_NOT_CONNECTED; // don't sent packet to controller
|
||||
}
|
||||
conn->state = SEND_CREATE_CONNECTION;
|
||||
return BLE_PERIPHERAL_OK;
|
||||
}
|
||||
conn->state = OPEN;
|
||||
hci_emit_le_connection_complete(conn, 0);
|
||||
hci_run();
|
||||
return BLE_PERIPHERAL_OK;
|
||||
}
|
||||
|
||||
|
||||
le_command_status_t le_central_disconnect(uint16_t * handle){
|
||||
return BLE_PERIPHERAL_OK;
|
||||
}
|
||||
|
@ -262,6 +262,7 @@ typedef enum {
|
||||
LE_STOP_SCAN,
|
||||
} le_scanning_state_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
// linked list - assert: first field
|
||||
linked_item_t item;
|
||||
@ -307,9 +308,9 @@ typedef struct {
|
||||
|
||||
// number ACL packets sent to controller
|
||||
uint8_t num_acl_packets_sent;
|
||||
|
||||
} hci_connection_t;
|
||||
|
||||
|
||||
/**
|
||||
* main data structure
|
||||
*/
|
||||
@ -399,7 +400,9 @@ typedef enum {
|
||||
// void le_central_register_handler(void (*le_callback)(le_event_t* event));
|
||||
le_command_status_t le_central_start_scan();
|
||||
le_command_status_t le_central_stop_scan();
|
||||
|
||||
le_command_status_t le_central_connect(bd_addr_t * addr, bd_addr_type_t addr_type);
|
||||
le_command_status_t le_central_disconnect(uint16_t * handle);
|
||||
|
||||
//*************** le client end
|
||||
|
||||
// create and send hci command packets based on a template and a list of parameters
|
||||
|
Loading…
x
Reference in New Issue
Block a user