GCC Code Coverage Report


Directory: src/gate/
File: src/gate/system/cxx_devices.cpp
Date: 2026-05-04 21:11:01
Exec Total Coverage
Lines: 0 148 0.0%
Functions: 0 40 0.0%
Branches: 0 118 0.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2026, Stefan Meislinger |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/system/devices.hpp"
30 #include "gate/exceptions.hpp"
31
32 namespace gate
33 {
34 namespace sys
35 {
36
37 Bluetooth::Device::Device() noexcept
38 {
39 }
40
41 Bluetooth::Device::Device(gate_device_bth_t const& bth) noexcept
42 {
43 Mem::copy(this->impl, bth);
44 }
45
46 gate_device_bth_t* Bluetooth::Device::c_impl() noexcept
47 {
48 return &this->impl;
49 }
50
51 gate_device_bth_t const* Bluetooth::Device::c_impl() const noexcept
52 {
53 return &this->impl;
54 }
55
56 String Bluetooth::Device::getUid() const
57 {
58 return this->impl.uid;
59 }
60 String Bluetooth::Device::getName() const
61 {
62 return this->impl.name;
63 }
64 String Bluetooth::Device::getAddress() const
65 {
66 return this->impl.address;
67 }
68 uint32_t Bluetooth::Device::getDeviceClass() const noexcept
69 {
70 return this->impl.device_class;
71 }
72 bool_t Bluetooth::Device::isConnected() const noexcept
73 {
74 return this->impl.connected;
75 }
76 bool_t Bluetooth::Device::isAuthenticated() const noexcept
77 {
78 return this->impl.authenticated;
79 }
80 Time Bluetooth::Device::getLastSeenTime() const
81 {
82 return Time(this->impl.last_seen, 0);
83 }
84 Time Bluetooth::Device::getLastUsedTime() const
85 {
86 return Time(this->impl.last_used, 0);
87 }
88
89 Bluetooth::Bluetooth()
90 {
91 }
92
93 struct GATE_API_LOCAL BluetoothDispatcherParam
94 {
95 Bluetooth::DeviceEnumCallback const* ptrCb;
96 };
97
98 static gate_bool_t GATE_CALL Bluetooth_enumDevices_dispatcher(gate_device_bth_t const* bth_dev, void* param)
99 {
100 BluetoothDispatcherParam* ptrParam = static_cast<BluetoothDispatcherParam*>(param);
101 if (ptrParam && ptrParam->ptrCb)
102 {
103 Bluetooth::Device dev(*bth_dev);
104 ptrParam->ptrCb->invoke(&dev);
105 }
106 return true;
107 }
108
109 void Bluetooth::enumDevices(DeviceEnumCallback const& cb)
110 {
111 BluetoothDispatcherParam param;
112 param.ptrCb = &cb;
113 result_t result = gate_device_bth_enum(&Bluetooth_enumDevices_dispatcher, &param);
114 GATEXX_CHECK_EXCEPTION(result);
115 }
116
117 static gate_bool_t GATE_CALL Bluetooth_enumDevices_array_dispatcher(gate_device_bth_t const* bth_dev, void* param)
118 {
119 ArrayList<Bluetooth::Device>* ptrList = static_cast<ArrayList<Bluetooth::Device>*>(param);
120 if (ptrList)
121 {
122 ptrList->add(Bluetooth::Device(*bth_dev));
123 }
124 return true;
125 }
126
127 Array<Bluetooth::Device> Bluetooth::enumDevices()
128 {
129 ArrayList<Bluetooth::Device> list;
130 result_t result = gate_device_bth_enum(&Bluetooth_enumDevices_array_dispatcher, &list);
131 GATEXX_CHECK_EXCEPTION(result);
132 return list.toArray();
133 }
134
135
136
137
138 BluetoothLE::Device::Device() noexcept
139 {
140 Mem::clear(this->impl);
141 }
142
143 BluetoothLE::Device::Device(gate_device_bthle_t const& bthle) noexcept
144 : impl(bthle)
145 {
146 }
147
148 gate_device_bthle_t* BluetoothLE::Device::c_impl() noexcept
149 {
150 return &this->impl;
151 }
152
153 gate_device_bthle_t const* BluetoothLE::Device::c_impl() const noexcept
154 {
155 return &this->impl;
156 }
157
158 String BluetoothLE::Device::getUid() const
159 {
160 return String(this->impl.uid);
161 }
162
163 String BluetoothLE::Device::getName() const
164 {
165 return String(this->impl.name);
166 }
167
168 String BluetoothLE::Device::getAddress() const
169 {
170 return String(this->impl.address);
171 }
172
173 Array<BluetoothLE::Service> BluetoothLE::Device::getServices() const
174 {
175 Array<BluetoothLE::Service> arr(this->impl.services, this->impl.service_count);
176 return arr;
177 }
178
179
180 BluetoothLE::BluetoothLE()
181 {
182 }
183
184 BluetoothLE::~BluetoothLE()
185 {
186 }
187
188 static gate_bool_t GATE_CALL bthle_enum_cb(gate_device_bthle_t const* device, void* param)
189 {
190 BluetoothLE::DeviceEnumCallback const* cb = static_cast<BluetoothLE::DeviceEnumCallback const*>(param);
191 if (cb)
192 {
193 BluetoothLE::Device leDevice(*device);
194 ExceptionInfo xcptStatus;
195 GATEXX_TRY_CATCHINFO(xcptStatus, {
196 cb->invoke(&leDevice);
197 });
198 return xcptStatus.succeeded();
199 }
200 else
201 {
202 return true;
203 }
204 }
205
206 static gate_bool_t GATE_CALL bthle_enum_devices_cb(gate_device_bthle_t const* device, void* param)
207 {
208 ArrayList<BluetoothLE::Device>* devices = static_cast<ArrayList<BluetoothLE::Device>*>(param);
209 if (devices && device)
210 {
211 devices->tryAdd(BluetoothLE::Device(*device));
212 }
213 return true;
214 }
215
216 void BluetoothLE::enumDevices(DeviceEnumCallback const& cb)
217 {
218 result_t result = gate_device_bthle_enum(&bthle_enum_cb, (void*)&cb);
219 GATEXX_CHECK_EXCEPTION(result);
220 }
221
222 Array<BluetoothLE::Device> BluetoothLE::enumDevices()
223 {
224 ArrayList<Device> devices;
225 result_t result = gate_device_bthle_enum(&bthle_enum_devices_cb, static_cast<void*>(&devices));
226 GATEXX_CHECK_EXCEPTION(result);
227 return devices.toArray();
228 }
229
230 BluetoothLE::Device BluetoothLE::getDeviceByUid(String const& uid)
231 {
232 gate_device_bthle_t device;
233 result_t result = gate_device_bthle_get(uid.c_impl(), &device);
234 GATEXX_CHECK_EXCEPTION(result);
235 return Device(device);
236 }
237
238 BluetoothLE::Device BluetoothLE::getDeviceByAddress(String const& address)
239 {
240 gate_device_bthle_t device;
241 result_t result = gate_device_bthle_get_by_address(address.c_impl(), &device);
242 GATEXX_CHECK_EXCEPTION(result);
243 return Device(device);
244 }
245
246 struct GATE_API_LOCAL bthle_chara_cb_param
247 {
248 BluetoothLE::Device const* device;
249 BluetoothLE::Service const* service;
250 BluetoothLE::CharacteristicsEnumCallback const* cb;
251 };
252
253 static gate_bool_t GATE_CALL bthle_chara_cb(gate_device_bthle_characteristic_t const* chara, void* user_param)
254 {
255 bthle_chara_cb_param* param = static_cast<bthle_chara_cb_param*>(user_param);
256 if (param)
257 {
258 GATEXX_TRY_IGNORE({
259 param->cb->invoke(param->device, param->service, chara);
260 });
261 }
262 return true;
263 }
264
265 static BluetoothLE::Service const* resolveBthLEService(BluetoothLE::Device const& device, Guid const& serviceGuid)
266 {
267 gate_device_bthle_service_t const* const services = &device.c_impl()->services[0];
268 gate_size_t const service_count = device.c_impl()->service_count;
269
270 for (size_t ndx = 0; ndx != service_count; ++ndx)
271 {
272 if (serviceGuid == services[ndx].service_guid)
273 {
274 return &services[ndx];
275 }
276 }
277 return NULL;
278 }
279
280 void BluetoothLE::enumCharacteristics(Device const& device, Guid const& serviceGuid, CharacteristicsEnumCallback const& cb)
281 {
282 Service const* const ptrSvc = resolveBthLEService(device, serviceGuid);
283 if (ptrSvc == NULL)
284 {
285 GATEXX_RAISE_EXCEPTION(results::InvalidArg, "Invalid service GUID", 0);
286 }
287 bthle_chara_cb_param param;
288 param.device = &device;
289 param.service = ptrSvc;
290 param.cb = &cb;
291 result_t result = gate_device_bthle_service_enum(device.c_impl(), ptrSvc, &bthle_chara_cb, &param);
292 GATEXX_CHECK_EXCEPTION(result);
293 }
294
295 static gate_bool_t GATE_CALL bthle_chara_guid_cb(gate_device_bthle_characteristic_t const* chara, void* user_param)
296 {
297 ArrayList<Guid>* guids = static_cast<ArrayList<Guid>*>(user_param);
298 if (guids)
299 {
300 guids->tryAdd(Guid(chara->characteristic_guid));
301 }
302 return true;
303 }
304
305 Array<Guid> BluetoothLE::enumCharacteristicsGuids(Device const& device, Guid const& serviceGuid)
306 {
307 ArrayList<Guid> guids;
308 Service const* const ptrSvc = resolveBthLEService(device, serviceGuid);
309 if (ptrSvc == NULL)
310 {
311 GATEXX_RAISE_EXCEPTION(results::InvalidArg, "Invalid service GUID", 0);
312 }
313 result_t result = gate_device_bthle_service_enum(device.c_impl(), ptrSvc, &bthle_chara_guid_cb, &guids);
314 GATEXX_CHECK_EXCEPTION(result);
315 return guids.toArray();
316 }
317
318
319 Blob BluetoothLE::getCharacteristicValue(Device const& device, Guid const& serviceGuid, Guid const& charaGuid)
320 {
321 char buffer[4096];
322 gate_size_t bufferLen = sizeof(buffer);
323 result_t result = gate_device_bthle_characteristic_get(device.c_impl(), &serviceGuid, &charaGuid, buffer, &bufferLen);
324 GATEXX_CHECK_EXCEPTION(result);
325
326 if (bufferLen > sizeof(buffer))
327 {
328 GATEXX_RAISE_ERROR(results::OutOfBounds);
329 }
330 return Blob(&buffer[0], bufferLen);
331 }
332
333 void BluetoothLE::setCharacteristicValue(Device const& device, Guid const& serviceGuid, Guid const& charaGuid, Blob const& value)
334 {
335 result_t result = gate_device_bthle_characteristic_set(device.c_impl(), &serviceGuid, &charaGuid,
336 static_cast<char const*>(value.data()), value.length());
337 GATEXX_CHECK_EXCEPTION(result);
338 }
339
340
341 } // end of namespace sys
342 } // end of namespace gate
343