script/dom/bluetooth/
bluetoothuuid.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use dom_struct::dom_struct;
6use regex::Regex;
7use script_bindings::cformat;
8
9use crate::dom::bindings::codegen::Bindings::BluetoothUUIDBinding::BluetoothUUIDMethods;
10use crate::dom::bindings::codegen::UnionTypes::StringOrUnsignedLong;
11use crate::dom::bindings::error::Error::Type;
12use crate::dom::bindings::error::Fallible;
13use crate::dom::bindings::reflector::Reflector;
14use crate::dom::bindings::str::DOMString;
15use crate::dom::window::Window;
16
17#[expect(clippy::upper_case_acronyms)]
18pub(crate) type UUID = DOMString;
19pub(crate) type BluetoothServiceUUID = StringOrUnsignedLong;
20pub(crate) type BluetoothCharacteristicUUID = StringOrUnsignedLong;
21pub(crate) type BluetoothDescriptorUUID = StringOrUnsignedLong;
22
23// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothuuid
24#[dom_struct]
25pub(crate) struct BluetoothUUID {
26    reflector_: Reflector,
27}
28
29// https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
30const BLUETOOTH_ASSIGNED_SERVICES: &[(&str, u32)] = &[
31    ("org.bluetooth.service.alert_notification", 0x1811_u32),
32    ("org.bluetooth.service.automation_io", 0x1815_u32),
33    ("org.bluetooth.service.battery_service", 0x180f_u32),
34    ("org.bluetooth.service.blood_pressure", 0x1810_u32),
35    ("org.bluetooth.service.body_composition", 0x181b_u32),
36    ("org.bluetooth.service.bond_management", 0x181e_u32),
37    (
38        "org.bluetooth.service.continuous_glucose_monitoring",
39        0x181f_u32,
40    ),
41    ("org.bluetooth.service.current_time", 0x1805_u32),
42    ("org.bluetooth.service.cycling_power", 0x1818_u32),
43    (
44        "org.bluetooth.service.cycling_speed_and_cadence",
45        0x1816_u32,
46    ),
47    ("org.bluetooth.service.device_information", 0x180a_u32),
48    ("org.bluetooth.service.environmental_sensing", 0x181a_u32),
49    ("org.bluetooth.service.generic_access", 0x1800_u32),
50    ("org.bluetooth.service.generic_attribute", 0x1801_u32),
51    ("org.bluetooth.service.glucose", 0x1808_u32),
52    ("org.bluetooth.service.health_thermometer", 0x1809_u32),
53    ("org.bluetooth.service.heart_rate", 0x180d_u32),
54    ("org.bluetooth.service.http_proxy", 0x1823_u32),
55    ("org.bluetooth.service.human_interface_device", 0x1812_u32),
56    ("org.bluetooth.service.immediate_alert", 0x1802_u32),
57    ("org.bluetooth.service.indoor_positioning", 0x1821_u32),
58    (
59        "org.bluetooth.service.internet_protocol_support",
60        0x1820_u32,
61    ),
62    ("org.bluetooth.service.link_loss", 0x1803_u32),
63    ("org.bluetooth.service.location_and_navigation", 0x1819_u32),
64    ("org.bluetooth.service.next_dst_change", 0x1807_u32),
65    ("org.bluetooth.service.object_transfer", 0x1825_u32),
66    ("org.bluetooth.service.phone_alert_status", 0x180e_u32),
67    ("org.bluetooth.service.pulse_oximeter", 0x1822_u32),
68    ("org.bluetooth.service.reference_time_update", 0x1806_u32),
69    (
70        "org.bluetooth.service.running_speed_and_cadence",
71        0x1814_u32,
72    ),
73    ("org.bluetooth.service.scan_parameters", 0x1813_u32),
74    ("org.bluetooth.service.transport_discovery", 0x1824),
75    ("org.bluetooth.service.tx_power", 0x1804_u32),
76    ("org.bluetooth.service.user_data", 0x181c_u32),
77    ("org.bluetooth.service.weight_scale", 0x181d_u32),
78];
79
80// https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
81const BLUETOOTH_ASSIGNED_CHARCTERISTICS: &[(&str, u32)] = &[
82    (
83        "org.bluetooth.characteristic.aerobic_heart_rate_lower_limit",
84        0x2a7e_u32,
85    ),
86    (
87        "org.bluetooth.characteristic.aerobic_heart_rate_upper_limit",
88        0x2a84_u32,
89    ),
90    ("org.bluetooth.characteristic.aerobic_threshold", 0x2a7f_u32),
91    ("org.bluetooth.characteristic.age", 0x2a80_u32),
92    ("org.bluetooth.characteristic.aggregate", 0x2a5a_u32),
93    ("org.bluetooth.characteristic.alert_category_id", 0x2a43_u32),
94    (
95        "org.bluetooth.characteristic.alert_category_id_bit_mask",
96        0x2a42_u32,
97    ),
98    ("org.bluetooth.characteristic.alert_level", 0x2a06_u32),
99    (
100        "org.bluetooth.characteristic.alert_notification_control_point",
101        0x2a44_u32,
102    ),
103    ("org.bluetooth.characteristic.alert_status", 0x2a3f_u32),
104    ("org.bluetooth.characteristic.altitude", 0x2ab3_u32),
105    (
106        "org.bluetooth.characteristic.anaerobic_heart_rate_lower_limit",
107        0x2a81_u32,
108    ),
109    (
110        "org.bluetooth.characteristic.anaerobic_heart_rate_upper_limit",
111        0x2a82_u32,
112    ),
113    (
114        "org.bluetooth.characteristic.anaerobic_threshold",
115        0x2a83_u32,
116    ),
117    ("org.bluetooth.characteristic.analog", 0x2a58_u32),
118    (
119        "org.bluetooth.characteristic.apparent_wind_direction",
120        0x2a73_u32,
121    ),
122    (
123        "org.bluetooth.characteristic.apparent_wind_speed",
124        0x2a72_u32,
125    ),
126    ("org.bluetooth.characteristic.gap.appearance", 0x2a01_u32),
127    (
128        "org.bluetooth.characteristic.barometric_pressure_trend",
129        0x2aa3_u32,
130    ),
131    ("org.bluetooth.characteristic.battery_level", 0x2a19_u32),
132    (
133        "org.bluetooth.characteristic.blood_pressure_feature",
134        0x2a49_u32,
135    ),
136    (
137        "org.bluetooth.characteristic.blood_pressure_measurement",
138        0x2a35_u32,
139    ),
140    (
141        "org.bluetooth.characteristic.body_composition_feature",
142        0x2a9b_u32,
143    ),
144    (
145        "org.bluetooth.characteristic.body_composition_measurement",
146        0x2a9c_u32,
147    ),
148    (
149        "org.bluetooth.characteristic.body_sensor_location",
150        0x2a38_u32,
151    ),
152    (
153        "org.bluetooth.characteristic.bond_management_control_point",
154        0x2aa4_u32,
155    ),
156    (
157        "org.bluetooth.characteristic.bond_management_feature",
158        0x2aa5_u32,
159    ),
160    (
161        "org.bluetooth.characteristic.boot_keyboard_input_report",
162        0x2a22_u32,
163    ),
164    (
165        "org.bluetooth.characteristic.boot_keyboard_output_report",
166        0x2a32_u32,
167    ),
168    (
169        "org.bluetooth.characteristic.boot_mouse_input_report",
170        0x2a33_u32,
171    ),
172    (
173        "org.bluetooth.characteristic.gap.central_address_resolution_support",
174        0x2aa6_u32,
175    ),
176    ("org.bluetooth.characteristic.cgm_feature", 0x2aa8_u32),
177    ("org.bluetooth.characteristic.cgm_measurement", 0x2aa7_u32),
178    (
179        "org.bluetooth.characteristic.cgm_session_run_time",
180        0x2aab_u32,
181    ),
182    (
183        "org.bluetooth.characteristic.cgm_session_start_time",
184        0x2aaa_u32,
185    ),
186    (
187        "org.bluetooth.characteristic.cgm_specific_ops_control_point",
188        0x2aac_u32,
189    ),
190    ("org.bluetooth.characteristic.cgm_status", 0x2aa9_u32),
191    ("org.bluetooth.characteristic.csc_feature", 0x2a5c_u32),
192    ("org.bluetooth.characteristic.csc_measurement", 0x2a5b_u32),
193    ("org.bluetooth.characteristic.current_time", 0x2a2b_u32),
194    (
195        "org.bluetooth.characteristic.cycling_power_control_point",
196        0x2a66_u32,
197    ),
198    (
199        "org.bluetooth.characteristic.cycling_power_feature",
200        0x2a65_u32,
201    ),
202    (
203        "org.bluetooth.characteristic.cycling_power_measurement",
204        0x2a63_u32,
205    ),
206    (
207        "org.bluetooth.characteristic.cycling_power_vector",
208        0x2a64_u32,
209    ),
210    (
211        "org.bluetooth.characteristic.database_change_increment",
212        0x2a99_u32,
213    ),
214    ("org.bluetooth.characteristic.date_of_birth", 0x2a85_u32),
215    (
216        "org.bluetooth.characteristic.date_of_threshold_assessment",
217        0x2a86_u32,
218    ),
219    ("org.bluetooth.characteristic.date_time", 0x2a08_u32),
220    ("org.bluetooth.characteristic.day_date_time", 0x2a0a_u32),
221    ("org.bluetooth.characteristic.day_of_week", 0x2a09_u32),
222    (
223        "org.bluetooth.characteristic.descriptor_value_changed",
224        0x2a7d_u32,
225    ),
226    ("org.bluetooth.characteristic.gap.device_name", 0x2a00_u32),
227    ("org.bluetooth.characteristic.dew_point", 0x2a7b_u32),
228    ("org.bluetooth.characteristic.digital", 0x2a56_u32),
229    ("org.bluetooth.characteristic.dst_offset", 0x2a0d_u32),
230    ("org.bluetooth.characteristic.elevation", 0x2a6c_u32),
231    ("org.bluetooth.characteristic.email_address", 0x2a87_u32),
232    ("org.bluetooth.characteristic.exact_time_256", 0x2a0c_u32),
233    (
234        "org.bluetooth.characteristic.fat_burn_heart_rate_lower_limit",
235        0x2a88_u32,
236    ),
237    (
238        "org.bluetooth.characteristic.fat_burn_heart_rate_upper_limit",
239        0x2a89_u32,
240    ),
241    (
242        "org.bluetooth.characteristic.firmware_revision_string",
243        0x2a26_u32,
244    ),
245    ("org.bluetooth.characteristic.first_name", 0x2a8a_u32),
246    (
247        "org.bluetooth.characteristic.five_zone_heart_rate_limits",
248        0x2a8b_u32,
249    ),
250    ("org.bluetooth.characteristic.floor_number", 0x2ab2_u32),
251    ("org.bluetooth.characteristic.gender", 0x2a8c_u32),
252    ("org.bluetooth.characteristic.glucose_feature", 0x2a51_u32),
253    (
254        "org.bluetooth.characteristic.glucose_measurement",
255        0x2a18_u32,
256    ),
257    (
258        "org.bluetooth.characteristic.glucose_measurement_context",
259        0x2a34_u32,
260    ),
261    ("org.bluetooth.characteristic.gust_factor", 0x2a74_u32),
262    (
263        "org.bluetooth.characteristic.hardware_revision_string",
264        0x2a27_u32,
265    ),
266    (
267        "org.bluetooth.characteristic.heart_rate_control_point",
268        0x2a39_u32,
269    ),
270    ("org.bluetooth.characteristic.heart_rate_max", 0x2a8d_u32),
271    (
272        "org.bluetooth.characteristic.heart_rate_measurement",
273        0x2a37_u32,
274    ),
275    ("org.bluetooth.characteristic.heat_index", 0x2a7a_u32),
276    ("org.bluetooth.characteristic.height", 0x2a8e_u32),
277    ("org.bluetooth.characteristic.hid_control_point", 0x2a4c_u32),
278    ("org.bluetooth.characteristic.hid_information", 0x2a4a_u32),
279    ("org.bluetooth.characteristic.hip_circumference", 0x2a8f_u32),
280    (
281        "org.bluetooth.characteristic.http_control_point",
282        0x2aba_u32,
283    ),
284    ("org.bluetooth.characteristic.http_entity_body", 0x2ab9_u32),
285    ("org.bluetooth.characteristic.http_headers", 0x2ab7_u32),
286    ("org.bluetooth.characteristic.http_status_code", 0x2ab8_u32),
287    ("org.bluetooth.characteristic.https_security", 0x2abb_u32),
288    ("org.bluetooth.characteristic.humidity", 0x2a6f_u32),
289    (
290        "org.bluetooth.characteristic.ieee_11073-20601_regulatory_certification_data_list",
291        0x2a2a_u32,
292    ),
293    (
294        "org.bluetooth.characteristic.indoor_positioning_configuration",
295        0x2aad_u32,
296    ),
297    (
298        "org.bluetooth.characteristic.intermediate_cuff_pressure",
299        0x2a36_u32,
300    ),
301    (
302        "org.bluetooth.characteristic.intermediate_temperature",
303        0x2a1e_u32,
304    ),
305    ("org.bluetooth.characteristic.irradiance", 0x2a77_u32),
306    ("org.bluetooth.characteristic.language", 0x2aa2_u32),
307    ("org.bluetooth.characteristic.last_name", 0x2a90_u32),
308    ("org.bluetooth.characteristic.latitude", 0x2aae_u32),
309    ("org.bluetooth.characteristic.ln_control_point", 0x2a6b_u32),
310    ("org.bluetooth.characteristic.ln_feature", 0x2a6a_u32),
311    (
312        "org.bluetooth.characteristic.local_east_coordinate.xml",
313        0x2ab1_u32,
314    ),
315    (
316        "org.bluetooth.characteristic.local_north_coordinate",
317        0x2ab0_u32,
318    ),
319    (
320        "org.bluetooth.characteristic.local_time_information",
321        0x2a0f_u32,
322    ),
323    (
324        "org.bluetooth.characteristic.location_and_speed",
325        0x2a67_u32,
326    ),
327    ("org.bluetooth.characteristic.location_name", 0x2ab5_u32),
328    ("org.bluetooth.characteristic.longitude", 0x2aaf_u32),
329    (
330        "org.bluetooth.characteristic.magnetic_declination",
331        0x2a2c_u32,
332    ),
333    (
334        "org.bluetooth.characteristic.magnetic_flux_density_2d",
335        0x2aa0_u32,
336    ),
337    (
338        "org.bluetooth.characteristic.magnetic_flux_density_3d",
339        0x2aa1_u32,
340    ),
341    (
342        "org.bluetooth.characteristic.manufacturer_name_string",
343        0x2a29_u32,
344    ),
345    (
346        "org.bluetooth.characteristic.maximum_recommended_heart_rate",
347        0x2a91_u32,
348    ),
349    (
350        "org.bluetooth.characteristic.measurement_interval",
351        0x2a21_u32,
352    ),
353    (
354        "org.bluetooth.characteristic.model_number_string",
355        0x2a24_u32,
356    ),
357    ("org.bluetooth.characteristic.navigation", 0x2a68_u32),
358    ("org.bluetooth.characteristic.new_alert", 0x2a46_u32),
359    (
360        "org.bluetooth.characteristic.object_action_control_point",
361        0x2ac5_u32,
362    ),
363    ("org.bluetooth.characteristic.object_changed", 0x2ac8_u32),
364    (
365        "org.bluetooth.characteristic.object_first_created",
366        0x2ac1_u32,
367    ),
368    ("org.bluetooth.characteristic.object_id", 0x2ac3_u32),
369    (
370        "org.bluetooth.characteristic.object_last_modified",
371        0x2ac2_u32,
372    ),
373    (
374        "org.bluetooth.characteristic.object_list_control_point",
375        0x2ac6_u32,
376    ),
377    (
378        "org.bluetooth.characteristic.object_list_filter",
379        0x2ac7_u32,
380    ),
381    ("org.bluetooth.characteristic.object_name", 0x2abe_u32),
382    ("org.bluetooth.characteristic.object_properties", 0x2ac4_u32),
383    ("org.bluetooth.characteristic.object_size", 0x2ac0_u32),
384    ("org.bluetooth.characteristic.object_type", 0x2abf_u32),
385    ("org.bluetooth.characteristic.ots_feature", 0x2abd_u32),
386    (
387        "org.bluetooth.characteristic.gap.peripheral_preferred_connection_parameters",
388        0x2a04_u32,
389    ),
390    (
391        "org.bluetooth.characteristic.gap.peripheral_privacy_flag",
392        0x2a02_u32,
393    ),
394    (
395        "org.bluetooth.characteristic.plx_continuous_measurement",
396        0x2a5f_u32,
397    ),
398    ("org.bluetooth.characteristic.plx_features", 0x2a60_u32),
399    (
400        "org.bluetooth.characteristic.plx_spot_check_measurement",
401        0x2a5e_u32,
402    ),
403    ("org.bluetooth.characteristic.pnp_id", 0x2a50_u32),
404    (
405        "org.bluetooth.characteristic.pollen_concentration",
406        0x2a75_u32,
407    ),
408    ("org.bluetooth.characteristic.position_quality", 0x2a69_u32),
409    ("org.bluetooth.characteristic.pressure", 0x2a6d_u32),
410    ("org.bluetooth.characteristic.protocol_mode", 0x2a4e_u32),
411    ("org.bluetooth.characteristic.rainfall", 0x2a78_u32),
412    (
413        "org.bluetooth.characteristic.gap.reconnection_address",
414        0x2a03_u32,
415    ),
416    (
417        "org.bluetooth.characteristic.record_access_control_point",
418        0x2a52_u32,
419    ),
420    (
421        "org.bluetooth.characteristic.reference_time_information",
422        0x2a14_u32,
423    ),
424    ("org.bluetooth.characteristic.report", 0x2a4d_u32),
425    ("org.bluetooth.characteristic.report_map", 0x2a4b_u32),
426    (
427        "org.bluetooth.characteristic.resting_heart_rate",
428        0x2a92_u32,
429    ),
430    (
431        "org.bluetooth.characteristic.ringer_control_point",
432        0x2a40_u32,
433    ),
434    ("org.bluetooth.characteristic.ringer_setting", 0x2a41_u32),
435    ("org.bluetooth.characteristic.rsc_feature", 0x2a54_u32),
436    ("org.bluetooth.characteristic.rsc_measurement", 0x2a53_u32),
437    ("org.bluetooth.characteristic.sc_control_point", 0x2a55_u32),
438    (
439        "org.bluetooth.characteristic.scan_interval_window",
440        0x2a4f_u32,
441    ),
442    ("org.bluetooth.characteristic.scan_refresh", 0x2a31_u32),
443    ("org.bluetooth.characteristic.sensor_location", 0x2a5d_u32),
444    (
445        "org.bluetooth.characteristic.serial_number_string",
446        0x2a25_u32,
447    ),
448    (
449        "org.bluetooth.characteristic.gatt.service_changed",
450        0x2a05_u32,
451    ),
452    (
453        "org.bluetooth.characteristic.software_revision_string",
454        0x2a28_u32,
455    ),
456    (
457        "org.bluetooth.characteristic.sport_type_for_aerobic_and_anaerobic_thresholds",
458        0x2a93_u32,
459    ),
460    (
461        "org.bluetooth.characteristic.supported_new_alert_category",
462        0x2a47_u32,
463    ),
464    (
465        "org.bluetooth.characteristic.supported_unread_alert_category",
466        0x2a48_u32,
467    ),
468    ("org.bluetooth.characteristic.system_id", 0x2a23_u32),
469    ("org.bluetooth.characteristic.tds_control_point", 0x2abc_u32),
470    ("org.bluetooth.characteristic.temperature", 0x2a6e_u32),
471    (
472        "org.bluetooth.characteristic.temperature_measurement",
473        0x2a1c_u32,
474    ),
475    ("org.bluetooth.characteristic.temperature_type", 0x2a1d_u32),
476    (
477        "org.bluetooth.characteristic.three_zone_heart_rate_limits",
478        0x2a94_u32,
479    ),
480    ("org.bluetooth.characteristic.time_accuracy", 0x2a12_u32),
481    ("org.bluetooth.characteristic.time_source", 0x2a13_u32),
482    (
483        "org.bluetooth.characteristic.time_update_control_point",
484        0x2a16_u32,
485    ),
486    ("org.bluetooth.characteristic.time_update_state", 0x2a17_u32),
487    ("org.bluetooth.characteristic.time_with_dst", 0x2a11_u32),
488    ("org.bluetooth.characteristic.time_zone", 0x2a0e_u32),
489    (
490        "org.bluetooth.characteristic.true_wind_direction",
491        0x2a71_u32,
492    ),
493    ("org.bluetooth.characteristic.true_wind_speed", 0x2a70_u32),
494    (
495        "org.bluetooth.characteristic.two_zone_heart_rate_limit",
496        0x2a95_u32,
497    ),
498    ("org.bluetooth.characteristic.tx_power_level", 0x2a07_u32),
499    ("org.bluetooth.characteristic.uncertainty", 0x2ab4_u32),
500    (
501        "org.bluetooth.characteristic.unread_alert_status",
502        0x2a45_u32,
503    ),
504    ("org.bluetooth.characteristic.uri", 0x2ab6_u32),
505    (
506        "org.bluetooth.characteristic.user_control_point",
507        0x2a9f_u32,
508    ),
509    ("org.bluetooth.characteristic.user_index", 0x2a9a_u32),
510    ("org.bluetooth.characteristic.uv_index", 0x2a76_u32),
511    ("org.bluetooth.characteristic.vo2_max", 0x2a96_u32),
512    (
513        "org.bluetooth.characteristic.waist_circumference",
514        0x2a97_u32,
515    ),
516    ("org.bluetooth.characteristic.weight", 0x2a98_u32),
517    (
518        "org.bluetooth.characteristic.weight_measurement",
519        0x2a9d_u32,
520    ),
521    (
522        "org.bluetooth.characteristic.weight_scale_feature",
523        0x2a9e_u32,
524    ),
525    ("org.bluetooth.characteristic.wind_chill", 0x2a79_u32),
526];
527
528// https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
529const BLUETOOTH_ASSIGNED_DESCRIPTORS: &[(&str, u32)] = &[
530    (
531        "org.bluetooth.descriptor.gatt.characteristic_extended_properties",
532        0x2900_u32,
533    ),
534    (
535        "org.bluetooth.descriptor.gatt.characteristic_user_description",
536        0x2901_u32,
537    ),
538    (
539        "org.bluetooth.descriptor.gatt.client_characteristic_configuration",
540        0x2902_u32,
541    ),
542    (
543        "org.bluetooth.descriptor.gatt.server_characteristic_configuration",
544        0x2903_u32,
545    ),
546    (
547        "org.bluetooth.descriptor.gatt.characteristic_presentation_format",
548        0x2904_u32,
549    ),
550    (
551        "org.bluetooth.descriptor.gatt.characteristic_aggregate_format",
552        0x2905_u32,
553    ),
554    ("org.bluetooth.descriptor.valid_range", 0x2906_u32),
555    (
556        "org.bluetooth.descriptor.external_report_reference",
557        0x2907_u32,
558    ),
559    ("org.bluetooth.descriptor.report_reference", 0x2908_u32),
560    ("org.bluetooth.descriptor.number_of_digitals", 0x2909_u32),
561    ("org.bluetooth.descriptor.value_trigger_setting", 0x290a_u32),
562    ("org.bluetooth.descriptor.es_configuration", 0x290b_u32),
563    ("org.bluetooth.descriptor.es_measurement", 0x290c_u32),
564    ("org.bluetooth.descriptor.es_trigger_setting", 0x290d_u32),
565    ("org.bluetooth.descriptor.time_trigger_setting", 0x290e_u32),
566];
567
568const BASE_UUID: &str = "-0000-1000-8000-00805f9b34fb";
569const SERVICE_PREFIX: &str = "org.bluetooth.service";
570const CHARACTERISTIC_PREFIX: &str = "org.bluetooth.characteristic";
571const DESCRIPTOR_PREFIX: &str = "org.bluetooth.descriptor";
572const VALID_UUID_REGEX: &str = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
573// https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp?l=314
574const UUID_ERROR_MESSAGE: &str = "It must be a valid UUID alias (e.g. 0x1234), \
575    UUID (lowercase hex characters e.g. '00001234-0000-1000-8000-00805f9b34fb'),\nor recognized standard name from";
576// https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp?l=321
577const SERVICES_ERROR_MESSAGE: &str = "https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx\
578     \ne.g. 'alert_notification'.";
579// https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp?l=327
580const CHARACTERISTIC_ERROR_MESSAGE: &str = "https://developer.bluetooth.org/gatt/characteristics/Pages/\
581     CharacteristicsHome.aspx\ne.g. 'aerobic_heart_rate_lower_limit'.";
582// https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/bluetooth/BluetoothUUID.cpp?l=333
583const DESCRIPTOR_ERROR_MESSAGE: &str = "https://developer.bluetooth.org/gatt/descriptors/Pages/\
584     DescriptorsHomePage.aspx\ne.g. 'gatt.characteristic_presentation_format'.";
585
586impl BluetoothUUIDMethods<crate::DomTypeHolder> for BluetoothUUID {
587    /// <https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-canonicaluuid>
588    fn CanonicalUUID(_: &Window, alias: u32) -> UUID {
589        canonical_uuid(alias)
590    }
591
592    /// <https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-getservice>
593    fn GetService(_: &Window, name: BluetoothServiceUUID) -> Fallible<UUID> {
594        Self::service(name)
595    }
596
597    /// <https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-getcharacteristic>
598    fn GetCharacteristic(_: &Window, name: BluetoothCharacteristicUUID) -> Fallible<UUID> {
599        Self::characteristic(name)
600    }
601
602    /// <https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-getdescriptor>
603    fn GetDescriptor(_: &Window, name: BluetoothDescriptorUUID) -> Fallible<UUID> {
604        Self::descriptor(name)
605    }
606}
607
608impl BluetoothUUID {
609    pub(crate) fn service(name: BluetoothServiceUUID) -> Fallible<UUID> {
610        resolve_uuid_name(name, BLUETOOTH_ASSIGNED_SERVICES, SERVICE_PREFIX)
611    }
612
613    pub(crate) fn characteristic(name: BluetoothCharacteristicUUID) -> Fallible<UUID> {
614        resolve_uuid_name(
615            name,
616            BLUETOOTH_ASSIGNED_CHARCTERISTICS,
617            CHARACTERISTIC_PREFIX,
618        )
619    }
620
621    pub(crate) fn descriptor(name: BluetoothDescriptorUUID) -> Fallible<UUID> {
622        resolve_uuid_name(name, BLUETOOTH_ASSIGNED_DESCRIPTORS, DESCRIPTOR_PREFIX)
623    }
624}
625
626fn canonical_uuid(alias: u32) -> UUID {
627    UUID::from(format!("{:08x}", &alias) + BASE_UUID)
628}
629
630/// <https://webbluetoothcg.github.io/web-bluetooth/#resolveuuidname>
631fn resolve_uuid_name(
632    name: StringOrUnsignedLong,
633    assigned_numbers_table: &'static [(&'static str, u32)],
634    prefix: &str,
635) -> Fallible<DOMString> {
636    match name {
637        // Step 1.
638        StringOrUnsignedLong::UnsignedLong(unsigned32) => Ok(canonical_uuid(unsigned32)),
639        StringOrUnsignedLong::String(dstring) => {
640            // Step 2.
641            let regex = Regex::new(VALID_UUID_REGEX).unwrap();
642            if regex.is_match(&dstring.str()) {
643                Ok(dstring)
644            } else {
645                // Step 3.
646                let concatenated = format!("{}.{}", prefix, dstring);
647                let is_in_table = assigned_numbers_table.iter().find(|p| p.0 == concatenated);
648                match is_in_table {
649                    Some(&(_, alias)) => Ok(canonical_uuid(alias)),
650                    None => {
651                        let (attribute_type, error_url_message) = match prefix {
652                            SERVICE_PREFIX => ("Service", SERVICES_ERROR_MESSAGE),
653                            CHARACTERISTIC_PREFIX => {
654                                ("Characteristic", CHARACTERISTIC_ERROR_MESSAGE)
655                            },
656                            DESCRIPTOR_PREFIX => ("Descriptor", DESCRIPTOR_ERROR_MESSAGE),
657                            _ => unreachable!(),
658                        };
659                        // Step 4.
660                        Err(Type(cformat!(
661                            "Invalid {} name : '{}'.\n{} {}",
662                            attribute_type,
663                            dstring,
664                            UUID_ERROR_MESSAGE,
665                            error_url_message
666                        )))
667                    },
668                }
669            }
670        },
671    }
672}