Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/Alarm.cpp
displayapp/screens/Styles.cpp
displayapp/screens/WeatherSymbols.cpp
displayapp/screens/Home.cpp
displayapp/Colors.cpp
displayapp/widgets/Counter.cpp
displayapp/widgets/PageIndicator.cpp
Expand Down Expand Up @@ -466,6 +467,7 @@ list(APPEND SOURCE_FILES
components/ble/ServiceDiscovery.cpp
components/ble/HeartRateService.cpp
components/ble/MotionService.cpp
components/ble/HomeService.cpp
components/firmwarevalidator/FirmwareValidator.cpp
components/motor/MotorController.cpp
components/settings/Settings.cpp
Expand Down Expand Up @@ -658,6 +660,7 @@ set(INCLUDE_FILES
components/ble/HeartRateService.h
components/ble/MotionService.h
components/ble/SimpleWeatherService.h
components/ble/HomeService.h
components/settings/Settings.h
components/timer/Timer.h
components/stopwatch/StopWatchController.h
Expand Down
144 changes: 144 additions & 0 deletions src/components/ble/HomeService.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#include "HomeService.h"

#include <libraries/log/nrf_log.h>
#include "components/ble/NimbleController.h"

namespace {
// 0006yyxx-78fc-48fe-8e23-433b3a1942d0
constexpr ble_uuid128_t CharUuid(uint8_t x, uint8_t y) {
return ble_uuid128_t {.u = {.type = BLE_UUID_TYPE_128},
.value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x06, 0x00}};
}

// 00060000-78fc-48fe-8e23-433b3a1942d0
constexpr ble_uuid128_t BaseUuid() {
return CharUuid(0x00, 0x00);
}

constexpr ble_uuid128_t homeUuid {BaseUuid()};

constexpr ble_uuid128_t homeOpenUuid {CharUuid(0x01, 0x00)};
constexpr ble_uuid128_t homeLayoutUuid {CharUuid(0x02, 0x00)};
constexpr ble_uuid128_t homePressUuid {CharUuid(0x03, 0x00)};

int HomeCallback(uint16_t /*conn_handle*/, uint16_t /*attr_handle*/, struct ble_gatt_access_ctxt* ctxt, void* arg) {
return static_cast<Pinetime::Controllers::HomeService*>(arg)->OnCommand(ctxt);
}
} // namespace

Pinetime::Controllers::HomeService::HomeService(NimbleController& nimble) : nimble(nimble) {
characteristicDefinition[0] = {.uuid = &homeLayoutUuid.u, .access_cb = HomeCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE};
characteristicDefinition[1] = {.uuid = &homeOpenUuid.u,
.access_cb = HomeCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_NOTIFY,
.val_handle = &eventOpenedHandle};
characteristicDefinition[2] = {.uuid = &homePressUuid.u,
.access_cb = HomeCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_NOTIFY,
.val_handle = &eventPressedHandle};
characteristicDefinition[3] = {0};

serviceDefinition[0] = {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &homeUuid.u, .characteristics = characteristicDefinition};
serviceDefinition[1] = {0};
}

void Pinetime::Controllers::HomeService::Init() {
uint8_t res = 0;
res = ble_gatts_count_cfg(serviceDefinition);
ASSERT(res == 0);

res = ble_gatts_add_svcs(serviceDefinition);
ASSERT(res == 0);
}

int Pinetime::Controllers::HomeService::OnCommand(ble_gatt_access_ctxt* ctxt) {
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
size_t bufferSize = OS_MBUF_PKTLEN(ctxt->om);

uint8_t data[bufferSize];
os_mbuf_copydata(ctxt->om, 0, bufferSize, data);

if (ble_uuid_cmp(ctxt->chr->uuid, &homeLayoutUuid.u) == 0) {
auto screen = std::make_unique<Screen>();
uint8_t* ptr = &data[0];

numScreens = *ptr++;
screen->index = *ptr++;

screen->cols = *ptr >> 4;
screen->rows = *ptr & 0x0F;
ptr++;
uint8_t num_comps = *(ptr++);

for (size_t j = 0; j < num_comps; j++) {
Component comp;
comp.type = (ComponentType) (*(ptr++));

comp.x = *ptr >> 4;
comp.y = *ptr & 0x0F;
ptr++;
comp.w = *ptr >> 4;
comp.h = *ptr & 0x0F;
ptr++;

uint8_t label_len = *(ptr++);
auto label = std::make_unique<char[]>(label_len + 1);
memcpy(label.get(), ptr, label_len);
label.get()[label_len] = 0;
ptr += label_len;

comp.label = std::move(label);

screen->components.emplace_back(std::move(comp));
}

currentScreen = std::move(screen);
dataUpdateTime = xTaskGetTickCount();
}
}

return 0;
}

bool Pinetime::Controllers::HomeService::NotifyOpened(int8_t screenIndex) {
uint16_t connectionHandle = nimble.connHandle();

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

auto* om = ble_hs_mbuf_from_flat(&screenIndex, sizeof(screenIndex));
ble_gattc_notify_custom(connectionHandle, eventOpenedHandle, om);

return true;
}

bool Pinetime::Controllers::HomeService::OnOpened() {
return NotifyOpened(0);
}

void Pinetime::Controllers::HomeService::OnViewScreen(uint8_t n) {
NotifyOpened(n);
}

void Pinetime::Controllers::HomeService::OnClosed() {
dataUpdateTime = 0;
numScreens = 0;
currentScreen.reset();

NotifyOpened(-1);
}

void Pinetime::Controllers::HomeService::OnPressed(uint8_t screen, uint8_t componentId) {
uint16_t connectionHandle = nimble.connHandle();

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

uint8_t v[] = {screen, componentId};
auto* om = ble_hs_mbuf_from_flat(v, sizeof(v));
ble_gattc_notify_custom(connectionHandle, eventPressedHandle, om);
}
70 changes: 70 additions & 0 deletions src/components/ble/HomeService.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#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 <atomic>
#include <memory>
#include <vector>

namespace Pinetime {
namespace Controllers {
class NimbleController;

class HomeService {
public:
enum ComponentType : uint8_t {
Button,
Label,
};

struct Component {
ComponentType type;
uint8_t x, y, w, h;
std::unique_ptr<char[]> label;
};

struct Screen {
uint8_t index, rows, cols;
std::vector<Component> components {};
};

HomeService(NimbleController& nimble);
void Init();

int OnCommand(struct ble_gatt_access_ctxt* ctxt);

bool OnOpened();
void OnViewScreen(uint8_t n);
void OnClosed();
void OnPressed(uint8_t screen, uint8_t componentId);

TickType_t DataUpdateTime() {
return dataUpdateTime;
}

const Screen& CurrentScreen() {
return *currentScreen.get();
}

uint8_t NumScreens() {
return numScreens;
}

private:
NimbleController& nimble;

uint16_t eventOpenedHandle {}, eventPressedHandle;

std::unique_ptr<Screen> currentScreen;
TickType_t dataUpdateTime = 0;
uint8_t numScreens;

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

bool NotifyOpened(int8_t screenIndex);
};
}
}
4 changes: 3 additions & 1 deletion src/components/ble/NimbleController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask,
heartRateService {*this, heartRateController},
motionService {*this, motionController},
fsService {systemTask, fs},
serviceDiscovery({&currentTimeClient, &alertNotificationClient}) {
serviceDiscovery({&currentTimeClient, &alertNotificationClient}),
homeService {*this} {
}

void nimble_on_reset(int reason) {
Expand Down Expand Up @@ -98,6 +99,7 @@ void NimbleController::Init() {
heartRateService.Init();
motionService.Init();
fsService.Init();
homeService.Init();

int rc;
rc = ble_hs_util_ensure_addr(0);
Expand Down
6 changes: 6 additions & 0 deletions src/components/ble/NimbleController.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "components/ble/ServiceDiscovery.h"
#include "components/ble/MotionService.h"
#include "components/ble/SimpleWeatherService.h"
#include "components/ble/HomeService.h"
#include "components/fs/FS.h"

namespace Pinetime {
Expand Down Expand Up @@ -71,6 +72,10 @@ namespace Pinetime {
return weatherService;
};

Pinetime::Controllers::HomeService& home() {
return homeService;
};

uint16_t connHandle();
void NotifyBatteryLevel(uint8_t level);

Expand Down Expand Up @@ -107,6 +112,7 @@ namespace Pinetime {
MotionService motionService;
FSService fsService;
ServiceDiscovery serviceDiscovery;
HomeService homeService;

uint8_t addrType;
uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/displayapp/Controllers.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace Pinetime {
class Timer;
class MusicService;
class NavigationService;
class HomeService;
}

namespace System {
Expand Down Expand Up @@ -53,6 +54,7 @@ namespace Pinetime {
Pinetime::Components::LittleVgl& lvgl;
Pinetime::Controllers::MusicService* musicService;
Pinetime::Controllers::NavigationService* navigationService;
Pinetime::Controllers::HomeService* homeService;
};
}
}
4 changes: 4 additions & 0 deletions src/displayapp/DisplayApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,10 @@ void DisplayApp::Register(Pinetime::Controllers::NavigationService* NavigationSe
this->controllers.navigationService = NavigationService;
}

void DisplayApp::Register(Pinetime::Controllers::HomeService* homeService) {
this->controllers.homeService = homeService;
}

void DisplayApp::ApplyBrightness() {
auto brightness = settingsController.GetBrightness();
if (brightness != Controllers::BrightnessController::Levels::Low && brightness != Controllers::BrightnessController::Levels::Medium &&
Expand Down
1 change: 1 addition & 0 deletions src/displayapp/DisplayApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ namespace Pinetime {
void Register(Pinetime::Controllers::SimpleWeatherService* weatherService);
void Register(Pinetime::Controllers::MusicService* musicService);
void Register(Pinetime::Controllers::NavigationService* NavigationService);
void Register(Pinetime::Controllers::HomeService* homeService);

private:
Pinetime::Drivers::St7789& lcd;
Expand Down
1 change: 1 addition & 0 deletions src/displayapp/UserApps.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "displayapp/screens/Timer.h"
#include "displayapp/screens/Twos.h"
#include "displayapp/screens/Tile.h"
#include "displayapp/screens/Home.h"
#include "displayapp/screens/ApplicationList.h"
#include "displayapp/screens/WatchFaceDigital.h"
#include "displayapp/screens/WatchFaceAnalog.h"
Expand Down
1 change: 1 addition & 0 deletions src/displayapp/apps/Apps.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace Pinetime {
Dice,
Weather,
PassKey,
Home,
QuickSettings,
Settings,
SettingWatchFace,
Expand Down
1 change: 1 addition & 0 deletions src/displayapp/apps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ else ()
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Navigation")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Calculator")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Weather")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Home")
#set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Motion")
set(USERAPP_TYPES "${DEFAULT_USER_APP_TYPES}" CACHE STRING "List of user apps to build into the firmware")
endif ()
Expand Down
Loading
Loading