Skip to content

Commit

Permalink
Add ImmediateAlertClient to support FindMyPhone functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
vchigrin committed Nov 28, 2024
1 parent 832d38f commit 24f5fbd
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ target_sources(infinisim PUBLIC
sim/components/battery/BatteryController.cpp
sim/components/ble/MusicService.h
sim/components/ble/MusicService.cpp
sim/components/ble/ImmediateAlertClient.h
sim/components/ble/ImmediateAlertClient.cpp
sim/components/ble/NimbleController.h
sim/components/ble/NimbleController.cpp
sim/components/brightness/BrightnessController.h
Expand Down
114 changes: 114 additions & 0 deletions sim/components/ble/ImmediateAlertClient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#include "components/ble/ImmediateAlertClient.h"
#include <cstring>
#include <nrf_log.h>
#include "systemtask/SystemTask.h"

using namespace Pinetime::Controllers;

constexpr ble_uuid16_t ImmediateAlertClient::immediateAlertClientUuid;
constexpr ble_uuid16_t ImmediateAlertClient::alertLevelCharacteristicUuid;

// namespace {
// int OnDiscoveryEventCallback(uint16_t conn_handle, const struct ble_gatt_error* error, const struct ble_gatt_svc* service, void* arg) {
// auto client = static_cast<ImmediateAlertClient*>(arg);
// return client->OnDiscoveryEvent(conn_handle, error, service);
// }

// int OnImmediateAlertCharacteristicDiscoveredCallback(uint16_t conn_handle,
// const struct ble_gatt_error* error,
// const struct ble_gatt_chr* chr,
// void* arg) {
// auto client = static_cast<ImmediateAlertClient*>(arg);
// return client->OnCharacteristicDiscoveryEvent(conn_handle, error, chr);
// }
// }

ImmediateAlertClient::ImmediateAlertClient(Pinetime::System::SystemTask& systemTask)
: systemTask {systemTask},
characteristicDefinition {{
.uuid = &alertLevelCharacteristicUuid.u,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
},
{0}},
serviceDefinition {
{/* Device Information Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &immediateAlertClientUuid.u,
.characteristics = characteristicDefinition},
{0},
} {
}

void ImmediateAlertClient::Init() {
}

bool ImmediateAlertClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service) {
// if (service == nullptr && error->status == BLE_HS_EDONE) {
// if (isDiscovered) {
// NRF_LOG_INFO("IAS found, starting characteristics discovery");

// ble_gattc_disc_all_chrs(connectionHandle, iasStartHandle, iasEndHandle, OnImmediateAlertCharacteristicDiscoveredCallback, this);
// } else {
// NRF_LOG_INFO("IAS not found");
// onServiceDiscovered(connectionHandle);
// }
// return true;
// }

// if (service != nullptr && ble_uuid_cmp(&immediateAlertClientUuid.u, &service->uuid.u) == 0) {
// NRF_LOG_INFO("IAS discovered : 0x%x - 0x%x", service->start_handle, service->end_handle);
// isDiscovered = true;
// iasStartHandle = service->start_handle;
// iasEndHandle = service->end_handle;
// }
return false;
}

int ImmediateAlertClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle,
const ble_gatt_error* error,
const ble_gatt_chr* characteristic) {

// if (error->status != 0 && error->status != BLE_HS_EDONE) {
// NRF_LOG_INFO("IAS Characteristic discovery ERROR");
// onServiceDiscovered(conn_handle);
// return 0;
// }

// if (characteristic == nullptr && error->status == BLE_HS_EDONE) {
// if (!isCharacteristicDiscovered) {
// NRF_LOG_INFO("IAS Characteristic discovery unsuccessful");
// onServiceDiscovered(conn_handle);
// }

// return 0;
// }

// if (characteristic != nullptr && ble_uuid_cmp(&alertLevelCharacteristicUuid.u, &characteristic->uuid.u) == 0) {
// NRF_LOG_INFO("AIS Characteristic discovered : 0x%x", characteristic->val_handle);
// isCharacteristicDiscovered = true;
// alertLevelHandle = characteristic->val_handle;
// }
return 0;
}

void ImmediateAlertClient::Discover(uint16_t connectionHandle, std::function<void(uint16_t)> onServiceDiscovered) {
NRF_LOG_INFO("[IAS] Starting discovery");
this->onServiceDiscovered = onServiceDiscovered;
// ble_gattc_disc_svc_by_uuid(connectionHandle, &immediateAlertClientUuid.u, OnDiscoveryEventCallback, this);
}

bool ImmediateAlertClient::sendImmediateAlert(ImmediateAlertClient::Levels level) {

// auto* om = ble_hs_mbuf_from_flat(&level, 1);

// uint16_t connectionHandle = systemTask.nimble().connHandle();

// if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) {
// return false;
// }

// ble_gattc_write_no_rsp(connectionHandle, alertLevelHandle, om);
// return true;
return false;
}
61 changes: 61 additions & 0 deletions sim/components/ble/ImmediateAlertClient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once
#define min // workaround: nimble's min/max macros conflict with libstdc++
#define max
#include <host/ble_gap.h>
#undef max
#undef min
#include <cstdint>
#include "components/ble/BleClient.h"

namespace Pinetime {
namespace System {
class SystemTask;
}

namespace Controllers {
class NotificationManager;

class ImmediateAlertClient : public BleClient {
public:
enum class Levels : uint8_t { NoAlert = 0, MildAlert = 1, HighAlert = 2 };

ImmediateAlertClient(Pinetime::System::SystemTask& systemTask);
void Init();

bool OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service);
int OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error* error, const ble_gatt_chr* characteristic);

bool sendImmediateAlert(Levels level);

static constexpr const ble_uuid16_t* Uuid() {
return &ImmediateAlertClient::immediateAlertClientUuid;
}

static constexpr const ble_uuid16_t* AlertLevelCharacteristicUuid() {
return &ImmediateAlertClient::alertLevelCharacteristicUuid;
}

void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override;

private:
Pinetime::System::SystemTask& systemTask;

static constexpr uint16_t immediateAlertClientId {0x1802};
static constexpr uint16_t alertLevelId {0x2A06};

static constexpr ble_uuid16_t immediateAlertClientUuid {.u {.type = BLE_UUID_TYPE_16}, .value = immediateAlertClientId};
static constexpr ble_uuid16_t alertLevelCharacteristicUuid {.u {.type = BLE_UUID_TYPE_16}, .value = alertLevelId};

bool isDiscovered = false;
uint16_t iasStartHandle;
uint16_t iasEndHandle;
bool isCharacteristicDiscovered = false;

struct ble_gatt_chr_def characteristicDefinition[3];
struct ble_gatt_svc_def serviceDefinition[2];

uint16_t alertLevelHandle;
std::function<void(uint16_t)> onServiceDiscovered;
};
}
}
2 changes: 2 additions & 0 deletions sim/components/ble/NimbleController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask,
// currentTimeService {dateTimeController},
musicService {systemTask},
weatherService {dateTimeController},
iaClient {systemTask},
// batteryInformationService {batteryController},
// immediateAlertService {systemTask, notificationManager},
// heartRateService {systemTask, heartRateController},
Expand Down Expand Up @@ -91,6 +92,7 @@ void NimbleController::Init() {
musicService.Init();
weatherService.Init();
navService.Init();
iaClient.Init();
// anService.Init();
// dfuService.Init();
// batteryInformationService.Init();
Expand Down
5 changes: 5 additions & 0 deletions sim/components/ble/NimbleController.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
//#include "components/ble/DfuService.h"
//#include "components/ble/HeartRateService.h"
//#include "components/ble/ImmediateAlertService.h"
#include "components/ble/ImmediateAlertClient.h"
#include "components/ble/MusicService.h"
#include "components/ble/NavigationService.h"
//#include "components/ble/ServiceDiscovery.h"
Expand Down Expand Up @@ -81,6 +82,9 @@ namespace Pinetime {
Pinetime::Controllers::SimpleWeatherService& weather() {
return weatherService;
};
Pinetime::Controllers::ImmediateAlertClient& immediateAlertClient() {
return iaClient;
};

uint16_t connHandle();
void NotifyBatteryLevel(uint8_t level);
Expand Down Expand Up @@ -115,6 +119,7 @@ namespace Pinetime {
NavigationService navService;
// BatteryInformationService batteryInformationService;
// ImmediateAlertService immediateAlertService;
ImmediateAlertClient iaClient;
// HeartRateService heartRateService;
MotionService motionService;
// FSService fsService;
Expand Down

0 comments on commit 24f5fbd

Please sign in to comment.