1212#include <soc.h>
1313#include <toolchain.h>
1414#include <errno.h>
15+ #include <atomic.h>
1516#include <bluetooth/hci.h>
1617#include <bluetooth/buf.h>
1718#include <bluetooth/bluetooth.h>
@@ -46,6 +47,18 @@ static s32_t dup_count;
4647static u32_t dup_curr ;
4748#endif
4849
50+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC )
51+ s32_t hci_hbuf_total ;
52+ u32_t hci_hbuf_sent ;
53+ u32_t hci_hbuf_acked ;
54+ atomic_t hci_state_mask ;
55+ static struct k_poll_signal * hbuf_signal ;
56+ #endif
57+
58+ #if defined(CONFIG_BLUETOOTH_CONN )
59+ static u32_t conn_count ;
60+ #endif
61+
4962#define DEFAULT_EVENT_MASK 0x1fffffffffff
5063#define DEFAULT_LE_EVENT_MASK 0x1f
5164
@@ -159,18 +172,119 @@ static void reset(struct net_buf *buf, struct net_buf **evt)
159172{
160173 struct bt_hci_evt_cc_status * ccst ;
161174
162- ll_reset ();
163-
164175#if CONFIG_BLUETOOTH_CONTROLLER_DUP_FILTER_LEN > 0
165176 dup_count = -1 ;
166177#endif
167178 /* reset event masks */
168179 event_mask = DEFAULT_EVENT_MASK ;
169180 le_event_mask = DEFAULT_LE_EVENT_MASK ;
170181
182+ if (buf ) {
183+ ll_reset ();
184+ ccst = cmd_complete (evt , sizeof (* ccst ));
185+ ccst -> status = 0x00 ;
186+ }
187+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC )
188+ hci_hbuf_total = 0 ;
189+ hci_hbuf_sent = 0 ;
190+ hci_hbuf_acked = 0 ;
191+ conn_count = 0 ;
192+ atomic_set_bit (& hci_state_mask , HCI_STATE_BIT_RESET );
193+ k_poll_signal (hbuf_signal , 0x0 );
194+ #endif
195+ }
196+
197+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC )
198+ static void set_ctl_to_host_flow (struct net_buf * buf , struct net_buf * * evt )
199+ {
200+ struct bt_hci_cp_set_ctl_to_host_flow * cmd = (void * )buf -> data ;
201+ struct bt_hci_evt_cc_status * ccst ;
202+
171203 ccst = cmd_complete (evt , sizeof (* ccst ));
172- ccst -> status = 0x00 ;
204+
205+ /* require host buffer size before enabling flow control, and
206+ * disallow if any connections are up
207+ */
208+ if (!hci_hbuf_total || conn_count ) {
209+ ccst -> status = BT_HCI_ERR_CMD_DISALLOWED ;
210+ return ;
211+ } else {
212+ ccst -> status = 0x00 ;
213+ }
214+
215+ switch (cmd -> flow_enable ) {
216+ case BT_HCI_CTL_TO_HOST_FLOW_DISABLE :
217+ if (hci_hbuf_total < 0 ) {
218+ /* already disabled */
219+ return ;
220+ }
221+ break ;
222+ case BT_HCI_CTL_TO_HOST_FLOW_ENABLE :
223+ if (hci_hbuf_total > 0 ) {
224+ /* already enabled */
225+ return ;
226+ }
227+ break ;
228+ default :
229+ ccst -> status = BT_HCI_ERR_INVALID_PARAM ;
230+ return ;
231+ }
232+
233+ hci_hbuf_sent = 0 ;
234+ hci_hbuf_acked = 0 ;
235+ hci_hbuf_total = - hci_hbuf_total ;
236+ }
237+
238+ static void host_buffer_size (struct net_buf * buf , struct net_buf * * evt )
239+ {
240+ struct bt_hci_cp_host_buffer_size * cmd = (void * )buf -> data ;
241+ struct bt_hci_evt_cc_status * ccst ;
242+
243+ ccst = cmd_complete (evt , sizeof (* ccst ));
244+
245+ if (hci_hbuf_total ) {
246+ ccst -> status = BT_HCI_ERR_CMD_DISALLOWED ;
247+ return ;
248+ }
249+ /* fragmentation from controller to host not supported, require
250+ * ACL MTU to be at least the LL MTU
251+ */
252+ if (cmd -> acl_mtu < RADIO_LL_LENGTH_OCTETS_RX_MAX ) {
253+ ccst -> status = BT_HCI_ERR_INVALID_PARAM ;
254+ return ;
255+ }
256+
257+ hci_hbuf_total = - cmd -> acl_pkts ;
258+ }
259+
260+ static void host_num_completed_packets (struct net_buf * buf ,
261+ struct net_buf * * evt )
262+ {
263+ struct bt_hci_cp_host_num_completed_packets * cmd = (void * )buf -> data ;
264+ struct bt_hci_evt_cc_status * ccst ;
265+ u32_t count = 0 ;
266+ int i ;
267+
268+ /* special case, no event returned except for error conditions */
269+ if (hci_hbuf_total <= 0 ) {
270+ ccst = cmd_complete (evt , sizeof (* ccst ));
271+ ccst -> status = BT_HCI_ERR_CMD_DISALLOWED ;
272+ return ;
273+ } else if (!conn_count ) {
274+ ccst = cmd_complete (evt , sizeof (* ccst ));
275+ ccst -> status = BT_HCI_ERR_INVALID_PARAM ;
276+ return ;
277+ }
278+
279+ /* leave *evt == NULL so no event is generated */
280+ for (i = 0 ; i < cmd -> num_handles ; i ++ ) {
281+ count += cmd -> h [i ].count ;
282+ }
283+
284+ hci_hbuf_acked += count ;
285+ k_poll_signal (hbuf_signal , 0x0 );
173286}
287+ #endif
174288
175289static int ctrl_bb_cmd_handle (u8_t ocf , struct net_buf * cmd ,
176290 struct net_buf * * evt )
@@ -184,6 +298,19 @@ static int ctrl_bb_cmd_handle(u8_t ocf, struct net_buf *cmd,
184298 reset (cmd , evt );
185299 break ;
186300
301+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC )
302+ case BT_OCF (BT_HCI_OP_SET_CTL_TO_HOST_FLOW ):
303+ set_ctl_to_host_flow (cmd , evt );
304+ break ;
305+
306+ case BT_OCF (BT_HCI_OP_HOST_BUFFER_SIZE ):
307+ host_buffer_size (cmd , evt );
308+ break ;
309+
310+ case BT_OCF (BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS ):
311+ host_num_completed_packets (cmd , evt );
312+ break ;
313+ #endif
187314 default :
188315 return - EINVAL ;
189316 }
@@ -1082,6 +1209,7 @@ static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b,
10821209
10831210}
10841211
1212+ #if defined(CONFIG_BLUETOOTH_CONN )
10851213static void le_conn_complete (struct pdu_data * pdu_data , u16_t handle ,
10861214 struct net_buf * buf )
10871215{
@@ -1106,6 +1234,8 @@ static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle,
11061234 sep -> latency = sys_cpu_to_le16 (radio_cc -> latency );
11071235 sep -> supv_timeout = sys_cpu_to_le16 (radio_cc -> timeout );
11081236 sep -> clock_accuracy = radio_cc -> mca ;
1237+
1238+ conn_count ++ ;
11091239}
11101240
11111241static void disconn_complete (struct pdu_data * pdu_data , u16_t handle ,
@@ -1123,6 +1253,8 @@ static void disconn_complete(struct pdu_data *pdu_data, u16_t handle,
11231253 ep -> status = 0x00 ;
11241254 ep -> handle = sys_cpu_to_le16 (handle );
11251255 ep -> reason = * ((u8_t * )pdu_data );
1256+
1257+ conn_count -- ;
11261258}
11271259
11281260static void le_conn_update_complete (struct pdu_data * pdu_data , u16_t handle ,
@@ -1163,6 +1295,7 @@ static void enc_refresh_complete(struct pdu_data *pdu_data, u16_t handle,
11631295 ep -> status = 0x00 ;
11641296 ep -> handle = sys_cpu_to_le16 (handle );
11651297}
1298+ #endif
11661299
11671300#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING )
11681301static void auth_payload_timeout_exp (struct pdu_data * pdu_data , u16_t handle ,
@@ -1212,6 +1345,7 @@ static void encode_control(struct radio_pdu_node_rx *node_rx,
12121345 le_advertising_report (pdu_data , b , buf );
12131346 break ;
12141347
1348+ #if defined(CONFIG_BLUETOOTH_CONN )
12151349 case NODE_RX_TYPE_CONNECTION :
12161350 le_conn_complete (pdu_data , handle , buf );
12171351 break ;
@@ -1227,6 +1361,7 @@ static void encode_control(struct radio_pdu_node_rx *node_rx,
12271361 case NODE_RX_TYPE_ENC_REFRESH :
12281362 enc_refresh_complete (pdu_data , handle , buf );
12291363 break ;
1364+ #endif
12301365
12311366#if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING )
12321367 case NODE_RX_TYPE_APTO :
@@ -1460,6 +1595,7 @@ static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx,
14601595 }
14611596}
14621597
1598+ #if defined(CONFIG_BLUETOOTH_CONN )
14631599void hci_acl_encode (struct radio_pdu_node_rx * node_rx , struct net_buf * buf )
14641600{
14651601 struct bt_hci_acl_hdr * acl ;
@@ -1484,6 +1620,13 @@ void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf)
14841620 acl -> len = sys_cpu_to_le16 (pdu_data -> len );
14851621 data = (void * )net_buf_add (buf , pdu_data -> len );
14861622 memcpy (data , & pdu_data -> payload .lldata [0 ], pdu_data -> len );
1623+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC )
1624+ if (hci_hbuf_total > 0 ) {
1625+ LL_ASSERT ((hci_hbuf_sent - hci_hbuf_acked ) <
1626+ hci_hbuf_total );
1627+ hci_hbuf_sent ++ ;
1628+ }
1629+ #endif
14871630 break ;
14881631
14891632 default :
@@ -1492,6 +1635,7 @@ void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf)
14921635 }
14931636
14941637}
1638+ #endif
14951639
14961640void hci_evt_encode (struct radio_pdu_node_rx * node_rx , struct net_buf * buf )
14971641{
@@ -1534,3 +1678,54 @@ bool hci_evt_is_discardable(struct radio_pdu_node_rx *node_rx)
15341678 return false;
15351679 }
15361680}
1681+
1682+ s8_t hci_get_class (struct radio_pdu_node_rx * node_rx )
1683+ {
1684+ struct pdu_data * pdu_data ;
1685+
1686+ pdu_data = (struct pdu_data * )node_rx -> pdu_data ;
1687+
1688+ if (node_rx -> hdr .type != NODE_RX_TYPE_DC_PDU ) {
1689+
1690+ switch (node_rx -> hdr .type ) {
1691+ case NODE_RX_TYPE_REPORT :
1692+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_INDICATION )
1693+ case NODE_RX_TYPE_ADV_INDICATION :
1694+ #endif
1695+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_PROFILE_ISR )
1696+ case NODE_RX_TYPE_PROFILE :
1697+ #endif
1698+ return HCI_CLASS_EVT_DISCARDABLE ;
1699+ case NODE_RX_TYPE_CONNECTION :
1700+ return HCI_CLASS_EVT_REQUIRED ;
1701+ case NODE_RX_TYPE_TERMINATE :
1702+ case NODE_RX_TYPE_CONN_UPDATE :
1703+ case NODE_RX_TYPE_ENC_REFRESH :
1704+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI )
1705+ case NODE_RX_TYPE_RSSI :
1706+ #endif
1707+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_LE_PING )
1708+ case NODE_RX_TYPE_APTO :
1709+ #endif
1710+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_CHAN_SEL_2 )
1711+ case NODE_RX_TYPE_CHAN_SEL_ALGO :
1712+ #endif
1713+ return HCI_CLASS_EVT_CONNECTION ;
1714+ default :
1715+ return -1 ;
1716+ }
1717+
1718+ } else if (pdu_data -> ll_id == PDU_DATA_LLID_CTRL ) {
1719+ return HCI_CLASS_EVT_CONNECTION ;
1720+ } else {
1721+ return HCI_CLASS_ACL_DATA ;
1722+ }
1723+ }
1724+
1725+ void hci_init (struct k_poll_signal * signal_host_buf )
1726+ {
1727+ #if defined(CONFIG_BLUETOOTH_CONTROLLER_TO_HOST_FC )
1728+ hbuf_signal = signal_host_buf ;
1729+ #endif
1730+ reset (NULL , NULL );
1731+ }
0 commit comments