Initial public release of the 2024A software.
This commit is contained in:
parent
7b9ad3edfd
commit
303e9e1dad
361 changed files with 60083 additions and 2 deletions
276
components/BLE/BLE.c
Normal file
276
components/BLE/BLE.c
Normal file
|
@ -0,0 +1,276 @@
|
|||
#include <SystemK.h>
|
||||
#include "esp_log.h"
|
||||
/* BLE */
|
||||
#include "esp_nimble_hci.h"
|
||||
#include "nimble/nimble_port.h"
|
||||
#include "nimble/nimble_port_freertos.h"
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/util/util.h"
|
||||
#include "console/console.h"
|
||||
#include "services/gap/ble_svc_gap.h"
|
||||
|
||||
static const char *TAG = "BLE";
|
||||
static bool Host_And_Controller_Synced = false;
|
||||
static bool Is_Scanning_And_Advertising = false;
|
||||
|
||||
static uint8_t Advertising_Data[BLE_KTAG_PACKET_TOTAL_SIZE] = {0x1E, 0xFF, 0xFF, 0xFF, 'K', 'T', 'a', 'g'};
|
||||
|
||||
// Forward declarations of NimBLE functions.
|
||||
void ble_store_config_init(void);
|
||||
static int ble_gap_event(struct ble_gap_event *event, void *arg);
|
||||
|
||||
/**
|
||||
* Initiates the GAP general discovery procedure.
|
||||
*/
|
||||
static void ble_scan(void)
|
||||
{
|
||||
uint8_t own_addr_type;
|
||||
struct ble_gap_disc_params disc_params;
|
||||
int rc;
|
||||
|
||||
/* Figure out address to use while advertising (no privacy for now) */
|
||||
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
||||
if (rc != 0)
|
||||
{
|
||||
KLOG_ERROR(TAG, "Error determining address type; rc=%d", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tell the controller not to filter duplicates; we want to process
|
||||
* repeated advertisements from the same device.
|
||||
*/
|
||||
disc_params.filter_duplicates = 0;
|
||||
|
||||
/**
|
||||
* Perform a passive scan. I.e., don't send follow-up scan requests to
|
||||
* each advertiser.
|
||||
*/
|
||||
disc_params.passive = 1;
|
||||
|
||||
/* Use defaults for the rest of the parameters. */
|
||||
disc_params.itvl = BLE_GAP_SCAN_ITVL_MS(40);
|
||||
disc_params.window = BLE_GAP_SCAN_WIN_MS(30);
|
||||
disc_params.filter_policy = 0;
|
||||
disc_params.limited = 0;
|
||||
|
||||
rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params, ble_gap_event, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
KLOG_ERROR(TAG, "Error initiating GAP discovery procedure; rc=%d", rc);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_advertise(void)
|
||||
{
|
||||
struct ble_gap_adv_params adv_params;
|
||||
|
||||
int rc = ble_gap_adv_set_data((const uint8_t *)&Advertising_Data, sizeof(Advertising_Data));
|
||||
if (rc != 0)
|
||||
{
|
||||
KLOG_ERROR(TAG, "Error setting advertisement data; rc=%d", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Begin advertising. */
|
||||
memset(&adv_params, 0, sizeof adv_params);
|
||||
adv_params.conn_mode = BLE_GAP_CONN_MODE_NON;
|
||||
adv_params.disc_mode = BLE_GAP_DISC_MODE_NON;
|
||||
|
||||
// N.B. High duty-cycle mode requires modification to NimBLE, or you will get an "Error enabling advertisement; rc=530"
|
||||
// adv_params.high_duty_cycle = 1;
|
||||
// adv_params.itvl_min = BLE_GAP_ADV_ITVL_MS(20);
|
||||
// adv_params.itvl_max = BLE_GAP_ADV_ITVL_MS(25);
|
||||
|
||||
adv_params.itvl_min = BLE_GAP_ADV_ITVL_MS(32);
|
||||
adv_params.itvl_max = BLE_GAP_ADV_ITVL_MS(37);
|
||||
|
||||
rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER,
|
||||
&adv_params, ble_gap_event, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
KLOG_ERROR(TAG, "Error enabling advertisement; rc=%d", rc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// https://mynewt.apache.org/latest/network/ble_setup/ble_sync_cb.html#reset
|
||||
static void ble_on_reset(int reason)
|
||||
{
|
||||
KLOG_ERROR(TAG, "Resetting state for reason %d.", reason);
|
||||
Host_And_Controller_Synced = false;
|
||||
}
|
||||
|
||||
// https://mynewt.apache.org/latest/network/ble_setup/ble_sync_cb.html#sync
|
||||
static void ble_on_sync(void)
|
||||
{
|
||||
KLOG_INFO(TAG, "Host and controller synchronized.");
|
||||
|
||||
/* Make sure we have proper identity address set (public preferred) */
|
||||
int rc = ble_hs_util_ensure_addr(0);
|
||||
assert(rc == 0);
|
||||
|
||||
Host_And_Controller_Synced = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The NimBLE host executes this callback when a GAP event occurs. The
|
||||
* application associates a GAP event callback with each connection that is
|
||||
* established. KTag uses the same callback for all connections.
|
||||
*
|
||||
* @param event The event being signalled.
|
||||
* @param arg Application-specified argument; unused by KTag.
|
||||
*
|
||||
* @return 0 if the application successfully handled the
|
||||
* event; nonzero on failure. The semantics
|
||||
* of the return code is specific to the
|
||||
* particular GAP event being signalled.
|
||||
*/
|
||||
static int ble_gap_event(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
struct ble_hs_adv_fields fields;
|
||||
int rc;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case BLE_GAP_EVENT_DISC:
|
||||
rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
|
||||
event->disc.length_data);
|
||||
if (rc != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
BLE_Packet_T *packet = BLE_DecodeKTagPacket(event->disc.data,
|
||||
event->disc.length_data,
|
||||
&(event->disc.addr.val[0]),
|
||||
event->disc.rssi);
|
||||
|
||||
if (packet != NULL)
|
||||
{
|
||||
if (packet->Generic.type == BLE_PACKET_TYPE_CONSOLE)
|
||||
{
|
||||
packet->Console.console_data[BLE_KTAG_PACKET_DATA_SIZE - 1] = '\0';
|
||||
HW_Execute_Console_Command(packet->Console.console_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
KEvent_T packet_received_event = {.ID = KEVENT_BLE_PACKET_RECEIVED, .Data = packet};
|
||||
Post_KEvent(&packet_received_event);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case BLE_GAP_EVENT_ADV_COMPLETE:
|
||||
KLOG_INFO(TAG, "Advertise complete; reason=%d", event->adv_complete.reason);
|
||||
ble_advertise();
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ble_host_task(void *param)
|
||||
{
|
||||
KLOG_INFO(TAG, "BLE Host Task Started");
|
||||
|
||||
// This function will return only after nimble_port_stop() is called:
|
||||
nimble_port_run();
|
||||
|
||||
nimble_port_freertos_deinit();
|
||||
}
|
||||
|
||||
void Initialize_BLE(void)
|
||||
{
|
||||
KLOG_INFO(TAG, "Initializing BLE...");
|
||||
|
||||
esp_err_t ret = nimble_port_init();
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
KLOG_ERROR(TAG, "Failed to initialize NimBLE for reason %d.", ret);
|
||||
return;
|
||||
}
|
||||
/* Configure the host. */
|
||||
ble_hs_cfg.reset_cb = ble_on_reset;
|
||||
ble_hs_cfg.sync_cb = ble_on_sync;
|
||||
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
|
||||
|
||||
ble_store_config_init();
|
||||
|
||||
nimble_port_freertos_init(ble_host_task);
|
||||
}
|
||||
|
||||
void Disable_BLE(void)
|
||||
{
|
||||
KLOG_INFO(TAG, "Disabling BLE...");
|
||||
|
||||
esp_err_t ret = nimble_port_deinit();
|
||||
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
KLOG_ERROR(TAG, "Failed to deinitialize NimBLE for reason %d.", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
KLOG_INFO(TAG, "NimBLE deinitialized--BLE disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
SystemKResult_T BLE_GetMyAddress(uint8_t *BD_ADDR)
|
||||
{
|
||||
/* Try to load a public address. */
|
||||
int result = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, BD_ADDR, NULL);
|
||||
if (result == BLE_HS_ENOADDR)
|
||||
{
|
||||
return SYSTEMK_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
SystemKResult_T BLE_SetAdvertisingData(BLE_AdvertisingData_T *data)
|
||||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
|
||||
|
||||
if (data->length > BLE_MAX_ADVERTISING_BYTES)
|
||||
{
|
||||
result = SYSTEMK_RESULT_TOO_MANY_DATA;
|
||||
}
|
||||
else if (data->length < BLE_KTAG_PACKET_TOTAL_SIZE)
|
||||
{
|
||||
result = SYSTEMK_RESULT_TOO_FEW_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(Advertising_Data, data, BLE_KTAG_PACKET_TOTAL_SIZE);
|
||||
}
|
||||
|
||||
if (Is_Scanning_And_Advertising == true)
|
||||
{
|
||||
// Restart advertising to put the new data into the advertisement.
|
||||
ble_gap_adv_stop();
|
||||
ble_advertise();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SystemKResult_T BLE_ScanAndAdvertise(void)
|
||||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_NOT_READY;
|
||||
|
||||
if (Host_And_Controller_Synced == true)
|
||||
{
|
||||
if (Is_Scanning_And_Advertising == false)
|
||||
{
|
||||
ble_scan();
|
||||
ble_advertise();
|
||||
Is_Scanning_And_Advertising = true;
|
||||
}
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue