Initial public release of the 2024A software.

This commit is contained in:
Joe Kearney 2025-01-25 14:04:42 -06:00
parent 7b9ad3edfd
commit 303e9e1dad
361 changed files with 60083 additions and 2 deletions

276
components/BLE/BLE.c Normal file
View 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;
}

4
components/BLE/BLE.h Normal file
View file

@ -0,0 +1,4 @@
#include "esp_err.h"
void Initialize_BLE(void);
void Disable_BLE(void);

View file

@ -0,0 +1,10 @@
idf_component_register(
SRCS
"BLE.c"
INCLUDE_DIRS
"."
REQUIRES
"SystemK"
"driver"
"bt"
)