Skip to content

Commit 662d7c3

Browse files
committed
IOS WORKS
1 parent edbe9c8 commit 662d7c3

File tree

8 files changed

+299
-9
lines changed

8 files changed

+299
-9
lines changed

.vscode/settings.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
"random": "c",
88
"array": "c",
99
"string": "c",
10-
"string_view": "c"
10+
"string_view": "c",
11+
"ble_svc_gap.h": "c",
12+
"console.h": "c"
1113
}
1214
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
idf_component_register(SRCS "misc.c" "scli.c"
2+
INCLUDE_DIRS "."
3+
PRIV_REQUIRES bt console driver)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Unlicense OR CC0-1.0
5+
*/
6+
7+
#ifndef H_ESP_PERIPHERAL_
8+
#define H_ESP_PERIPHERAL_
9+
10+
#include <stdbool.h>
11+
#include "nimble/ble.h"
12+
#include "modlog/modlog.h"
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
/* Console */
18+
int scli_init(void);
19+
int scli_receive_key(int *key);
20+
21+
/** Misc. */
22+
void print_bytes(const uint8_t *bytes, int len);
23+
void print_addr(const void *addr);
24+
25+
#ifdef __cplusplus
26+
}
27+
#endif
28+
29+
#endif
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Unlicense OR CC0-1.0
5+
*/
6+
7+
#include "esp_peripheral.h"
8+
9+
/**
10+
* Utility function to log an array of bytes.
11+
*/
12+
void
13+
print_bytes(const uint8_t *bytes, int len)
14+
{
15+
int i;
16+
17+
for (i = 0; i < len; i++) {
18+
MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
19+
}
20+
}
21+
22+
void
23+
print_addr(const void *addr)
24+
{
25+
const uint8_t *u8p;
26+
27+
u8p = addr;
28+
MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
29+
u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
30+
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Unlicense OR CC0-1.0
5+
*/
6+
7+
#include <stdio.h>
8+
#include <ctype.h>
9+
#include "esp_log.h"
10+
#include <string.h>
11+
#include <esp_log.h>
12+
#include <esp_console.h>
13+
#include <freertos/FreeRTOS.h>
14+
#include <freertos/task.h>
15+
#include <freertos/queue.h>
16+
#include <driver/uart.h>
17+
#include "esp_peripheral.h"
18+
19+
#define BLE_RX_TIMEOUT (30000 / portTICK_PERIOD_MS)
20+
21+
static TaskHandle_t cli_task;
22+
static QueueHandle_t cli_handle;
23+
static int stop;
24+
25+
static int enter_passkey_handler(int argc, char *argv[])
26+
{
27+
int key;
28+
char pkey[8];
29+
int num;
30+
31+
if (argc != 2) {
32+
return -1;
33+
}
34+
35+
sscanf(argv[1], "%s", pkey);
36+
ESP_LOGI("You entered", "%s %s", argv[0], argv[1]);
37+
num = pkey[0];
38+
39+
if (isalpha(num)) {
40+
if ((strcasecmp(pkey, "Y") == 0) || (strcasecmp(pkey, "Yes") == 0)) {
41+
key = 1;
42+
xQueueSend(cli_handle, &key, 0);
43+
} else {
44+
key = 0;
45+
xQueueSend(cli_handle, &key, 0);
46+
}
47+
} else {
48+
sscanf(pkey, "%d", &key);
49+
xQueueSend(cli_handle, &key, 0);
50+
}
51+
52+
return 0;
53+
}
54+
55+
int scli_receive_key(int *console_key)
56+
{
57+
return xQueueReceive(cli_handle, console_key, BLE_RX_TIMEOUT);
58+
}
59+
60+
static esp_console_cmd_t cmds[] = {
61+
{
62+
.command = "key",
63+
.help = "",
64+
.func = enter_passkey_handler,
65+
},
66+
};
67+
68+
static int ble_register_cli(void)
69+
{
70+
int cmds_num = sizeof(cmds) / sizeof(esp_console_cmd_t);
71+
int i;
72+
for (i = 0; i < cmds_num; i++) {
73+
esp_console_cmd_register(&cmds[i]);
74+
}
75+
return 0;
76+
}
77+
78+
static void scli_task(void *arg)
79+
{
80+
int uart_num = (int) arg;
81+
uint8_t linebuf[256];
82+
int i, cmd_ret;
83+
esp_err_t ret;
84+
QueueHandle_t uart_queue;
85+
uart_event_t event;
86+
87+
uart_driver_install(uart_num, 256, 0, 8, &uart_queue, 0);
88+
/* Initialize the console */
89+
esp_console_config_t console_config = {
90+
.max_cmdline_args = 8,
91+
.max_cmdline_length = 256,
92+
};
93+
94+
esp_console_init(&console_config);
95+
96+
while (!stop) {
97+
i = 0;
98+
memset(linebuf, 0, sizeof(linebuf));
99+
do {
100+
ret = xQueueReceive(uart_queue, (void * )&event, (TickType_t)portMAX_DELAY);
101+
if (ret != pdPASS) {
102+
if (stop == 1) {
103+
break;
104+
} else {
105+
continue;
106+
}
107+
}
108+
if (event.type == UART_DATA) {
109+
while (uart_read_bytes(uart_num, (uint8_t *) &linebuf[i], 1, 0)) {
110+
if (linebuf[i] == '\r') {
111+
uart_write_bytes(uart_num, "\r\n", 2);
112+
} else {
113+
uart_write_bytes(uart_num, (char *) &linebuf[i], 1);
114+
}
115+
i++;
116+
}
117+
}
118+
} while ((i < 255) && linebuf[i - 1] != '\r');
119+
if (stop) {
120+
break;
121+
}
122+
/* Remove the truncating \r\n */
123+
linebuf[strlen((char *)linebuf) - 1] = '\0';
124+
ret = esp_console_run((char *) linebuf, &cmd_ret);
125+
if (ret < 0) {
126+
break;
127+
}
128+
}
129+
vTaskDelete(NULL);
130+
}
131+
132+
int scli_init(void)
133+
{
134+
/* Register CLI "key <value>" to accept input from user during pairing */
135+
ble_register_cli();
136+
137+
xTaskCreate(scli_task, "scli_cli", 4096, (void *) 0, 3, &cli_task);
138+
if (cli_task == NULL) {
139+
return ESP_FAIL;
140+
}
141+
cli_handle = xQueueCreate( 1, sizeof(int) );
142+
if (cli_handle == NULL) {
143+
return ESP_FAIL;
144+
}
145+
return ESP_OK;
146+
}

infos

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Linux reicht es wenn irgendwie viel bytes im report sind, welches zum gerät geschickt wird.
2+
Windows und Android muss die report größe mit der größe des report deskriptors übereinstimmen.
3+
IOS benötigt eine sichere Verbindung und dann noch die erlaubnis auf das report zuzugreifen wenn es eine sichere verbindung ist. Zusätzlich darf während dem aufbau einer sicheren verbindung keine connection updates durchgeführt werden.

main/gatt_svr.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,7 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
142142
.descriptors = (struct ble_gatt_dsc_def[]){
143143
//client configuration descriptor soll nicht manuell hinzugefügt werden, da dieser mittels dem flag notify automatisch hinzugefügt wird
144144
{
145-
//TODO: | BLE_ATT_F_WRITE_ENC vielleicht bei ios benötigt
146-
.att_flags = BLE_ATT_F_READ,
145+
.att_flags = BLE_ATT_F_READ | BLE_ATT_F_READ_ENC,
147146
.access_cb = report_descriptor_callback,
148147
.uuid = BLE_UUID16_DECLARE(GATT_REPORT_REFERENCE_CHAR_UUID) //damit wird angegeben welche report id und report type abgedeckt werden
149148
}, {

main/main.c

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
//https://macchina.io/blog/internet-of-things/communication-with-low-energy-bluetooth-devices-on-linux/
33

44

5-
//TODO: alle geräte funktionieren außer ios; hier reinschauen wie notify gemacht wird; muss wahrscheinlich secure verbindung sein
6-
//https://github.com/Xi-MingYu/Central/tree/394ccfb02f2c58d8ea7eb0e72b0abe927602f5ea/lib/NimBLE/src
7-
//vielleicht eine secure verbindung aufbauen https://github.com/h2zero/NimBLE-Arduino/issues/222
8-
//https://github.com/wakwak-koba/ESP32-NimBLE-Keyboard/blob/ec4ce707f00d260f30286191fe63dc23d65a5934/BleKeyboard.cpp#L141
9-
// Diese verschlüsselung mal hinzufügen
5+
//TODO: Update connection parameter wieder hinzufügen (bleprh anschauen)
6+
//TODO: Schauen warum unter ios sich bei erneuter verbindung das gerät nicht verbinden kann
7+
//TODO: Bei einem erneuten verbindungsaufbau wird das gestoppte updaten der daten nicht wieder gestartet
8+
//TODO: vielleicht mal schauen ob a Resolvable Private Address schwierig sind hinzuzufügen statt publich adressen (bleprh anschauen)
9+
//Update connection parameters are not allowed during iPhone HID encryption, slave turns off the ability to automatically update connection parameters during encryption.
10+
11+
//https://github.com/espressif/esp-idf/issues/3532
1012

1113
#include "esp_log.h"
1214
#include "nvs_flash.h"
@@ -21,6 +23,7 @@
2123
#include "services/gap/ble_svc_gap.h"
2224
#include "blehr_sens.h"
2325
#include "host/ble_uuid.h"
26+
#include "esp_peripheral.h"
2427

2528
static const char *tag = "NimBLE_BLE_HeartRate";
2629
static const ble_uuid16_t hid_service_uuid = BLE_UUID16_INIT(0x1812);
@@ -183,6 +186,9 @@ blehr_tx_hrate(xTimerHandle ev)
183186
static int
184187
blehr_gap_event(struct ble_gap_event *event, void *arg)
185188
{
189+
struct ble_gap_conn_desc desc;
190+
int rc;
191+
186192
switch (event->type) {
187193
case BLE_GAP_EVENT_CONNECT:
188194
/* A new connection was established or a connection attempt failed */
@@ -205,13 +211,15 @@ blehr_gap_event(struct ble_gap_event *event, void *arg)
205211
.supervision_timeout = 1860/10 //10ms units, laut apple größer als itvl_max * (latency + 1) * 3
206212
};
207213

208-
ESP_ERROR_CHECK(ble_gap_update_params(event->connect.conn_handle, &connectionParameters));
214+
//ESP_ERROR_CHECK(ble_gap_update_params(event->connect.conn_handle, &connectionParameters));
209215

210216
conn_handle = event->connect.conn_handle;
217+
ble_gap_security_initiate(conn_handle);
211218
break;
212219

213220
case BLE_GAP_EVENT_DISCONNECT:
214221
ESP_LOGI("ASDF", "disconnect; reason=%d\n", event->disconnect.reason);
222+
//531 = Remote User Terminated Connection
215223

216224
/* Connection terminated; resume advertising */
217225
blehr_advertise();
@@ -239,7 +247,73 @@ blehr_gap_event(struct ble_gap_event *event, void *arg)
239247
event->mtu.conn_handle,
240248
event->mtu.value);
241249
break;
250+
case BLE_GAP_EVENT_ENC_CHANGE:
251+
ESP_LOGI("ASDF", "encryption change event; status=%d ",
252+
event->enc_change.status);
253+
break;
254+
case BLE_GAP_EVENT_REPEAT_PAIRING:
255+
/* We already have a bond with the peer, but it is attempting to
256+
* establish a new secure link. This app sacrifices security for
257+
* convenience: just throw away the old bond and accept the new link.
258+
*/
259+
ESP_LOGI("ASDF", "establisch new secure link");
260+
261+
/* Delete the old bond. */
262+
rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
263+
assert(rc == 0);
264+
ble_store_util_delete_peer(&desc.peer_id_addr);
265+
266+
/* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
267+
* continue with the pairing operation.
268+
*/
269+
return BLE_GAP_REPEAT_PAIRING_RETRY;
270+
break;
242271

272+
case BLE_GAP_EVENT_PASSKEY_ACTION:
273+
ESP_LOGI("ASDF", "PASSKEY_ACTION_EVENT started \n");
274+
275+
struct ble_sm_io pkey = {0};
276+
int key = 0;
277+
278+
if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
279+
pkey.action = event->passkey.params.action;
280+
pkey.passkey = 123456; // This is the passkey to be entered on peer
281+
ESP_LOGI(tag, "Enter passkey %d on the peer side", pkey.passkey);
282+
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
283+
ESP_LOGI(tag, "ble_sm_inject_io result: %d\n", rc);
284+
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
285+
ESP_LOGI(tag, "Passkey on device's display: %d", event->passkey.params.numcmp);
286+
ESP_LOGI(tag, "Accept or reject the passkey through console in this format -> key Y or key N");
287+
pkey.action = event->passkey.params.action;
288+
if (scli_receive_key(&key)) {
289+
pkey.numcmp_accept = key;
290+
} else {
291+
pkey.numcmp_accept = 0;
292+
ESP_LOGE(tag, "Timeout! Rejecting the key");
293+
}
294+
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
295+
ESP_LOGI(tag, "ble_sm_inject_io result: %d\n", rc);
296+
} else if (event->passkey.params.action == BLE_SM_IOACT_OOB) {
297+
static uint8_t tem_oob[16] = {0};
298+
pkey.action = event->passkey.params.action;
299+
for (int i = 0; i < 16; i++) {
300+
pkey.oob[i] = tem_oob[i];
301+
}
302+
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
303+
ESP_LOGI(tag, "ble_sm_inject_io result: %d\n", rc);
304+
} else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
305+
ESP_LOGI(tag, "Enter the passkey through console in this format-> key 123456");
306+
pkey.action = event->passkey.params.action;
307+
if (scli_receive_key(&key)) {
308+
pkey.passkey = key;
309+
} else {
310+
pkey.passkey = 0;
311+
ESP_LOGE(tag, "Timeout! Passing 0 as the key");
312+
}
313+
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
314+
ESP_LOGI(tag, "ble_sm_inject_io result: %d\n", rc);
315+
}
316+
return 0;
243317
}
244318

245319
return 0;
@@ -297,6 +371,10 @@ void app_main(void)
297371
/* Initialize the NimBLE host configuration */
298372
ble_hs_cfg.sync_cb = blehr_on_sync;
299373
ble_hs_cfg.reset_cb = blehr_on_reset;
374+
ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
375+
ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_NO_IO;
376+
ble_hs_cfg.sm_sc = 1;
377+
ble_hs_cfg.sm_mitm = 1;
300378

301379
/* name, period/time, auto reload, timer ID, callback */
302380
blehr_tx_timer = xTimerCreate("blehr_tx_timer", pdMS_TO_TICKS(2000), pdTRUE, (void *)0, blehr_tx_hrate);

0 commit comments

Comments
 (0)