fundamentum_edge_mcu_http_client/
provisioning_api.rs1use core::marker::PhantomData;
2
3use crate::{
4 models::{DeviceFQN, Empty, HttpMethod},
5 HttpClient, HttpClientErrorWrapper, HttpHandler,
6};
7
8use super::{
9 api_version::{ApiVersion, V3},
10 models::{DeviceIdentity, ProvisionRequestV3, ProvisionResponse},
11};
12
13const PROVISIONING_PATH: &str = "/provision";
14
15pub struct ProvisioningApi<'a, V: ApiVersion, H: HttpHandler> {
20 http_client: &'a HttpClient<'a, V, H>,
21
22 _marker: PhantomData<fn() -> V>,
25}
26
27impl<'a, V: ApiVersion, H: HttpHandler> ProvisioningApi<'a, V, H> {
28 #[must_use]
30 pub const fn new(http_client: &'a HttpClient<'a, V, H>) -> Self {
31 Self {
32 http_client,
33 _marker: PhantomData,
34 }
35 }
36}
37
38impl<'a, H: HttpHandler> ProvisioningApi<'a, V3, H> {
39 pub async fn provision<'d>(
44 &'a self,
45 device_fqn: &'a DeviceFQN<'a>,
46 asset_type_id: i32,
47 access_token: &'a str,
48 device_identity: &'a DeviceIdentity<'a>,
49 mode: ProvisionMode,
50 out_buffer: &'d mut [u8],
51 ) -> Result<ProvisionResponse<'d, Empty>, HttpClientErrorWrapper<'d, H>> {
52 let body = ProvisionRequestV3 {
53 project_id: device_fqn.registry_fqn.project_id,
54 region_id: device_fqn.registry_fqn.region_id,
55 registry_id: device_fqn.registry_fqn.registry_id,
56 serial_number: device_fqn.serial_number,
57 asset_type_id,
58 access_token,
59 algorithm: &device_identity.tag(),
60 secret: match *device_identity {
61 DeviceIdentity::Rsa256 { public_key } => public_key,
62 },
63 };
64
65 self.http_client
66 .send(mode.into(), None, PROVISIONING_PATH, body, out_buffer)
67 .await
68 }
69}
70
71#[derive(Default)]
73pub enum ProvisionMode {
74 #[default]
76 Normal,
77 Force,
79}
80
81#[allow(clippy::from_over_into)]
82impl Into<HttpMethod> for ProvisionMode {
83 fn into(self) -> HttpMethod {
84 match self {
85 Self::Normal => HttpMethod::POST,
86 Self::Force => HttpMethod::PUT,
87 }
88 }
89}