@@ -42,6 +42,19 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask,
4242 serviceDiscovery ({¤tTimeClient, &alertNotificationClient}) {
4343}
4444
45+ void nimble_on_reset (int reason) {
46+ NRF_LOG_INFO (" Resetting state; reason=%d\n " , reason);
47+ }
48+
49+ void nimble_on_sync (void ) {
50+ int rc;
51+
52+ rc = ble_hs_util_ensure_addr (0 );
53+ ASSERT (rc == 0 );
54+
55+ nptr->StartAdvertising ();
56+ }
57+
4558int GAPEventCallback (struct ble_gap_event * event, void * arg) {
4659 auto nimbleController = static_cast <NimbleController*>(arg);
4760 return nimbleController->OnGAPEvent (event);
@@ -51,6 +64,10 @@ void NimbleController::Init() {
5164 while (!ble_hs_synced ()) {
5265 }
5366
67+ nptr = this ;
68+ ble_hs_cfg.reset_cb = nimble_on_reset;
69+ ble_hs_cfg.sync_cb = nimble_on_sync;
70+
5471 ble_svc_gap_init ();
5572 ble_svc_gatt_init ();
5673
@@ -64,28 +81,31 @@ void NimbleController::Init() {
6481 batteryInformationService.Init ();
6582 immediateAlertService.Init ();
6683 heartRateService.Init ();
67- int res;
68- res = ble_hs_util_ensure_addr (0 );
69- ASSERT (res == 0 );
70- res = ble_hs_id_infer_auto (0 , &addrType);
71- ASSERT (res == 0 );
72- res = ble_svc_gap_device_name_set (deviceName);
73- ASSERT (res == 0 );
84+
85+ int rc;
86+ rc = ble_hs_util_ensure_addr (0 );
87+ ASSERT (rc == 0 );
88+ rc = ble_hs_id_infer_auto (0 , &addrType);
89+ ASSERT (rc == 0 );
90+ rc = ble_svc_gap_device_name_set (deviceName);
91+ ASSERT (rc == 0 );
92+ rc = ble_svc_gap_device_appearance_set (0xC2 );
93+ ASSERT (rc == 0 );
7494 Pinetime::Controllers::Ble::BleAddress address;
75- res = ble_hs_id_copy_addr (addrType, address.data (), nullptr );
76- ASSERT (res == 0 );
95+ rc = ble_hs_id_copy_addr (addrType, address.data (), nullptr );
96+ ASSERT (rc == 0 );
7797 bleController.AddressType ((addrType == 0 ) ? Ble::AddressTypes::Public : Ble::AddressTypes::Random);
7898 bleController.Address (std::move (address));
7999
80- res = ble_gatts_start ();
81- ASSERT (res == 0 );
100+ rc = ble_gatts_start ();
101+ ASSERT (rc == 0 );
102+
103+ if (!ble_gap_adv_active () && !bleController.IsConnected ())
104+ StartAdvertising ();
82105}
83106
84107void NimbleController::StartAdvertising () {
85- if (bleController.IsConnected () || ble_gap_conn_active () || ble_gap_adv_active ())
86- return ;
87-
88- ble_svc_gap_device_name_set (deviceName);
108+ int rc;
89109
90110 /* set adv parameters */
91111 struct ble_gap_adv_params adv_params;
@@ -102,11 +122,17 @@ void NimbleController::StartAdvertising() {
102122
103123 adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
104124 adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
125+ /* fast advertise for 30 sec */
126+ if (fastAdvCount < 15 ) {
127+ adv_params.itvl_min = 32 ;
128+ adv_params.itvl_max = 47 ;
129+ fastAdvCount++;
130+ } else {
131+ adv_params.itvl_min = 1636 ;
132+ adv_params.itvl_max = 1651 ;
133+ }
105134
106135 fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
107- // fields.uuids128 = BLE_UUID128(BLE_UUID128_DECLARE(
108- // 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
109- // 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff));
110136 fields.uuids128 = &dfuServiceUuid;
111137 fields.num_uuids128 = 1 ;
112138 fields.uuids128_is_complete = 1 ;
@@ -116,64 +142,70 @@ void NimbleController::StartAdvertising() {
116142 rsp_fields.name_len = strlen (deviceName);
117143 rsp_fields.name_is_complete = 1 ;
118144
119- ble_gap_adv_set_fields (&fields);
120- // ASSERT(res == 0); // TODO this one sometimes fails with error 22 (notsync)
145+ rc = ble_gap_adv_set_fields (&fields);
146+ ASSERT (rc == 0 );
121147
122- ble_gap_adv_rsp_set_fields (&rsp_fields);
123- // ASSERT(res == 0);
148+ rc = ble_gap_adv_rsp_set_fields (&rsp_fields);
149+ ASSERT (rc == 0 );
124150
125- ble_gap_adv_start (addrType, NULL , 180000 , &adv_params, GAPEventCallback, this );
126- // ASSERT(res == 0);// TODO I've disabled these ASSERT as they sometime asserts and reset the mcu.
127- // For now, the advertising is restarted as soon as it ends. There may be a race condition
128- // that prevent the advertising from restarting reliably.
129- // I remove the assert to prevent this unnecessary crash, but in the long term, the management of
130- // the advertising should be improve (better error handling, and advertise for 3 minutes after
131- // the application has been woken up, for example.
151+ rc = ble_gap_adv_start (addrType, NULL , 2000 , &adv_params, GAPEventCallback, this );
152+ ASSERT (rc == 0 );
132153}
133154
134155int NimbleController::OnGAPEvent (ble_gap_event* event) {
135156 switch (event->type ) {
136157 case BLE_GAP_EVENT_ADV_COMPLETE:
137158 NRF_LOG_INFO (" Advertising event : BLE_GAP_EVENT_ADV_COMPLETE" );
138- NRF_LOG_INFO (" advertise complete; reason=%dn status=%d" , event->adv_complete .reason , event->connect .status );
159+ NRF_LOG_INFO (" reason=%d; status=%d" , event->adv_complete .reason , event->connect .status );
160+ StartAdvertising ();
139161 break ;
140- case BLE_GAP_EVENT_CONNECT: {
162+
163+ case BLE_GAP_EVENT_CONNECT:
141164 NRF_LOG_INFO (" Advertising event : BLE_GAP_EVENT_CONNECT" );
142165
143166 /* A new connection was established or a connection attempt failed. */
144167 NRF_LOG_INFO (" connection %s; status=%d " , event->connect .status == 0 ? " established" : " failed" , event->connect .status );
145168
146169 if (event->connect .status != 0 ) {
147170 /* Connection failed; resume advertising. */
148- StartAdvertising ();
171+ currentTimeClient.Reset ();
172+ alertNotificationClient.Reset ();
173+ connectionHandle = BLE_HS_CONN_HANDLE_NONE;
149174 bleController.Disconnect ();
175+ fastAdvCount = 0 ;
176+ StartAdvertising ();
150177 } else {
178+ connectionHandle = event->connect .conn_handle ;
151179 bleController.Connect ();
152180 systemTask.PushMessage (Pinetime::System::Messages::BleConnected);
153- connectionHandle = event->connect .conn_handle ;
154- // Service discovery is deffered via systemtask
181+ // Service discovery is deferred via systemtask
155182 }
156- } break ;
183+ break ;
184+
157185 case BLE_GAP_EVENT_DISCONNECT:
158186 NRF_LOG_INFO (" Advertising event : BLE_GAP_EVENT_DISCONNECT" );
159- NRF_LOG_INFO (" disconnect; reason=%d" , event->disconnect .reason );
187+ NRF_LOG_INFO (" disconnect reason=%d" , event->disconnect .reason );
160188
161189 /* Connection terminated; resume advertising. */
162190 currentTimeClient.Reset ();
163191 alertNotificationClient.Reset ();
164192 connectionHandle = BLE_HS_CONN_HANDLE_NONE;
165193 bleController.Disconnect ();
194+ fastAdvCount = 0 ;
166195 StartAdvertising ();
167196 break ;
197+
168198 case BLE_GAP_EVENT_CONN_UPDATE:
169199 NRF_LOG_INFO (" Advertising event : BLE_GAP_EVENT_CONN_UPDATE" );
170200 /* The central has updated the connection parameters. */
171- NRF_LOG_INFO (" connection updated; status=%d " , event->conn_update .status );
201+ NRF_LOG_INFO (" update status=%d " , event->conn_update .status );
172202 break ;
203+
173204 case BLE_GAP_EVENT_ENC_CHANGE:
174205 /* Encryption has been enabled or disabled for this connection. */
175206 NRF_LOG_INFO (" encryption change event; status=%d " , event->enc_change .status );
176- return 0 ;
207+ break ;
208+
177209 case BLE_GAP_EVENT_SUBSCRIBE:
178210 NRF_LOG_INFO (" subscribe event; conn_handle=%d attr_handle=%d "
179211 " reason=%d prevn=%d curn=%d previ=%d curi=???\n " ,
@@ -183,10 +215,12 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
183215 event->subscribe .prev_notify ,
184216 event->subscribe .cur_notify ,
185217 event->subscribe .prev_indicate );
186- return 0 ;
218+ break ;
219+
187220 case BLE_GAP_EVENT_MTU:
188- NRF_LOG_INFO (" mtu update event; conn_handle=%d cid=%d mtu=%d\n " , event->mtu .conn_handle , event->mtu .channel_id , event->mtu .value );
189- return 0 ;
221+ NRF_LOG_INFO (" mtu update event; conn_handle=%d cid=%d mtu=%d\n " ,
222+ event->mtu .conn_handle , event->mtu .channel_id , event->mtu .value );
223+ break ;
190224
191225 case BLE_GAP_EVENT_REPEAT_PAIRING: {
192226 /* We already have a bond with the peer, but it is attempting to
@@ -217,8 +251,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
217251 notifSize);
218252
219253 alertNotificationClient.OnNotification (event);
220- return 0 ;
221- }
254+ } break ;
222255 /* Attribute data is contained in event->notify_rx.attr_data. */
223256
224257 default :
@@ -229,15 +262,17 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
229262}
230263
231264void NimbleController::StartDiscovery () {
232- serviceDiscovery.StartDiscovery (connectionHandle);
265+ if (connectionHandle != BLE_HS_CONN_HANDLE_NONE) {
266+ serviceDiscovery.StartDiscovery (connectionHandle);
267+ }
233268}
234269
235270uint16_t NimbleController::connHandle () {
236271 return connectionHandle;
237272}
238273
239274void NimbleController::NotifyBatteryLevel (uint8_t level) {
240- if (connectionHandle != BLE_HS_CONN_HANDLE_NONE) {
275+ if (connectionHandle != BLE_HS_CONN_HANDLE_NONE) {
241276 batteryInformationService.NotifyBatteryLevel (connectionHandle, level);
242277 }
243278}
0 commit comments