rainmaker_components/wifi_prov/
ble.rs

1use uuid::Uuid;
2
3use crate::{
4    ble::{Advertisement, AdvertisementHandle},
5    error::Error,
6    protocomm::{ProtocommCallbackType, ProtocommGatt, ProtocommGattConfig, ProtocommSecurity},
7};
8
9use super::base::WiFiProvTransportTrait;
10
11#[derive(Debug, Default, Clone)]
12pub struct WifiProvBleConfig {
13    pub service_name: String,
14    pub service_uuid: [u8; 16],
15}
16
17pub struct WiFiProvTransportBle {
18    pub(crate) device_name: String,
19    pub(crate) uuid: [u8; 16],
20    pub(crate) ep_count: u16,
21    pub(crate) pc: ProtocommGatt,
22    pub(crate) adv_handle: Option<AdvertisementHandle>,
23}
24
25impl WiFiProvTransportBle {
26    pub fn new(config: WifiProvBleConfig, sec: ProtocommSecurity) -> Self {
27        let pc = ProtocommGatt::new(
28            ProtocommGattConfig {
29                service_uuid: Uuid::from_bytes(config.service_uuid),
30            },
31            sec,
32        );
33
34        Self {
35            device_name: config.service_name,
36            uuid: config.service_uuid,
37            ep_count: 0,
38            pc,
39            adv_handle: None,
40        }
41    }
42}
43
44impl WiFiProvTransportTrait for WiFiProvTransportBle {
45    fn start(&mut self) -> Result<(), Error> {
46        self.pc.start();
47        self.start_advertising()?;
48
49        Ok(())
50    }
51
52    fn add_endpoint(&mut self, ep_name: &str, cb: ProtocommCallbackType) {
53        let uuid = self.next_uuid();
54
55        self.pc.register_endpoint(uuid, ep_name, cb);
56    }
57
58    fn set_version_info(&mut self, ep_name: &str, version_info: String) {
59        let uuid = self.next_uuid();
60        self.pc.set_version_info(uuid, ep_name, version_info);
61    }
62
63    fn set_security_ep(&mut self, ep_name: &str) {
64        let uuid = self.next_uuid();
65        self.pc.set_security_endpoint(uuid, ep_name);
66    }
67}
68
69impl WiFiProvTransportBle {
70    fn start_advertising(&mut self) -> Result<(), Error> {
71        let adv = Advertisement {
72            device_name: Some(self.device_name.clone()),
73            discoverable: true,
74            primary_service: Uuid::from_bytes(self.uuid),
75            service_uuids: vec![Uuid::from_bytes(self.uuid)],
76        };
77
78        let adv_handle = adv.advertise()?;
79
80        self.adv_handle = Some(adv_handle);
81
82        Ok(())
83    }
84
85    fn next_uuid(&mut self) -> Uuid {
86        let mut new_uuid = self.uuid;
87        new_uuid[2] = (self.ep_count >> 8) as u8; // Higher 8 bits
88        new_uuid[3] = (self.ep_count & 0xFF) as u8; // Lower 8 bits
89        self.ep_count += 1;
90
91        Uuid::from_bytes(new_uuid)
92    }
93}