1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//! # wrapper-ble-esp32c3mini
//!
//! Bibliothèque `no_std` encapsulant l'initialisation d'un périphérique BLE
//! (rôle *GATT peripheral*) sur ESP32-C3, en s'appuyant sur :
//!
//! - [`esp-radio`](https://docs.rs/esp-radio) pour le contrôleur HCI matériel
//! ([`BleConnector`]),
//! - [`bt-hci`](https://docs.rs/bt-hci) et son [`ExternalController`] pour
//! exposer ce contrôleur au format attendu par la pile hôte,
//! - [`trouble-host`](https://docs.rs/trouble-host) pour la pile hôte BLE
//! (GAP, GATT, L2CAP) et l'exécution asynchrone via Embassy.
//!
//! ## Vue d'ensemble
//!
//! Le point d'entrée est [`BleSystem::init`], qui construit :
//! 1. le contrôleur BLE matériel ([`BleController`]),
//! 2. la pile hôte `trouble-host` configurée en rôle périphérique,
//! 3. un serveur GATT [`BleServer`] exposant le service [`DisplayService`].
//!
//! Le `[`Runner`](trouble_host::Runner)` renvoyé doit ensuite être piloté en
//! continu par la tâche [`run_ble_runner`], typiquement *spawnée* sur
//! l'exécuteur Embassy du binaire final.
//!
//! ## Exemple d'utilisation (squelette)
//!
//! ```ignore
//! #![no_std]
//! #![no_main]
//!
//! use wrapper_ble_esp32c3mini::{BleSystem, run_ble_runner};
//!
//! #[esp_hal_embassy::main]
//! async fn main(spawner: embassy_executor::Spawner) {
//! let peripherals = esp_hal::init(esp_hal::Config::default());
//!
//! let BleSystem { runner, peripheral, server } = BleSystem::init(peripherals.BT);
//!
//! spawner.spawn(ble_runner_task(runner)).unwrap();
//!
//! // `peripheral` sert ensuite à publicité + acceptation de connexions,
//! // `server` expose les caractéristiques `command` / `status`.
//! }
//!
//! #[embassy_executor::task]
//! async fn ble_runner_task(runner: trouble_host::Runner<'static, wrapper_ble_esp32c3mini::BleController, trouble_host::DefaultPacketPool>) {
//! wrapper_ble_esp32c3mini::run_ble_runner(runner).await;
//! }
//! ```
//!
//! ## Compatibilité des versions
//!
//! Les versions figées dans `Cargo.toml` ne sont pas arbitraires : elles
//! forment le seul jeu de versions récentes qui se lient toutes ensemble au
//! moment de la rédaction de ce crate.
//!
//! - `esp-radio = "0.18.0"` exige `esp-hal` dans la plage `~1.1.0-rc.0`
//! (donc `esp-hal = "1.1.2"`, **pas** la branche `1.2.x`) et `bt-hci`
//! dans la plage `^0.8.0`.
//! - `bt-hci = "0.8.1"` est donc la version retenue, ce qui impose à son
//! tour `trouble-host = "0.6.0"` (la seule branche de `trouble-host` qui
//! dépend elle-même de `bt-hci ^0.8`, les versions `0.7`/`0.8` étant
//! passées à `bt-hci ^0.9`/`^0.10`).
//!
//! Si, à l'avenir, `esp-radio` publie une version qui suit `esp-hal 1.2.x`
//! et un `bt-hci` plus récent, il faudra remonter `trouble-host` en même
//! temps que `bt-hci`, pas séparément.
use ExternalController;
use ;
use BleConnector;
use StaticCell;
use *;
/// Taille (en octets) du buffer HCI utilisé par le contrôleur externe.
///
/// `20` correspond à la taille de payload HCI ACL par défaut utilisée dans
/// les exemples `esp-radio` / `trouble-host`. Augmenter cette valeur permet
/// de négocier un MTU L2CAP plus grand, au prix de plus de RAM statique.
pub type BleController = ;
/// Serveur GATT exposé par ce périphérique BLE.
///
/// Contient un unique service, [`DisplayService`], monté à la construction
/// via [`BleServer::new_with_config`].
/// Service GATT « Display », de type Nordic UART Service (UUID `6e400001…`).
///
/// - `command` : caractéristique en écriture, utilisée par le client BLE
/// pour envoyer des ordres à l'appareil (jusqu'à 16 octets).
/// - `status` : caractéristique en lecture + notification, utilisée par
/// l'appareil pour signaler son état au client (jusqu'à 16 octets).
/// Regroupe les trois composants nécessaires au fonctionnement de la pile
/// BLE : le *runner* de la pile hôte, le rôle périphérique et le serveur
/// GATT applicatif.
///
/// Ces trois éléments sont volontairement scindés (plutôt que gardés dans
/// une seule struct opaque) car `trouble-host` attend qu'ils soient
/// utilisés indépendamment : le `runner` est piloté en tâche de fond
/// ([`run_ble_runner`]), tandis que `peripheral` sert à publier des
/// annonces BLE et `server` à répondre aux lectures/écritures GATT.
/// Fait tourner indéfiniment la boucle d'évènements de la pile hôte BLE.
///
/// À *spawner* sur l'exécuteur Embassy du binaire final (voir l'exemple du
/// module). En cas d'erreur du runner (déconnexion inattendue du
/// contrôleur, par exemple), l'erreur est journalisée via [`esp_println`]
/// et la boucle retente après une seconde plutôt que de paniquer, afin de
/// ne pas interrompre le reste de l'application.
pub async