@@ -109,6 +109,7 @@ enum {
109
109
SEND_CONFIRM , /* Waiting to send Confirm value */
110
110
WAIT_NUMBER , /* Waiting for number input from user */
111
111
WAIT_STRING , /* Waiting for string input from user */
112
+ LINK_INVALID , /* Error occurred during provisioning */
112
113
113
114
NUM_FLAGS ,
114
115
};
@@ -160,6 +161,8 @@ struct prov_link {
160
161
struct k_delayed_work retransmit ;
161
162
} tx ;
162
163
#endif
164
+
165
+ struct k_delayed_work prot_timer ;
163
166
};
164
167
165
168
struct prov_rx {
@@ -171,6 +174,7 @@ struct prov_rx {
171
174
#define RETRANSMIT_TIMEOUT K_MSEC(500)
172
175
#define BUF_TIMEOUT K_MSEC(400)
173
176
#define TRANSACTION_TIMEOUT K_SECONDS(30)
177
+ #define PROTOCOL_TIMEOUT K_SECONDS(60)
174
178
175
179
#if defined(CONFIG_BT_MESH_PB_GATT )
176
180
#define PROV_BUF_HEADROOM 5
@@ -186,10 +190,10 @@ static struct prov_link link;
186
190
187
191
static const struct bt_mesh_prov * prov ;
188
192
189
- static void close_link (u8_t err , u8_t reason );
190
-
191
193
static void reset_state (void )
192
194
{
195
+ k_delayed_work_cancel (& link .prot_timer );
196
+
193
197
/* Disable Attention Timer if it was set */
194
198
if (link .conf_inputs [0 ]) {
195
199
bt_mesh_attention (NULL , 0 );
@@ -202,7 +206,9 @@ static void reset_state(void)
202
206
#endif
203
207
204
208
#if defined(CONFIG_BT_MESH_PB_ADV )
205
- /* Clear everything except the retransmit delayed work config */
209
+ /* Clear everything except the retransmit and protocol timer
210
+ * delayed work objects.
211
+ */
206
212
(void )memset (& link , 0 , offsetof(struct prov_link , tx .retransmit ));
207
213
link .rx .prev_id = XACT_NVAL ;
208
214
@@ -213,8 +219,9 @@ static void reset_state(void)
213
219
link .rx .buf = & rx_buf ;
214
220
#endif /* PB_GATT */
215
221
216
- #else
217
- (void )memset (& link , 0 , sizeof (link ));
222
+ #else /* !PB_ADV */
223
+ /* Clear everything except the protocol timer (k_delayed_work) */
224
+ (void )memset (& link , 0 , offsetof(struct prov_link , prot_timer ));
218
225
#endif /* PB_ADV */
219
226
}
220
227
@@ -471,6 +478,8 @@ static int prov_send_gatt(struct net_buf_simple *msg)
471
478
472
479
static inline int prov_send (struct net_buf_simple * buf )
473
480
{
481
+ k_delayed_work_submit (& link .prot_timer , PROTOCOL_TIMEOUT );
482
+
474
483
#if defined(CONFIG_BT_MESH_PB_GATT )
475
484
if (link .conn ) {
476
485
return prov_send_gatt (buf );
@@ -496,6 +505,8 @@ static void prov_send_fail_msg(u8_t err)
496
505
prov_buf_init (& buf , PROV_FAILED );
497
506
net_buf_simple_add_u8 (& buf , err );
498
507
prov_send (& buf );
508
+
509
+ atomic_set_bit (link .flags , LINK_INVALID );
499
510
}
500
511
501
512
static void prov_invite (const u8_t * data )
@@ -540,7 +551,7 @@ static void prov_invite(const u8_t *data)
540
551
541
552
if (prov_send (& buf )) {
542
553
BT_ERR ("Failed to send capabilities" );
543
- close_link (PROV_ERR_RESOURCES , CLOSE_REASON_FAILED );
554
+ prov_send_fail_msg (PROV_ERR_RESOURCES );
544
555
return ;
545
556
}
546
557
@@ -746,23 +757,23 @@ static void send_confirm(void)
746
757
747
758
if (bt_mesh_prov_conf_salt (link .conf_inputs , link .conf_salt )) {
748
759
BT_ERR ("Unable to generate confirmation salt" );
749
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
760
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
750
761
return ;
751
762
}
752
763
753
764
BT_DBG ("ConfirmationSalt: %s" , bt_hex (link .conf_salt , 16 ));
754
765
755
766
if (bt_mesh_prov_conf_key (link .dhkey , link .conf_salt , link .conf_key )) {
756
767
BT_ERR ("Unable to generate confirmation key" );
757
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
768
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
758
769
return ;
759
770
}
760
771
761
772
BT_DBG ("ConfirmationKey: %s" , bt_hex (link .conf_key , 16 ));
762
773
763
774
if (bt_rand (link .rand , 16 )) {
764
775
BT_ERR ("Unable to generate random number" );
765
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
776
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
766
777
return ;
767
778
}
768
779
@@ -773,13 +784,13 @@ static void send_confirm(void)
773
784
if (bt_mesh_prov_conf (link .conf_key , link .rand , link .auth ,
774
785
net_buf_simple_add (& cfm , 16 ))) {
775
786
BT_ERR ("Unable to generate confirmation value" );
776
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
787
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
777
788
return ;
778
789
}
779
790
780
791
if (prov_send (& cfm )) {
781
792
BT_ERR ("Failed to send Provisioning Confirm" );
782
- close_link (PROV_ERR_RESOURCES , CLOSE_REASON_FAILED );
793
+ prov_send_fail_msg (PROV_ERR_RESOURCES );
783
794
return ;
784
795
}
785
796
@@ -846,7 +857,7 @@ static void prov_dh_key_cb(const u8_t key[32])
846
857
847
858
if (!key ) {
848
859
BT_ERR ("DHKey generation failed" );
849
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
860
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
850
861
return ;
851
862
}
852
863
@@ -874,7 +885,7 @@ static void send_pub_key(void)
874
885
key = bt_pub_key_get ();
875
886
if (!key ) {
876
887
BT_ERR ("No public key available" );
877
- close_link ( PROV_ERR_RESOURCES , CLOSE_REASON_FAILED );
888
+ prov_send_fail_msg ( PROV_ERR_UNEXP_ERR );
878
889
return ;
879
890
}
880
891
@@ -899,7 +910,7 @@ static void send_pub_key(void)
899
910
900
911
if (bt_dh_key_gen (buf .data , prov_dh_key_cb )) {
901
912
BT_ERR ("Failed to generate DHKey" );
902
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
913
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
903
914
return ;
904
915
}
905
916
@@ -969,15 +980,15 @@ static void prov_random(const u8_t *data)
969
980
970
981
if (bt_mesh_prov_conf (link .conf_key , data , link .auth , conf_verify )) {
971
982
BT_ERR ("Unable to calculate confirmation verification" );
972
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
983
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
973
984
return ;
974
985
}
975
986
976
987
if (memcmp (conf_verify , link .conf , 16 )) {
977
988
BT_ERR ("Invalid confirmation value" );
978
989
BT_DBG ("Received: %s" , bt_hex (link .conf , 16 ));
979
990
BT_DBG ("Calculated: %s" , bt_hex (conf_verify , 16 ));
980
- close_link (PROV_ERR_CFM_FAILED , CLOSE_REASON_FAILED );
991
+ prov_send_fail_msg (PROV_ERR_CFM_FAILED );
981
992
return ;
982
993
}
983
994
@@ -986,14 +997,14 @@ static void prov_random(const u8_t *data)
986
997
987
998
if (prov_send (& rnd )) {
988
999
BT_ERR ("Failed to send Provisioning Random" );
989
- close_link (PROV_ERR_RESOURCES , CLOSE_REASON_FAILED );
1000
+ prov_send_fail_msg (PROV_ERR_RESOURCES );
990
1001
return ;
991
1002
}
992
1003
993
1004
if (bt_mesh_prov_salt (link .conf_salt , data , link .rand ,
994
1005
link .prov_salt )) {
995
1006
BT_ERR ("Failed to generate provisioning salt" );
996
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
1007
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
997
1008
return ;
998
1009
}
999
1010
@@ -1030,7 +1041,7 @@ static void prov_data(const u8_t *data)
1030
1041
err = bt_mesh_session_key (link .dhkey , link .prov_salt , session_key );
1031
1042
if (err ) {
1032
1043
BT_ERR ("Unable to generate session key" );
1033
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
1044
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
1034
1045
return ;
1035
1046
}
1036
1047
@@ -1039,7 +1050,7 @@ static void prov_data(const u8_t *data)
1039
1050
err = bt_mesh_prov_nonce (link .dhkey , link .prov_salt , nonce );
1040
1051
if (err ) {
1041
1052
BT_ERR ("Unable to generate session nonce" );
1042
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
1053
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
1043
1054
return ;
1044
1055
}
1045
1056
@@ -1048,14 +1059,14 @@ static void prov_data(const u8_t *data)
1048
1059
err = bt_mesh_prov_decrypt (session_key , nonce , data , pdu );
1049
1060
if (err ) {
1050
1061
BT_ERR ("Unable to decrypt provisioning data" );
1051
- close_link (PROV_ERR_DECRYPT , CLOSE_REASON_FAILED );
1062
+ prov_send_fail_msg (PROV_ERR_DECRYPT );
1052
1063
return ;
1053
1064
}
1054
1065
1055
1066
err = bt_mesh_dev_key (link .dhkey , link .prov_salt , dev_key );
1056
1067
if (err ) {
1057
1068
BT_ERR ("Unable to generate device key" );
1058
- close_link (PROV_ERR_UNEXP_ERR , CLOSE_REASON_FAILED );
1069
+ prov_send_fail_msg (PROV_ERR_UNEXP_ERR );
1059
1070
return ;
1060
1071
}
1061
1072
@@ -1122,27 +1133,6 @@ static const struct {
1122
1133
{ prov_failed , 1 },
1123
1134
};
1124
1135
1125
- static void close_link (u8_t err , u8_t reason )
1126
- {
1127
- #if defined(CONFIG_BT_MESH_PB_GATT )
1128
- if (link .conn ) {
1129
- bt_mesh_pb_gatt_close (link .conn );
1130
- return ;
1131
- }
1132
- #endif
1133
-
1134
- #if defined(CONFIG_BT_MESH_PB_ADV )
1135
- if (err ) {
1136
- prov_send_fail_msg (err );
1137
- }
1138
-
1139
- link .rx .seg = 0U ;
1140
- bearer_ctl_send (LINK_CLOSE , & reason , sizeof (reason ));
1141
- #endif
1142
-
1143
- reset_state ();
1144
- }
1145
-
1146
1136
#if defined(CONFIG_BT_MESH_PB_ADV )
1147
1137
static void prov_retransmit (struct k_work * work )
1148
1138
{
@@ -1273,6 +1263,8 @@ static void prov_msg_recv(void)
1273
1263
1274
1264
BT_DBG ("type 0x%02x len %u" , type , link .rx .buf -> len );
1275
1265
1266
+ k_delayed_work_submit (& link .prot_timer , PROTOCOL_TIMEOUT );
1267
+
1276
1268
if (!bt_mesh_fcs_check (link .rx .buf , link .rx .fcs )) {
1277
1269
BT_ERR ("Incorrect FCS" );
1278
1270
return ;
@@ -1282,6 +1274,12 @@ static void prov_msg_recv(void)
1282
1274
link .rx .prev_id = link .rx .id ;
1283
1275
link .rx .id = 0U ;
1284
1276
1277
+ if (atomic_test_bit (link .flags , LINK_INVALID )) {
1278
+ BT_WARN ("Unexpected msg 0x%02x on invalidated link" , type );
1279
+ prov_send_fail_msg (PROV_ERR_UNEXP_PDU );
1280
+ return ;
1281
+ }
1282
+
1285
1283
if (type != PROV_FAILED && type != link .expect ) {
1286
1284
BT_WARN ("Unexpected msg 0x%02x != 0x%02x" , type , link .expect );
1287
1285
prov_send_fail_msg (PROV_ERR_UNEXP_PDU );
@@ -1290,14 +1288,14 @@ static void prov_msg_recv(void)
1290
1288
1291
1289
if (type >= ARRAY_SIZE (prov_handlers )) {
1292
1290
BT_ERR ("Unknown provisioning PDU type 0x%02x" , type );
1293
- close_link (PROV_ERR_NVAL_PDU , CLOSE_REASON_FAILED );
1291
+ prov_send_fail_msg (PROV_ERR_NVAL_PDU );
1294
1292
return ;
1295
1293
}
1296
1294
1297
1295
if (1 + prov_handlers [type ].len != link .rx .buf -> len ) {
1298
1296
BT_ERR ("Invalid length %u for type 0x%02x" ,
1299
1297
link .rx .buf -> len , type );
1300
- close_link (PROV_ERR_NVAL_FMT , CLOSE_REASON_FAILED );
1298
+ prov_send_fail_msg (PROV_ERR_NVAL_FMT );
1301
1299
return ;
1302
1300
}
1303
1301
@@ -1324,7 +1322,7 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf)
1324
1322
1325
1323
if (seg > link .rx .last_seg ) {
1326
1324
BT_ERR ("Invalid segment index %u" , seg );
1327
- close_link (PROV_ERR_NVAL_FMT , CLOSE_REASON_FAILED );
1325
+ prov_send_fail_msg (PROV_ERR_NVAL_FMT );
1328
1326
return ;
1329
1327
} else if (seg == link .rx .last_seg ) {
1330
1328
u8_t expect_len ;
@@ -1334,7 +1332,7 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf)
1334
1332
if (expect_len != buf -> len ) {
1335
1333
BT_ERR ("Incorrect last seg len: %u != %u" ,
1336
1334
expect_len , buf -> len );
1337
- close_link (PROV_ERR_NVAL_FMT , CLOSE_REASON_FAILED );
1335
+ prov_send_fail_msg (PROV_ERR_NVAL_FMT );
1338
1336
return ;
1339
1337
}
1340
1338
}
@@ -1387,20 +1385,20 @@ static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf)
1387
1385
1388
1386
if (link .rx .buf -> len < 1 ) {
1389
1387
BT_ERR ("Ignoring zero-length provisioning PDU" );
1390
- close_link (PROV_ERR_NVAL_FMT , CLOSE_REASON_FAILED );
1388
+ prov_send_fail_msg (PROV_ERR_NVAL_FMT );
1391
1389
return ;
1392
1390
}
1393
1391
1394
1392
if (link .rx .buf -> len > link .rx .buf -> size ) {
1395
1393
BT_ERR ("Too large provisioning PDU (%u bytes)" ,
1396
1394
link .rx .buf -> len );
1397
- close_link (PROV_ERR_NVAL_FMT , CLOSE_REASON_FAILED );
1395
+ prov_send_fail_msg (PROV_ERR_NVAL_FMT );
1398
1396
return ;
1399
1397
}
1400
1398
1401
1399
if (START_LAST_SEG (rx -> gpc ) > 0 && link .rx .buf -> len <= 20U ) {
1402
1400
BT_ERR ("Too small total length for multi-segment PDU" );
1403
- close_link (PROV_ERR_NVAL_FMT , CLOSE_REASON_FAILED );
1401
+ prov_send_fail_msg (PROV_ERR_NVAL_FMT );
1404
1402
return ;
1405
1403
}
1406
1404
@@ -1556,6 +1554,27 @@ bool bt_prov_active(void)
1556
1554
return atomic_test_bit (link .flags , LINK_ACTIVE );
1557
1555
}
1558
1556
1557
+ static void protocol_timeout (struct k_work * work )
1558
+ {
1559
+ BT_DBG ("Protocol timeout" );
1560
+
1561
+ #if defined(CONFIG_BT_MESH_PB_GATT )
1562
+ if (link .conn ) {
1563
+ bt_mesh_pb_gatt_close (link .conn );
1564
+ return ;
1565
+ }
1566
+ #endif
1567
+
1568
+ #if defined(CONFIG_BT_MESH_PB_ADV )
1569
+ u8_t reason = CLOSE_REASON_TIMEOUT ;
1570
+
1571
+ link .rx .seg = 0U ;
1572
+ bearer_ctl_send (LINK_CLOSE , & reason , sizeof (reason ));
1573
+
1574
+ reset_state ();
1575
+ #endif
1576
+ }
1577
+
1559
1578
int bt_mesh_prov_init (const struct bt_mesh_prov * prov_info )
1560
1579
{
1561
1580
static struct bt_pub_key_cb pub_key_cb = {
@@ -1568,6 +1587,8 @@ int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info)
1568
1587
return - EINVAL ;
1569
1588
}
1570
1589
1590
+ k_delayed_work_init (& link .prot_timer , protocol_timeout );
1591
+
1571
1592
err = bt_pub_key_gen (& pub_key_cb );
1572
1593
if (err ) {
1573
1594
BT_ERR ("Failed to generate public key (%d)" , err );
0 commit comments