-
Notifications
You must be signed in to change notification settings - Fork 162
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
examples/nordic_uart: Port to new API
- Loading branch information
1 parent
a074af0
commit ead29e7
Showing
2 changed files
with
140 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
* | ||
* GattLib - GATT Library | ||
* | ||
* Copyright (C) 2016-2021 Olivier Martin <[email protected]> | ||
* Copyright (C) 2016-2024 Olivier Martin <[email protected]> | ||
* | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
|
@@ -22,75 +22,73 @@ | |
*/ | ||
|
||
#include <assert.h> | ||
#include <ctype.h> | ||
#include <pthread.h> | ||
#include <signal.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <signal.h> | ||
|
||
#ifdef GATTLIB_LOG_BACKEND_SYSLOG | ||
#include <syslog.h> | ||
#endif | ||
|
||
#include "gattlib.h" | ||
|
||
#define MIN(a,b) ((a)<(b)?(a):(b)) | ||
|
||
#define NUS_CHARACTERISTIC_TX_UUID "6e400002-b5a3-f393-e0a9-e50e24dcca9e" | ||
#define NUS_CHARACTERISTIC_RX_UUID "6e400003-b5a3-f393-e0a9-e50e24dcca9e" | ||
|
||
gattlib_connection_t* m_connection; | ||
#define BLE_SCAN_TIMEOUT 10 | ||
|
||
#define MIN(a,b) ((a)<(b)?(a):(b)) | ||
|
||
void notification_cb(const uuid_t* uuid, const uint8_t* data, size_t data_length, void* user_data) { | ||
int i; | ||
static struct { | ||
char *adapter_name; | ||
char* mac_address; | ||
} m_argument; | ||
|
||
// Declaration of thread condition variable | ||
static pthread_cond_t m_connection_terminated = PTHREAD_COND_INITIALIZER; | ||
|
||
// declaring mutex | ||
static pthread_mutex_t m_connection_terminated_lock = PTHREAD_MUTEX_INITIALIZER; | ||
|
||
static gattlib_connection_t* m_connection; | ||
|
||
static void usage(char *argv[]) { | ||
printf("%s <device_address>\n", argv[0]); | ||
} | ||
|
||
static void notification_handler(const uuid_t* uuid, const uint8_t* data, size_t data_length, void* user_data) { | ||
uintptr_t i; | ||
|
||
for(i = 0; i < data_length; i++) { | ||
printf("%c", data[i]); | ||
} | ||
fflush(stdout); | ||
} | ||
|
||
static void usage(char *argv[]) { | ||
printf("%s <device_address>\n", argv[0]); | ||
} | ||
|
||
void int_handler(int dummy) { | ||
static void int_handler(int dummy) { | ||
gattlib_disconnect(m_connection, false /* wait_disconnection */); | ||
exit(0); | ||
} | ||
|
||
int main(int argc, char *argv[]) { | ||
char input[256]; | ||
char* input_ptr; | ||
int i, ret, total_length, length = 0; | ||
static void on_device_connect(gattlib_adapter_t* adapter, const char *dst, gattlib_connection_t* connection, int error, void* user_data) { | ||
uuid_t nus_characteristic_tx_uuid; | ||
uuid_t nus_characteristic_rx_uuid; | ||
|
||
if (argc != 2) { | ||
usage(argv); | ||
return 1; | ||
} | ||
|
||
#ifdef GATTLIB_LOG_BACKEND_SYSLOG | ||
openlog("gattlib_nordic_uart", LOG_CONS | LOG_NDELAY | LOG_PERROR, LOG_USER); | ||
setlogmask(LOG_UPTO(LOG_INFO)); | ||
#endif | ||
|
||
m_connection = gattlib_connect(NULL, argv[1], | ||
GATTLIB_CONNECTION_OPTIONS_LEGACY_BDADDR_LE_RANDOM | | ||
GATTLIB_CONNECTION_OPTIONS_LEGACY_BT_SEC_LOW); | ||
if (m_connection == NULL) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Fail to connect to the bluetooth device."); | ||
return 1; | ||
} | ||
char input[256]; | ||
char* input_ptr; | ||
int ret, total_length, length = 0; | ||
|
||
// Convert characteristics to their respective UUIDs | ||
ret = gattlib_string_to_uuid(NUS_CHARACTERISTIC_TX_UUID, strlen(NUS_CHARACTERISTIC_TX_UUID) + 1, &nus_characteristic_tx_uuid); | ||
if (ret) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Fail to convert characteristic TX to UUID."); | ||
return 1; | ||
goto EXIT; | ||
} | ||
ret = gattlib_string_to_uuid(NUS_CHARACTERISTIC_RX_UUID, strlen(NUS_CHARACTERISTIC_RX_UUID) + 1, &nus_characteristic_rx_uuid); | ||
if (ret) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Fail to convert characteristic RX to UUID."); | ||
return 1; | ||
goto EXIT; | ||
} | ||
|
||
// Look for handle for NUS_CHARACTERISTIC_TX_UUID | ||
|
@@ -99,11 +97,14 @@ int main(int argc, char *argv[]) { | |
ret = gattlib_discover_char(m_connection, &characteristics, &characteristic_count); | ||
if (ret) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Fail to discover characteristic."); | ||
return 1; | ||
goto EXIT; | ||
} | ||
|
||
// | ||
// Confirm the Nordic UART RX and TX GATT characteristics are present | ||
// | ||
uint16_t tx_handle = 0, rx_handle = 0; | ||
for (i = 0; i < characteristic_count; i++) { | ||
for (int i = 0; i < characteristic_count; i++) { | ||
if (gattlib_uuid_cmp(&characteristics[i].uuid, &nus_characteristic_tx_uuid) == 0) { | ||
tx_handle = characteristics[i].value_handle; | ||
} else if (gattlib_uuid_cmp(&characteristics[i].uuid, &nus_characteristic_rx_uuid) == 0) { | ||
|
@@ -112,23 +113,29 @@ int main(int argc, char *argv[]) { | |
} | ||
if (tx_handle == 0) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Fail to find NUS TX characteristic."); | ||
return 1; | ||
goto FREE_GATT_CHARACTERISTICS; | ||
} else if (rx_handle == 0) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Fail to find NUS RX characteristic."); | ||
return 1; | ||
goto FREE_GATT_CHARACTERISTICS; | ||
} | ||
free(characteristics); | ||
|
||
// Register notification handler | ||
gattlib_register_notification(m_connection, notification_cb, NULL); | ||
// | ||
// Listen for Nordic UART TX GATT characteristic | ||
// | ||
ret = gattlib_register_notification(connection, notification_handler, NULL); | ||
if (ret) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Fail to register notification callback."); | ||
goto FREE_GATT_CHARACTERISTICS; | ||
} | ||
|
||
ret = gattlib_notification_start(m_connection, &nus_characteristic_rx_uuid); | ||
ret = gattlib_notification_start(connection, &nus_characteristic_rx_uuid); | ||
if (ret) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Fail to start notification."); | ||
return 2; | ||
goto FREE_GATT_CHARACTERISTICS; | ||
} | ||
|
||
// Register handler to catch Ctrl+C | ||
m_connection = connection; | ||
signal(SIGINT, int_handler); | ||
|
||
while(1) { | ||
|
@@ -141,11 +148,97 @@ int main(int argc, char *argv[]) { | |
ret = gattlib_write_without_response_char_by_handle(m_connection, tx_handle, input_ptr, length); | ||
if (ret) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Fail to send data to NUS TX characteristic."); | ||
return 1; | ||
goto FREE_GATT_CHARACTERISTICS; | ||
} | ||
input_ptr += length; | ||
} | ||
} | ||
|
||
FREE_GATT_CHARACTERISTICS: | ||
free(characteristics); | ||
|
||
EXIT: | ||
gattlib_disconnect(connection, false /* wait_disconnection */); | ||
|
||
pthread_mutex_lock(&m_connection_terminated_lock); | ||
pthread_cond_signal(&m_connection_terminated); | ||
pthread_mutex_unlock(&m_connection_terminated_lock); | ||
} | ||
|
||
static int stricmp(char const *a, char const *b) { | ||
for (;; a++, b++) { | ||
int d = tolower((unsigned char)*a) - tolower((unsigned char)*b); | ||
if (d != 0 || !*a) | ||
return d; | ||
} | ||
} | ||
|
||
static void ble_discovered_device(gattlib_adapter_t* adapter, const char* addr, const char* name, void *user_data) { | ||
int ret; | ||
int16_t rssi; | ||
|
||
if (stricmp(addr, m_argument.mac_address) != 0) { | ||
return; | ||
} | ||
|
||
ret = gattlib_get_rssi_from_mac(adapter, addr, &rssi); | ||
if (ret == 0) { | ||
GATTLIB_LOG(GATTLIB_INFO, "Found bluetooth device '%s' with RSSI:%d", m_argument.mac_address, rssi); | ||
} else { | ||
GATTLIB_LOG(GATTLIB_INFO, "Found bluetooth device '%s'", m_argument.mac_address); | ||
} | ||
|
||
ret = gattlib_connect(adapter, addr, GATTLIB_CONNECTION_OPTIONS_NONE, on_device_connect, NULL); | ||
if (ret != GATTLIB_SUCCESS) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Failed to connect to the bluetooth device '%s'", addr); | ||
} | ||
} | ||
|
||
static void* ble_task(void* arg) { | ||
char* addr = arg; | ||
gattlib_adapter_t* adapter; | ||
int ret; | ||
|
||
ret = gattlib_adapter_open(m_argument.adapter_name, &adapter); | ||
if (ret) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Failed to open adapter."); | ||
return NULL; | ||
} | ||
|
||
ret = gattlib_adapter_scan_enable(adapter, ble_discovered_device, BLE_SCAN_TIMEOUT, addr); | ||
if (ret) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Failed to scan."); | ||
return NULL; | ||
} | ||
|
||
// Wait for the device to be connected | ||
pthread_mutex_lock(&m_connection_terminated_lock); | ||
pthread_cond_wait(&m_connection_terminated, &m_connection_terminated_lock); | ||
pthread_mutex_unlock(&m_connection_terminated_lock); | ||
|
||
return NULL; | ||
} | ||
|
||
int main(int argc, char *argv[]) { | ||
int ret; | ||
|
||
if (argc != 2) { | ||
usage(argv); | ||
return 1; | ||
} | ||
|
||
#ifdef GATTLIB_LOG_BACKEND_SYSLOG | ||
openlog("gattlib_nordic_uart", LOG_CONS | LOG_NDELAY | LOG_PERROR, LOG_USER); | ||
setlogmask(LOG_UPTO(LOG_INFO)); | ||
#endif | ||
|
||
m_argument.adapter_name = NULL; | ||
m_argument.mac_address = argv[1]; | ||
|
||
ret = gattlib_mainloop(ble_task, NULL); | ||
if (ret != GATTLIB_SUCCESS) { | ||
GATTLIB_LOG(GATTLIB_ERROR, "Failed to create gattlib mainloop"); | ||
} | ||
|
||
return 0; | ||
} |