@@ -112,18 +112,6 @@ K_MEM_SLAB_DEFINE(chan_slab, sizeof(struct bt_att_chan),
112112		  __alignof__(struct  bt_att_chan ));
113113static  struct  bt_att_req  cancel ;
114114
115- static  void  att_req_destroy (struct  bt_att_req  * req )
116- {
117- 	BT_DBG ("req %p" , req );
118- 
119- 	if  (req -> buf ) {
120- 		net_buf_unref (req -> buf );
121- 		req -> buf  =  NULL ;
122- 	}
123- 
124- 	bt_att_req_free (req );
125- }
126- 
127115typedef  void  (* bt_att_chan_sent_t )(struct  bt_att_chan  * chan );
128116
129117static  bt_att_chan_sent_t  chan_cb (struct  net_buf  * buf );
@@ -201,19 +189,14 @@ static int chan_send(struct bt_att_chan *chan, struct net_buf *buf,
201189
202190	chan -> sent  =  cb  ? cb  : chan_cb (buf );
203191
204- 	/* Take a ref since bt_l2cap_send_cb takes ownership of the buffer */ 
205192	err  =  bt_l2cap_send_cb (chan -> att -> conn , BT_L2CAP_CID_ATT ,
206- 				net_buf_ref (buf ), att_cb (chan -> sent ),
207- 				& chan -> chan .chan );
208- 	if  (!err ) {
209- 		net_buf_unref (buf );
210- 		return  0 ;
193+ 			       buf , att_cb (chan -> sent ),
194+ 			       & chan -> chan .chan );
195+ 	if  (err ) {
196+ 		net_buf_simple_restore (& buf -> b , & state );
211197	}
212198
213- 	net_buf_simple_restore (& buf -> b , & state );
214- 
215199	return  err ;
216- 
217200}
218201
219202static  int  process_queue (struct  bt_att_chan  * chan , struct  k_fifo  * queue )
@@ -239,6 +222,7 @@ static int process_queue(struct bt_att_chan *chan, struct k_fifo *queue)
239222/* Send requests without taking tx_sem */ 
240223static  int  chan_req_send (struct  bt_att_chan  * chan , struct  bt_att_req  * req )
241224{
225+ 	struct  net_buf  * buf ;
242226	int  err ;
243227
244228	if  (chan -> chan .tx .mtu  <  net_buf_frags_len (req -> buf )) {
@@ -250,19 +234,14 @@ static int chan_req_send(struct bt_att_chan *chan, struct bt_att_req *req)
250234
251235	chan -> req  =  req ;
252236
253- 	/* Save request state so it can be resent */ 
254- 	net_buf_simple_save (& req -> buf -> b , & req -> state );
237+ 	/* Release since bt_l2cap_send_cb takes ownership of the buffer */ 
238+ 	buf  =  req -> buf ;
239+ 	req -> buf  =  NULL ;
255240
256- 	/* Keep a reference for resending the req in case the security 
257- 	 * needs to be changed. 
258- 	 */ 
259- 	err  =  chan_send (chan , net_buf_ref (req -> buf ), NULL );
241+ 	err  =  chan_send (chan , buf , NULL );
260242	if  (err ) {
261- 		/* Drop the extra reference if buffer could not be sent but 
262- 		 * don't reset the buffer as it will likelly be pushed back to 
263- 		 * request queue to be send later. 
264- 		 */ 
265- 		net_buf_unref (req -> buf );
243+ 		/* We still have the ownership of the buffer */ 
244+ 		req -> buf  =  buf ;
266245	}
267246
268247	return  err ;
@@ -607,19 +586,13 @@ static uint8_t att_handle_rsp(struct bt_att_chan *chan, void *pdu, uint16_t len,
607586		goto process ;
608587	}
609588
610- 	/* Release original buffer */ 
611- 	if  (chan -> req -> buf ) {
612- 		net_buf_unref (chan -> req -> buf );
613- 		chan -> req -> buf  =  NULL ;
614- 	}
615- 
616589	/* Reset func so it can be reused by the callback */ 
617590	func  =  chan -> req -> func ;
618591	chan -> req -> func  =  NULL ;
619592	params  =  chan -> req -> user_data ;
620593
621594	/* free allocated request so its memory can be reused */ 
622- 	att_req_destroy (chan -> req );
595+ 	bt_att_req_free (chan -> req );
623596	chan -> req  =  NULL ;
624597
625598process :
@@ -2040,11 +2013,6 @@ static uint8_t att_error_rsp(struct bt_att_chan *chan, struct net_buf *buf)
20402013		goto done ;
20412014	}
20422015
2043- 	if  (chan -> req -> buf ) {
2044- 		/* Restore state to be resent */ 
2045- 		net_buf_simple_restore (& chan -> req -> buf -> b , & chan -> req -> state );
2046- 	}
2047- 
20482016	err  =  rsp -> error ;
20492017#if  defined(CONFIG_BT_SMP )
20502018	/* Check if error can be handled by elevating security. */ 
@@ -2530,7 +2498,7 @@ static void att_reset(struct bt_att *att)
25302498				  req -> user_data );
25312499		}
25322500
2533- 		att_req_destroy (req );
2501+ 		bt_att_req_free (req );
25342502	}
25352503
25362504	k_mem_slab_free (& att_slab , (void  * * )& att );
@@ -2646,12 +2614,43 @@ static void bt_att_disconnected(struct bt_l2cap_chan *chan)
26462614}
26472615
26482616#if  defined(CONFIG_BT_SMP )
2617+ static  uint8_t  att_req_retry (struct  bt_att_chan  * att_chan )
2618+ {
2619+ 	struct  bt_att_req  * req  =  att_chan -> req ;
2620+ 	struct  net_buf  * buf ;
2621+ 
2622+ 	/* Resend buffer */ 
2623+ 	if  (!req -> encode ) {
2624+ 		/* This request does not support resending */ 
2625+ 		return  BT_ATT_ERR_AUTHENTICATION ;
2626+ 	}
2627+ 
2628+ 
2629+ 	buf  =  bt_att_chan_create_pdu (att_chan , req -> att_op , req -> len );
2630+ 	if  (!buf ) {
2631+ 		return  BT_ATT_ERR_UNLIKELY ;
2632+ 	}
2633+ 
2634+ 	if  (req -> encode (buf , req -> len , req -> user_data )) {
2635+ 		net_buf_unref (buf );
2636+ 		return  BT_ATT_ERR_UNLIKELY ;
2637+ 	}
2638+ 
2639+ 	if  (chan_send (att_chan , buf , NULL )) {
2640+ 		net_buf_unref (buf );
2641+ 		return  BT_ATT_ERR_UNLIKELY ;
2642+ 	}
2643+ 
2644+ 	return  BT_ATT_ERR_SUCCESS ;
2645+ }
2646+ 
26492647static  void  bt_att_encrypt_change (struct  bt_l2cap_chan  * chan ,
26502648				  uint8_t  hci_status )
26512649{
26522650	struct  bt_att_chan  * att_chan  =  ATT_CHAN (chan );
26532651	struct  bt_l2cap_le_chan  * ch  =  BT_L2CAP_LE_CHAN (chan );
26542652	struct  bt_conn  * conn  =  ch -> chan .conn ;
2653+ 	uint8_t  err ;
26552654
26562655	BT_DBG ("chan %p conn %p handle %u sec_level 0x%02x status 0x%02x" , ch ,
26572656	       conn , conn -> handle , conn -> sec_level , hci_status );
@@ -2686,14 +2685,10 @@ static void bt_att_encrypt_change(struct bt_l2cap_chan *chan,
26862685
26872686	BT_DBG ("Retrying" );
26882687
2689- 	/* Resend buffer */ 
2690- 
2691- 	/* Since packets are created in ATT and released in L2CAP we need to 
2692- 	 * take a new reference to "create" the packet in ATT again. 
2693- 	 */ 
2694- 	if  (chan_send (att_chan , net_buf_ref (att_chan -> req -> buf ), NULL )) {
2695- 		net_buf_unref (att_chan -> req -> buf );
2696- 		att_handle_rsp (att_chan , NULL , 0 , BT_ATT_ERR_AUTHENTICATION );
2688+ 	err  =  att_req_retry (att_chan );
2689+ 	if  (err ) {
2690+ 		BT_DBG ("Retry failed (%d)" , err );
2691+ 		att_handle_rsp (att_chan , NULL , 0 , err );
26972692	}
26982693}
26992694#endif  /* CONFIG_BT_SMP */ 
@@ -2932,6 +2927,7 @@ struct bt_att_req *bt_att_req_alloc(k_timeout_t timeout)
29322927
29332928	/* Reserve space for request */ 
29342929	if  (k_mem_slab_alloc (& req_slab , (void  * * )& req , timeout )) {
2930+ 		BT_DBG ("No space for req" );
29352931		return  NULL ;
29362932	}
29372933
@@ -2946,6 +2942,11 @@ void bt_att_req_free(struct bt_att_req *req)
29462942{
29472943	BT_DBG ("req %p" , req );
29482944
2945+ 	if  (req -> buf ) {
2946+ 		net_buf_unref (req -> buf );
2947+ 		req -> buf  =  NULL ;
2948+ 	}
2949+ 
29492950	k_mem_slab_free (& req_slab , (void  * * )& req );
29502951}
29512952
@@ -3003,8 +3004,6 @@ int bt_att_req_send(struct bt_conn *conn, struct bt_att_req *req)
30033004
30043005	att  =  att_get (conn );
30053006	if  (!att ) {
3006- 		net_buf_unref (req -> buf );
3007- 		req -> buf  =  NULL ;
30083007		return  - ENOTCONN ;
30093008	}
30103009
@@ -3037,7 +3036,7 @@ static bool bt_att_chan_req_cancel(struct bt_att_chan *chan,
30373036
30383037	chan -> req  =  & cancel ;
30393038
3040- 	att_req_destroy (req );
3039+ 	bt_att_req_free (req );
30413040
30423041	return  true;
30433042}
@@ -3068,5 +3067,5 @@ void bt_att_req_cancel(struct bt_conn *conn, struct bt_att_req *req)
30683067	/* Remove request from the list */ 
30693068	sys_slist_find_and_remove (& att -> reqs , & req -> node );
30703069
3071- 	att_req_destroy (req );
3070+ 	bt_att_req_free (req );
30723071}
0 commit comments