TinyCTS
Bluetooth Current Time Service client and server for Arduino
Loading...
Searching...
No Matches
TinyCTSServerNimBLE.h
Go to the documentation of this file.
1
6
7#pragma once
8#include <NimBLEDevice.h>
9
11
12namespace tiny_cts {
13
38class TinyCTSServer : public TinyCTSServerBase, public NimBLECharacteristicCallbacks {
39 public:
40 TinyCTSServer() = default;
41
50 bool begin(TinyCTSTimeSource& source, const char* deviceName = "TinyCTS") {
51 _source = &source;
52 if (!NimBLEDevice::isInitialized()) NimBLEDevice::init(deviceName);
53 NimBLEServer* server = NimBLEDevice::getServer();
54 if (server == nullptr) server = NimBLEDevice::createServer();
55 if (server == nullptr) return false;
56 server->advertiseOnDisconnect(true);
57
58 NimBLEService* service = server->createService(NimBLEUUID(CTS_SERVICE_UUID));
59 if (service == nullptr) return false;
60
61 uint32_t current = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY;
62 uint32_t local = NIMBLE_PROPERTY::READ;
63 if (_settable) {
64 current |= NIMBLE_PROPERTY::WRITE;
65 local |= NIMBLE_PROPERTY::WRITE;
66 if (_encrypted) {
67 current |= NIMBLE_PROPERTY::WRITE_ENC;
68 local |= NIMBLE_PROPERTY::WRITE_ENC;
69 }
70 }
71 _current = service->createCharacteristic(NimBLEUUID(CTS_CURRENT_TIME_UUID), current);
72 _local = service->createCharacteristic(NimBLEUUID(CTS_LOCAL_TIME_INFO_UUID), local);
73 _reference = service->createCharacteristic(
74 NimBLEUUID(CTS_REFERENCE_TIME_INFO_UUID), NIMBLE_PROPERTY::READ);
75 if (_current == nullptr || _local == nullptr || _reference == nullptr) return false;
76 _current->setCallbacks(this);
77 _local->setCallbacks(this);
78 _reference->setCallbacks(this);
79 updateCurrent(0);
80 updateLocal();
81 updateReference();
82 if (!server->start()) return false; // starts the services
83
84 NimBLEAdvertising* adv = NimBLEDevice::getAdvertising();
85 adv->addServiceUUID(NimBLEUUID(CTS_SERVICE_UUID));
86 adv->enableScanResponse(true);
87 return adv->start();
88 }
89
91 void end() {
92 NimBLEDevice::getAdvertising()->stop();
93 _source = nullptr;
94 }
95
100 bool process() {
101 if (_current == nullptr || !notifyDue()) return false;
102 return notifyTime(0);
103 }
104
106 bool notifyTime(uint8_t adjustReason = 0) {
107 if (_current == nullptr) return false;
108 updateCurrent(adjustReason);
109 return _current->notify();
110 }
111
112 protected:
113 void onTimeZoneChanged() override {
114 if (_local == nullptr) return;
115 updateLocal();
116 notifyTime(TinyCTSCurrentTime::TimeZoneChange);
117 }
118
119 void onReferenceChanged() override {
120 if (_reference != nullptr) updateReference();
121 }
122
123 void onRead(NimBLECharacteristic* chr, NimBLEConnInfo&) override {
124 if (chr == _current) updateCurrent(0);
125 }
126
127 void onWrite(NimBLECharacteristic* chr, NimBLEConnInfo&) override {
128 NimBLEAttValue value = chr->getValue();
129 if (chr == _current) {
130 if (setTimeFromWrite(value.data(), value.size())) {
131 notifyTime(TinyCTSCurrentTime::ManualUpdate);
132 } else {
133 updateCurrent(0); // refused: show the real time again
134 }
135 } else if (chr == _local) {
136 setTimeZoneFromWrite(value.data(), value.size());
137 updateLocal();
138 notifyTime(TinyCTSCurrentTime::TimeZoneChange);
139 }
140 }
141
142 void updateCurrent(uint8_t reason) {
143 uint8_t data[TinyCTSCurrentTime::Size];
144 _current->setValue(data, currentTimeValue(reason, data));
145 }
146
147 void updateLocal() {
148 uint8_t data[TinyCTSLocalTimeInfo::Size];
149 _local->setValue(data, localTimeValue(data));
150 }
151
152 void updateReference() {
153 uint8_t data[TinyCTSReferenceTimeInfo::Size];
154 _reference->setValue(data, referenceTimeValue(data));
155 }
156
157 NimBLECharacteristic* _current = nullptr;
158 NimBLECharacteristic* _local = nullptr;
159 NimBLECharacteristic* _reference = nullptr;
160};
161
162} // namespace tiny_cts
The logic of the Current Time Service server, independent of the Bluetooth stack: the values of the c...
constexpr uint16_t CTS_CURRENT_TIME_UUID
16 bit UUID of the Current Time characteristic (read, notify, write)
Definition TinyCTSTypes.h:19
constexpr uint16_t CTS_SERVICE_UUID
16 bit UUID of the Current Time Service
Definition TinyCTSTypes.h:17
constexpr uint16_t CTS_REFERENCE_TIME_INFO_UUID
16 bit UUID of the Reference Time Information characteristic (read)
Definition TinyCTSTypes.h:23
constexpr uint16_t CTS_LOCAL_TIME_INFO_UUID
16 bit UUID of the Local Time Information characteristic (read, write)
Definition TinyCTSTypes.h:21
Settings and values of a TinyCTSServer. Use TinyCTSServer, which adds the Bluetooth part.
Definition TinyCTSServerBase.h:22
bool setTimeZoneFromWrite(const uint8_t *data, size_t len)
Definition TinyCTSServerBase.h:117
bool setTimeFromWrite(const uint8_t *data, size_t len)
Definition TinyCTSServerBase.h:102
bool notifyDue()
Definition TinyCTSServerBase.h:125
size_t currentTimeValue(uint8_t reason, uint8_t *out)
Definition TinyCTSServerBase.h:84
A BLE peripheral that offers the Current Time Service (0x1805) and serves the time of a time source t...
Definition TinyCTSServerDesktop.h:40
void end()
Stop advertising.
Definition TinyCTSServerNimBLE.h:91
bool begin(TinyCTSTimeSource &source, const char *deviceName="TinyCTS")
Start the service and the advertising. NimBLEDevice::init() is called with the name,...
Definition TinyCTSServerNimBLE.h:50
void onTimeZoneChanged() override
Definition TinyCTSServerNimBLE.h:113
bool process()
Call this regularly in loop(): it sends the notifications.
Definition TinyCTSServerNimBLE.h:100
void onReferenceChanged() override
Definition TinyCTSServerNimBLE.h:119
bool notifyTime(uint8_t adjustReason=0)
Notify the subscribed clients now.
Definition TinyCTSServerDesktop.h:95
bool onRead(uint16_t uuid, std::vector< uint8_t > &value) override
Definition TinyCTSServerDesktop.h:113
bool onWrite(uint16_t uuid, const uint8_t *data, size_t len) override
Definition TinyCTSServerDesktop.h:129
Abstract base class of the time sources: an object that knows the current UTC time.
Definition TinyCTSTimeSource.h:51
static constexpr size_t Size
Size of the encoded characteristic.
Definition TinyCTSTypes.h:70