1111#include <zephyr/bluetooth/gatt.h>
1212
1313#include <pouch/transport/gatt/common/packetizer.h>
14+ #include <pouch/transport/gatt/common/receiver.h>
1415
1516#include <pouch_gateway/bt/connect.h>
1617
2223#include <zephyr/logging/log.h>
2324LOG_MODULE_REGISTER (device_cert_gatt , CONFIG_POUCH_GATEWAY_GATT_LOG_LEVEL );
2425
25-
2626static void device_cert_cleanup (struct bt_conn * conn )
2727{
2828 struct pouch_gateway_node_info * node = pouch_gateway_get_node_info (conn );
@@ -32,80 +32,120 @@ static void device_cert_cleanup(struct bt_conn *conn)
3232 pouch_gateway_device_cert_abort (node -> device_cert_ctx );
3333 node -> device_cert_ctx = NULL ;
3434 }
35+
36+ if (node -> device_cert_receiver )
37+ {
38+ pouch_gatt_receiver_destroy (node -> device_cert_receiver );
39+ node -> device_cert_receiver = NULL ;
40+ }
3541}
3642
37- static uint8_t device_cert_read_cb ( struct bt_conn * conn ,
38- uint8_t err ,
39- struct bt_gatt_read_params * params ,
40- const void * data ,
41- uint16_t length )
43+ static int device_cert_data_received_cb ( void * conn ,
44+ const void * data ,
45+ size_t length ,
46+ bool is_first ,
47+ bool is_last )
4248{
4349 struct pouch_gateway_node_info * node = pouch_gateway_get_node_info (conn );
4450
51+ int err = pouch_gateway_device_cert_push (node -> device_cert_ctx , data , length );
4552 if (err )
4653 {
47- LOG_ERR ("Failed to read BLE GATT %s (err %d)" , "device cert" , err );
48- device_cert_cleanup (conn );
49- pouch_gateway_bt_finished (conn );
50- return BT_GATT_ITER_STOP ;
54+ LOG_ERR ("Failed to push device cert" );
55+ goto finish ;
5156 }
5257
53- if (length == 0 )
58+ if (is_last )
5459 {
55- LOG_ERR ("No device cert" );
56- device_cert_cleanup (conn );
57- pouch_gateway_bt_finished (conn );
58- return BT_GATT_ITER_STOP ;
60+ err = pouch_gateway_device_cert_finish (node -> device_cert_ctx );
61+ if (err )
62+ {
63+ LOG_ERR ("Failed to finish device cert: %d" , err );
64+ goto finish ;
65+ }
66+ node -> device_cert_ctx = NULL ;
5967 }
6068
61- bool is_first = false;
62- bool is_last = false;
63- const void * payload = NULL ;
64- ssize_t payload_len = pouch_gatt_packetizer_decode (data , length , & payload , & is_first , & is_last );
65- if (payload_len < 0 )
69+ finish :
70+ if (err )
6671 {
67- LOG_ERR ("Failed to decode BLE GATT %s (err %d)" , "device cert" , (int ) payload_len );
6872 device_cert_cleanup (conn );
6973 pouch_gateway_bt_finished (conn );
70- return BT_GATT_ITER_STOP ;
7174 }
7275
73- if (data )
76+ return err ;
77+ }
78+
79+ static int send_ack_cb (void * conn , const void * data , size_t length )
80+ {
81+ struct pouch_gateway_node_info * node = pouch_gateway_get_node_info (conn );
82+ uint16_t handle = node -> attr_handles [POUCH_GATEWAY_GATT_ATTR_DEVICE_CERT ].value ;
83+
84+ return bt_gatt_write_without_response (conn , handle , data , length , false);
85+ }
86+
87+ static uint8_t device_cert_notify_cb (struct bt_conn * conn ,
88+ struct bt_gatt_subscribe_params * params ,
89+ const void * data ,
90+ uint16_t length )
91+ {
92+ struct pouch_gateway_node_info * node = pouch_gateway_get_node_info (conn );
93+
94+ if (NULL == data )
7495 {
75- LOG_HEXDUMP_DBG ( data , length , "[READ] BLE GATT device cert " );
76- }
96+ LOG_DBG ( "Subscription terminated " );
97+ device_cert_cleanup ( conn );
7798
78- pouch_gateway_device_cert_push (node -> device_cert_ctx , payload , payload_len );
99+ return BT_GATT_ITER_STOP ;
100+ }
79101
80- if (is_last )
102+ if (NULL == node -> device_cert_receiver )
81103 {
82- int err = pouch_gateway_device_cert_finish ( node -> device_cert_ctx ) ;
83- if (err )
104+ enum pouch_gatt_ack_code code ;
105+ if (pouch_gatt_packetizer_is_fin ( data , length , & code ) )
84106 {
85- LOG_ERR ("Failed to finish device cert: %d" , err );
86- device_cert_cleanup (conn );
87- pouch_gateway_bt_finished (conn );
88- return BT_GATT_ITER_STOP ;
107+ LOG_WRN ("Received FIN while idle: %d" , code );
108+ }
109+ else
110+ {
111+ LOG_ERR ("Received packet while idle" );
112+
113+ pouch_gatt_receiver_send_nack (send_ack_cb , conn , POUCH_GATT_NACK_IDLE );
89114 }
90115
91- pouch_gateway_uplink_start (conn );
92116 return BT_GATT_ITER_STOP ;
93117 }
94118
95- err = bt_gatt_read (conn , params );
119+ bool complete = false;
120+ int err = pouch_gatt_receiver_receive_data (node -> device_cert_receiver , data , length , & complete );
96121 if (err )
97122 {
98- LOG_ERR ("BT (re)read request failed: %d" , err );
123+ LOG_ERR ("Error receiving data: %d" , err );
124+
99125 device_cert_cleanup (conn );
126+
100127 pouch_gateway_bt_finished (conn );
128+
101129 return BT_GATT_ITER_STOP ;
102130 }
103131
104- return BT_GATT_ITER_STOP ;
132+ if (complete )
133+ {
134+ device_cert_cleanup (conn );
135+
136+ pouch_gateway_uplink_start (conn );
137+
138+ return BT_GATT_ITER_STOP ;
139+ }
140+
141+
142+ return BT_GATT_ITER_CONTINUE ;
105143}
106144
107145void pouch_gateway_device_cert_read (struct bt_conn * conn )
108146{
147+ LOG_INF ("Starting device cert read" );
148+
109149 struct pouch_gateway_node_info * node = pouch_gateway_get_node_info (conn );
110150
111151 if (node -> device_cert_provisioned )
@@ -114,8 +154,12 @@ void pouch_gateway_device_cert_read(struct bt_conn *conn)
114154 return ;
115155 }
116156
117- struct bt_gatt_read_params * read_params = & node -> read_params ;
118- memset (read_params , 0 , sizeof (* read_params ));
157+ if (0 == node -> attr_handles [POUCH_GATEWAY_GATT_ATTR_DEVICE_CERT ].ccc )
158+ {
159+ LOG_ERR ("Did not discover Device Cert CCC" );
160+ pouch_gateway_bt_finished (conn );
161+ return ;
162+ }
119163
120164 node -> device_cert_ctx = pouch_gateway_device_cert_start ();
121165 if (node -> device_cert_ctx == NULL )
@@ -126,13 +170,32 @@ void pouch_gateway_device_cert_read(struct bt_conn *conn)
126170 return ;
127171 }
128172
129- read_params -> func = device_cert_read_cb ;
130- read_params -> handle_count = 1 ;
131- read_params -> single .handle = node -> attr_handles [POUCH_GATEWAY_GATT_ATTR_DEVICE_CERT ].value ;
132- int err = bt_gatt_read (conn , read_params );
173+ node -> device_cert_receiver =
174+ pouch_gatt_receiver_create (send_ack_cb ,
175+ conn ,
176+ device_cert_data_received_cb ,
177+ conn ,
178+ CONFIG_POUCH_GATT_DEVICE_CERT_WINDOW_SIZE );
179+ if (NULL == node -> device_cert_receiver )
180+ {
181+ LOG_ERR ("Failed to create receiver" );
182+ device_cert_cleanup (conn );
183+ pouch_gateway_bt_finished (conn );
184+ return ;
185+ }
186+
187+ struct bt_gatt_subscribe_params * subscribe_params = & node -> device_cert_subscribe_params ;
188+ memset (subscribe_params , 0 , sizeof (* subscribe_params ));
189+
190+ subscribe_params -> notify = device_cert_notify_cb ;
191+ subscribe_params -> value = BT_GATT_CCC_NOTIFY ;
192+ subscribe_params -> value_handle = node -> attr_handles [POUCH_GATEWAY_GATT_ATTR_DEVICE_CERT ].value ;
193+ subscribe_params -> ccc_handle = node -> attr_handles [POUCH_GATEWAY_GATT_ATTR_DEVICE_CERT ].ccc ;
194+ atomic_set_bit (subscribe_params -> flags , BT_GATT_SUBSCRIBE_FLAG_VOLATILE );
195+ int err = bt_gatt_subscribe (conn , subscribe_params );
133196 if (err )
134197 {
135- LOG_ERR ("BT read request failed: %d" , err );
198+ LOG_ERR ("BT subscribe request failed: %d" , err );
136199 device_cert_cleanup (conn );
137200 pouch_gateway_bt_finished (conn );
138201 }
0 commit comments