@@ -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;
@@ -104,9 +124,6 @@ void NimbleController::StartAdvertising() {
104124 adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
105125
106126 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));
110127 fields.uuids128 = &dfuServiceUuid;
111128 fields.num_uuids128 = 1 ;
112129 fields.uuids128_is_complete = 1 ;
@@ -116,27 +133,24 @@ void NimbleController::StartAdvertising() {
116133 rsp_fields.name_len = strlen (deviceName);
117134 rsp_fields.name_is_complete = 1 ;
118135
119- ble_gap_adv_set_fields (&fields);
120- // ASSERT(res == 0); // TODO this one sometimes fails with error 22 (notsync)
136+ rc = ble_gap_adv_set_fields (&fields);
137+ ASSERT (rc == 0 );
121138
122- ble_gap_adv_rsp_set_fields (&rsp_fields);
123- // ASSERT(res == 0);
139+ rc = ble_gap_adv_rsp_set_fields (&rsp_fields);
140+ ASSERT (rc == 0 );
124141
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 uncesseray 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.
142+ rc = ble_gap_adv_start (addrType, NULL , 5000 , &adv_params, GAPEventCallback, this );
143+ ASSERT (rc == 0 );
132144}
133145
134146int NimbleController::OnGAPEvent (ble_gap_event* event) {
135147 switch (event->type ) {
136148 case BLE_GAP_EVENT_ADV_COMPLETE:
137149 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 );
150+ NRF_LOG_INFO (" reason=%d; status=%d" , event->adv_complete .reason , event->connect .status );
151+ StartAdvertising ();
139152 break ;
153+
140154 case BLE_GAP_EVENT_CONNECT: {
141155 NRF_LOG_INFO (" Advertising event : BLE_GAP_EVENT_CONNECT" );
142156
@@ -145,18 +159,19 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
145159
146160 if (event->connect .status != 0 ) {
147161 /* Connection failed; resume advertising. */
148- StartAdvertising ();
149162 bleController.Disconnect ();
163+ StartAdvertising ();
150164 } else {
165+ connectionHandle = event->connect .conn_handle ;
151166 bleController.Connect ();
152167 systemTask.PushMessage (Pinetime::System::Messages::BleConnected);
153- connectionHandle = event->connect .conn_handle ;
154- // Service discovery is deffered via systemtask
168+ // Service discovery is deferred via systemtask
155169 }
156170 } break ;
171+
157172 case BLE_GAP_EVENT_DISCONNECT:
158173 NRF_LOG_INFO (" Advertising event : BLE_GAP_EVENT_DISCONNECT" );
159- NRF_LOG_INFO (" disconnect; reason=%d" , event->disconnect .reason );
174+ NRF_LOG_INFO (" disconnect reason=%d" , event->disconnect .reason );
160175
161176 /* Connection terminated; resume advertising. */
162177 currentTimeClient.Reset ();
@@ -165,15 +180,18 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
165180 bleController.Disconnect ();
166181 StartAdvertising ();
167182 break ;
183+
168184 case BLE_GAP_EVENT_CONN_UPDATE:
169185 NRF_LOG_INFO (" Advertising event : BLE_GAP_EVENT_CONN_UPDATE" );
170186 /* The central has updated the connection parameters. */
171- NRF_LOG_INFO (" connection updated; status=%d " , event->conn_update .status );
187+ NRF_LOG_INFO (" update status=%d " , event->conn_update .status );
172188 break ;
189+
173190 case BLE_GAP_EVENT_ENC_CHANGE:
174191 /* Encryption has been enabled or disabled for this connection. */
175192 NRF_LOG_INFO (" encryption change event; status=%d " , event->enc_change .status );
176- return 0 ;
193+ break ;
194+
177195 case BLE_GAP_EVENT_SUBSCRIBE:
178196 NRF_LOG_INFO (" subscribe event; conn_handle=%d attr_handle=%d "
179197 " reason=%d prevn=%d curn=%d previ=%d curi=???\n " ,
@@ -183,10 +201,11 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
183201 event->subscribe .prev_notify ,
184202 event->subscribe .cur_notify ,
185203 event->subscribe .prev_indicate );
186- return 0 ;
204+ break ;
205+
187206 case BLE_GAP_EVENT_MTU:
188207 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 ;
208+ break ;
190209
191210 case BLE_GAP_EVENT_REPEAT_PAIRING: {
192211 /* We already have a bond with the peer, but it is attempting to
@@ -217,8 +236,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
217236 notifSize);
218237
219238 alertNotificationClient.OnNotification (event);
220- return 0 ;
221- }
239+ } break ;
222240 /* Attribute data is contained in event->notify_rx.attr_data. */
223241
224242 default :
0 commit comments