ble/device_information_service: skeleton files

This commit is contained in:
Milanka Ringwald 2021-03-05 09:13:19 +01:00
parent 08b8a6e446
commit 77aad12581
7 changed files with 492 additions and 41 deletions

View File

@ -83,8 +83,9 @@ GATT_SERVER += \
att_server.c \
GATT_CLIENT += \
gatt_client.c \
battery_service_client.c \
gatt_client.c \
battery_service_client.c \
device_information_service_client.c \
PAN += \
pan.c \
@ -213,28 +214,29 @@ EXAMPLES_CLASSIC_ONLY = \
# List of Examples that only use Bluetooth LE
EXAMPLES_LE_ONLY= \
ancs_client_demo \
att_delayed_response \
gap_le_advertisements \
gatt_battery_query \
gatt_browser \
gatt_counter \
gatt_heart_rate_client \
gatt_streamer_server \
hog_keyboard_demo \
hog_mouse_demo \
hog_boot_host_demo \
le_data_channel_client \
le_data_channel_server \
le_mitm \
le_streamer_client \
mesh_node_demo \
nordic_spp_le_counter \
nordic_spp_le_streamer \
sm_pairing_central \
sm_pairing_peripheral \
ublox_spp_le_counter \
EXAMPLES_LE_ONLY= \
ancs_client_demo \
att_delayed_response \
gap_le_advertisements \
gatt_battery_query \
gatt_browser \
gatt_counter \
gatt_device_information_query \
gatt_heart_rate_client \
gatt_streamer_server \
hog_boot_host_demo \
hog_keyboard_demo \
hog_mouse_demo \
le_data_channel_client \
le_data_channel_server \
le_mitm \
le_streamer_client \
mesh_node_demo \
nordic_spp_le_counter \
nordic_spp_le_streamer \
sm_pairing_central \
sm_pairing_peripheral \
ublox_spp_le_counter \
# List of Examples that use Bluetooth BR/EDR/LE = Dual Mode
@ -246,23 +248,24 @@ EXAMPLES_DUAL_MODE= \
# List of GATT files used by either LE_ONLY or DUAL_MODE examples
EXAMPLES_GATT_FILES = \
att_delayed_response.gatt \
ancs_client_demo.gatt \
gatt_battery_query.gatt \
gatt_browser.gatt \
gatt_counter.gatt \
gatt_streamer_server.gatt \
hog_keyboard_demo.gatt \
hog_mouse_demo.gatt \
le_data_channel_server.gatt \
nordic_spp_le_counter.gatt \
nordic_spp_le_streamer.gatt \
sm_pairing_central.gatt \
sm_pairing_peripheral.gatt \
spp_and_gatt_counter.gatt \
spp_and_gatt_streamer.gatt \
ublox_spp_le_counter.gatt \
EXAMPLES_GATT_FILES = \
ancs_client_demo.gatt \
att_delayed_response.gatt \
gatt_battery_query.gatt \
gatt_browser.gatt \
gatt_counter.gatt \
gatt_device_information_query.gatt \
gatt_streamer_server.gatt \
hog_keyboard_demo.gatt \
hog_mouse_demo.gatt \
le_data_channel_server.gatt \
nordic_spp_le_counter.gatt \
nordic_spp_le_streamer.gatt \
sm_pairing_central.gatt \
sm_pairing_peripheral.gatt \
spp_and_gatt_counter.gatt \
spp_and_gatt_streamer.gatt \
ublox_spp_le_counter.gatt \
# .h for .gatt
EXAMPLES_GATT_H_FILES = $(EXAMPLES_GATT_FILES:.gatt=.h)
@ -379,6 +382,9 @@ gatt_browser: gatt_browser.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_CLIENT_
gatt_battery_query: gatt_battery_query.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_CLIENT_OBJ} ${GATT_SERVER_OBJ} gatt_battery_query.c
${CC} $(filter-out gatt_battery_query.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
gatt_device_information_query: gatt_device_information_query.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_CLIENT_OBJ} ${GATT_SERVER_OBJ} gatt_device_information_query.c
${CC} $(filter-out gatt_device_information_query.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
ancs_client_demo: ancs_client_demo.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${GATT_CLIENT_OBJ} ancs_client.c ancs_client_demo.c
${CC} $(filter-out ancs_client_demo.h,$^) ${CFLAGS} ${LDFLAGS} -o $@

View File

@ -0,0 +1,255 @@
/*
* Copyright (C) 2014 BlueKitchen GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* 4. Any redistribution, use, or modification is done solely for
* personal benefit and not for any commercial purpose or for
* monetary gain.
*
* THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Please inquire about commercial licensing options at
* contact@bluekitchen-gmbh.com
*
*/
#define BTSTACK_FILE__ "gatt_device_information_query.c"
// *****************************************************************************
/* EXAMPLE_START(gatt_device_information_query): GATT Device Information Client
*
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "btstack.h"
// gatt_device_information_query.gatt contains the declaration of the provided GATT Services + Characteristics
// gatt_device_information_query.h contains the binary representation of gatt_device_information_query.gatt
// it is generated by the build system by calling: $BTSTACK_ROOT/tool/compile_gatt.py gatt_device_information_query.gatt gatt_device_information_query.h
// it needs to be regenerated when the GATT Database declared in gatt_device_information_query.gatt file is modified
#include "gatt_device_information_query.h"
typedef struct advertising_report {
uint8_t type;
uint8_t event_type;
uint8_t address_type;
bd_addr_t address;
uint8_t rssi;
uint8_t length;
const uint8_t * data;
} advertising_report_t;
static enum {
APP_STATE_IDLE,
APP_STATE_W4_SCAN_RESULT,
APP_STATE_W4_CONNECT,
APP_STATE_CONNECTED
} app_state;
static int blacklist_index = 0;
static bd_addr_t blacklist[20];
static advertising_report_t report;
static hci_con_handle_t connection_handle;
static bd_addr_t cmdline_addr;
static int cmdline_addr_found = 0;
static btstack_packet_callback_registration_t hci_event_callback_registration;
static int blacklist_size(void){
return sizeof(blacklist) / sizeof(bd_addr_t);
}
static int blacklist_contains(bd_addr_t addr){
int i;
for (i=0; i<blacklist_size(); i++){
if (bd_addr_cmp(addr, blacklist[i]) == 0) return 1;
}
return 0;
}
static void add_to_blacklist(bd_addr_t addr){
printf("%s added to blacklist (no device information service found).\n", bd_addr_to_str(addr));
bd_addr_copy(blacklist[blacklist_index], addr);
blacklist_index = (blacklist_index + 1) % blacklist_size();
}
static void dump_advertising_report(uint8_t *packet){
bd_addr_t address;
gap_event_advertising_report_get_address(packet, address);
printf(" * adv. event: evt-type %u, addr-type %u, addr %s, rssi %u, length adv %u, data: ",
gap_event_advertising_report_get_advertising_event_type(packet),
gap_event_advertising_report_get_address_type(packet),
bd_addr_to_str(address),
gap_event_advertising_report_get_rssi(packet),
gap_event_advertising_report_get_data_length(packet));
printf_hexdump(gap_event_advertising_report_get_data(packet), gap_event_advertising_report_get_data_length(packet));
}
static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
UNUSED(packet_type);
UNUSED(channel);
UNUSED(size);
if (hci_event_packet_get_type(packet) != HCI_EVENT_GATTSERVICE_META){
return;
}
switch (hci_event_gattservice_meta_get_subevent_code(packet)){
default:
break;
}
}
static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
UNUSED(channel);
UNUSED(size);
uint8_t status;
bd_addr_t address;
if (packet_type != HCI_EVENT_PACKET){
return;
}
switch (hci_event_packet_get_type(packet)) {
case BTSTACK_EVENT_STATE:
// BTstack activated, get started
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
if (cmdline_addr_found){
printf("Connect to %s\n", bd_addr_to_str(cmdline_addr));
app_state = APP_STATE_W4_CONNECT;
gap_connect(cmdline_addr, 0);
break;
}
printf("Start scanning!\n");
app_state = APP_STATE_W4_SCAN_RESULT;
gap_set_scan_parameters(0,0x0030, 0x0030);
gap_start_scan();
break;
case GAP_EVENT_ADVERTISING_REPORT:
if (app_state != APP_STATE_W4_SCAN_RESULT) return;
gap_event_advertising_report_get_address(packet, address);
if (blacklist_contains(address)) {
break;
}
dump_advertising_report(packet);
// stop scanning, and connect to the device
app_state = APP_STATE_W4_CONNECT;
gap_stop_scan();
printf("Stop scan. Connect to device with addr %s.\n", bd_addr_to_str(report.address));
gap_connect(report.address,report.address_type);
break;
case HCI_EVENT_LE_META:
// wait for connection complete
if (hci_event_le_meta_get_subevent_code(packet) != HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break;
if (app_state != APP_STATE_W4_CONNECT) return;
connection_handle = hci_subevent_le_connection_complete_get_connection_handle(packet);
status = device_information_service_client_query(connection_handle, handle_gatt_client_event);
btstack_assert(status == ERROR_CODE_SUCCESS);
app_state = APP_STATE_CONNECTED;
printf("Device Information service queried.\n");
break;
case HCI_EVENT_DISCONNECTION_COMPLETE:
connection_handle = HCI_CON_HANDLE_INVALID;
if (cmdline_addr_found){
printf("Disconnected %s\n", bd_addr_to_str(cmdline_addr));
return;
}
printf("Disconnected %s\n", bd_addr_to_str(report.address));
printf("Restart scan.\n");
app_state = APP_STATE_W4_SCAN_RESULT;
gap_start_scan();
break;
default:
break;
}
}
int btstack_main(int argc, const char * argv[]);
int btstack_main(int argc, const char * argv[]){
// parse address if command line arguments are provided
int arg = 1;
cmdline_addr_found = 0;
while (arg < argc) {
if(!strcmp(argv[arg], "-a") || !strcmp(argv[arg], "--address")){
arg++;
cmdline_addr_found = sscanf_bd_addr(argv[arg], cmdline_addr);
arg++;
if (!cmdline_addr_found) exit(1);
continue;
}
fprintf(stderr, "\nUsage: %s [-a|--address aa:bb:cc:dd:ee:ff]\n", argv[0]);
fprintf(stderr, "If no argument is provided, GATT browser will start scanning and connect to the first found device.\nTo connect to a specific device use argument [-a].\n\n");
return 0;
}
(void)argv;
l2cap_init();
// setup ATT server - only needed if LE Peripheral does ATT queries on its own, e.g. Android phones
att_server_init(profile_data, NULL, NULL);
// GATT Client setup
gatt_client_init();
device_information_service_client_init();
sm_init();
sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT);
hci_event_callback_registration.callback = &hci_event_handler;
hci_add_event_handler(&hci_event_callback_registration);
app_state = APP_STATE_IDLE;
// turn on!
hci_power_control(HCI_POWER_ON);
return 0;
}
/* EXAMPLE_END */

View File

@ -0,0 +1,4 @@
PRIMARY_SERVICE, GAP_SERVICE
CHARACTERISTIC, GAP_DEVICE_NAME, READ, "GATT Device Informaition Query"

View File

@ -6,6 +6,8 @@ SRC_BLE_FILES = \
att_db_util.c \
att_dispatch.c \
att_server.c \
battery_service_client.c \
device_information_service_client.c \
gatt_client.c \
hids_client.c \
le_device_db_memory.c \

View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2021 BlueKitchen GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* 4. Any redistribution, use, or modification is done solely for
* personal benefit and not for any commercial purpose or for
* monetary gain.
*
* THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Please inquire about commercial licensing options at
* contact@bluekitchen-gmbh.com
*
*/
#define BTSTACK_FILE__ "device_information_service_client.c"
#include "btstack_config.h"
#include <stdint.h>
#include <string.h>
#include "device_information_service_client.h"
#include "btstack_memory.h"
#include "ble/att_db.h"
#include "ble/core.h"
#include "ble/gatt_client.h"
#include "ble/sm.h"
#include "bluetooth_gatt.h"
#include "btstack_debug.h"
#include "btstack_event.h"
#include "btstack_run_loop.h"
#include "gap.h"
static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
UNUSED(packet_type); // ok: only hci events
UNUSED(channel); // ok: there is no channel
UNUSED(size); // ok: fixed format events read from HCI buffer
}
uint8_t device_information_service_client_query(hci_con_handle_t con_handle, btstack_packet_handler_t packet_handler){
btstack_assert(packet_handler != NULL);
return ERROR_CODE_SUCCESS;
}
void device_information_service_client_init(void){}
void device_information_service_client_deinit(void){}

View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 2021 BlueKitchen GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* 4. Any redistribution, use, or modification is done solely for
* personal benefit and not for any commercial purpose or for
* monetary gain.
*
* THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Please inquire about commercial licensing options at
* contact@bluekitchen-gmbh.com
*
*/
#ifndef DEVICE_INFORMATION_SERVICE_CLIENT_H
#define DEVICE_INFORMATION_SERVICE_CLIENT_H
#include <stdint.h>
#include "btstack_defines.h"
#include "bluetooth.h"
#include "btstack_linked_list.h"
#include "ble/gatt_client.h"
#if defined __cplusplus
extern "C" {
#endif
typedef enum {
DEVICE_INFORMATION_SERVICE_CLIENT_STATE_IDLE,
DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE,
DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT,
DEVICE_INFORMATION_SERVICE_CLIENT_STATE_CONNECTED
} device_information_service_client_state_t;
typedef struct {
// service
uint16_t start_handle;
uint16_t end_handle;
} device_information_service_t;
typedef struct {
btstack_linked_item_t item;
hci_con_handle_t con_handle;
device_information_service_client_state_t state;
btstack_packet_handler_t client_handler;
} device_information_service_client_t;
/* API_START */
/**
* @brief Initialize Device Information Service.
*/
void device_information_service_client_init(void);
/**
* @brief Query Device Information Service.
* @param con_handle
* @param packet_handler
*/
uint8_t device_information_service_client_query(hci_con_handle_t con_handle, btstack_packet_handler_t packet_handler);
/**
* @brief De-initialize Device Information Service.
*/
void device_information_service_client_deinit(void);
/* API_END */
#if defined __cplusplus
}
#endif
#endif

View File

@ -82,6 +82,7 @@
#include "ble/att_dispatch.h"
#include "ble/att_server.h"
#include "ble/battery_service_client.h"
#include "ble/device_information_service_client.h"
#include "ble/gatt-service/battery_service_server.h"
#include "ble/gatt-service/cycling_power_service_server.h"
#include "ble/gatt-service/cycling_speed_and_cadence_service_server.h"