1 /**
2  ****************************************************************************************
3  *
4  * @file hci.h
5  *
6  * @brief This file contains definitions related to the HCI module.
7  *
8  * Copyright (C) RivieraWaves 2009-2015
9  *
10  *
11  ****************************************************************************************
12  */
13 
14 #ifndef HCI_INT_H_
15 #define HCI_INT_H_
16 
17 /**
18  ****************************************************************************************
19  * @addtogroup HCI Host Controller Interface
20  *@{
21  ****************************************************************************************
22  */
23 
24 /*
25  * INCLUDE FILES
26  ****************************************************************************************
27  */
28 
29 #include "rwip_config.h"       // SW configuration
30 
31 #if (HCI_PRESENT)
32 
33 #include <stddef.h>          // standard definition
34 #include <stdint.h>          // standard integer
35 #include "co_bt.h"           // BT standard definitions
36 
37 #include "ke_msg.h"          // Kernel message definitions
38 
39 /*
40  * DEFINES
41  ****************************************************************************************
42  */
43 
44 /// Macro to get OCF of a known command
45 #define OCF(cmd)        (HCI_OP2OCF(HCI_##cmd##_CMD_OPCODE))
46 
47 /// Unknown opcode identifier
48 #define HCI_OPCODE_UNKNOWN                 0xFFFF
49 
50 /**
51  * Destination field decoding
52  *
53  * bit |     7 6      | 5 4 | 3..0 |
54  * def | Rsvd (pkupk) |  HL |  LL  |
55  */
56 #define HCI_CMD_DEST_LL_POS           0
57 #define HCI_CMD_DEST_LL_MASK          0x0F
58 #define HCI_CMD_DEST_HL_POS           4
59 #define HCI_CMD_DEST_HL_MASK          0x30
60 
61 /**
62  * Destination field decoding
63  *
64  * bit | 7..2 | 1 0 |
65  * def | Rsvd |  HL |
66  */
67 #define HCI_EVT_DEST_HL_POS           0
68 #define HCI_EVT_DEST_HL_MASK          0x03
69 
70 #if (HCI_TL_SUPPORT)
71 
72 /// Special Pack-Unpack settings for HCI commands (parameters and return parameters)
73 /**
74  * Special Pack-Unpack settings for HCI commands (parameters and return parameters)
75  *
76  * bit |    7    |  6  | 5..0 |
77  * def | RET PAR | PAR | Rsvd |
78  */
79 #define HCI_CMD_DEST_SPEC_PAR_PK_POS        6
80 #define HCI_CMD_DEST_SPEC_PAR_PK_MSK        0x40
81 #define HCI_CMD_DEST_SPEC_RET_PAR_PK_POS    7
82 #define HCI_CMD_DEST_SPEC_RET_PAR_PK_MSK    0x80
83 #define PK_GEN_GEN   (0x00)
84 #define PK_GEN_SPE   (HCI_CMD_DEST_SPEC_RET_PAR_PK_MSK)
85 #define PK_SPE_GEN   (HCI_CMD_DEST_SPEC_PAR_PK_MSK)
86 #define PK_SPE_SPE   (HCI_CMD_DEST_SPEC_RET_PAR_PK_MSK | HCI_CMD_DEST_SPEC_PAR_PK_MSK)
87 
88 /// Special Pack settings for HCI events
89 #define PK_GEN           0x00
90 #define PK_SPE           0x01
91 
92 /// Macro for building a command descriptor in split mode (with parameters packing/unpacking)
93 #define CMD(opcode, dest_ll, dest_hl, pkupk, par_size_max, par_fmt, ret_fmt)  {HCI_##opcode##_CMD_OPCODE, (dest_ll<<HCI_CMD_DEST_LL_POS) | (dest_hl<<HCI_CMD_DEST_HL_POS) | pkupk, par_size_max, (void*)par_fmt, (void*)ret_fmt}
94 /// Macro for building an event descriptor in split mode (with parameters packing/unpacking)
95 #define EVT(code, dest_hl, pkupk, par_fmt)                      {HCI_##code##_EVT_CODE, (dest_hl<<HCI_EVT_DEST_HL_POS), pkupk, (void*)par_fmt}
96 /// Macro for building an event descriptor in split mode (with parameters packing/unpacking)
97 #define LE_EVT(subcode, dest_hl, pkupk, par_fmt)                {HCI_##subcode##_EVT_SUBCODE, (dest_hl<<HCI_EVT_DEST_HL_POS), pkupk, (void*)par_fmt}
98 /// Macro for building an event descriptor in split mode (with parameters packing/unpacking)
99 #define DBG_EVT(subcode, dest_hl, pkupk, par_fmt)               {HCI_##subcode##_EVT_SUBCODE, (dest_hl<<HCI_EVT_DEST_HL_POS), pkupk, (void*)par_fmt}
100 
101 #else //(HCI_TL_SUPPORT)
102 
103 /// Macro for building a command descriptor in full mode (without parameters packing/unpacking)
104 #define CMD(opcode, dest_ll, dest_hl, pkupk, par_size_max, par_fmt, ret_fmt)  {HCI_##opcode##_CMD_OPCODE, (dest_ll<<HCI_CMD_DEST_LL_POS) | (dest_hl<<HCI_CMD_DEST_HL_POS)}
105 /// Macro for building an event descriptor in full mode (without parameters packing/unpacking)
106 #define EVT(code, dest_hl, pkupk, par_fmt)                      {HCI_##code##_EVT_CODE, (dest_hl<<HCI_EVT_DEST_HL_POS)}
107 /// Macro for building an event descriptor in full mode (without parameters packing/unpacking)
108 #define LE_EVT(subcode, dest_hl, pkupk, par_fmt)                {HCI_##subcode##_EVT_SUBCODE, (dest_hl<<HCI_EVT_DEST_HL_POS)}
109 /// Macro for building an event descriptor in full mode (without parameters packing/unpacking)
110 #define DBG_EVT(subcode, dest_hl, pkupk, par_fmt)                {HCI_##subcode##_EVT_SUBCODE, (dest_hl<<HCI_EVT_DEST_HL_POS)}
111 
112 #endif //(HCI_TL_SUPPORT)
113 
114 /*
115  * ENUMERATIONS DEFINITIONS
116  ****************************************************************************************
117  */
118 
119 /// Possible destination field values within lower layers
120 enum HCI_MSG_DEST_LL
121 {
122     MNG,
123     CTRL,
124     BLE_MNG,
125     BLE_CTRL,
126     BT_MNG,
127     BT_CTRL_CONHDL,
128     BT_CTRL_BD_ADDR,
129     BT_BCST,
130     DBG,
131     LL_UNDEF,
132 };
133 
134 /// Possible destination field values within higher layers
135 enum HCI_MSG_DEST_HL
136 {
137     HL_MNG,
138     HL_CTRL,
139     HL_DATA,
140     HL_AM0,
141     HL_UNDEF,
142 };
143 
144 #if (HCI_TL_SUPPORT)
145 /// Status returned by generic packer-unpacker
146 enum HCI_PACK_STATUS
147 {
148     HCI_PACK_OK,
149     HCI_PACK_IN_BUF_OVFLW,
150     HCI_PACK_OUT_BUF_OVFLW,
151     HCI_PACK_WRONG_FORMAT,
152     HCI_PACK_ERROR,
153 };
154 #endif //(HCI_TL_SUPPORT)
155 
156 #if  (BT_EMB_PRESENT)
157 /// Status of BT ACL connection at HCI level
158 enum HCI_BT_ACL_CON_STATUS
159 {
160     /// ACL link not active
161     HCI_BT_ACL_STATUS_NOT_ACTIVE,
162     /// ACL link ID associated with BD address
163     HCI_BT_ACL_STATUS_BD_ADDR,
164     /// ACL link ID associated with BD address + connection handle
165     HCI_BT_ACL_STATUS_BD_ADDR_CONHDL,
166 };
167 #endif //(BT_EMB_PRESENT)
168 
169 
170 /*
171  * STRUCTURES DEFINITIONS
172  ****************************************************************************************
173  */
174 
175 /// HCI command descriptor structure
176 struct hci_cmd_desc_tab_ref
177 {
178     /// OpCode Group Field (OGF)
179     uint8_t ogf;
180 
181     /// Number of commands supported in this group
182     uint16_t nb_cmds;
183 
184     /// Command descriptor table
185     const struct hci_cmd_desc_tag* cmd_desc_tab;
186 };
187 
188 /// HCI command descriptor structure
189 struct hci_cmd_desc_tag
190 {
191     /// Command opcode with flags indicating if a special packing or unpacking is needed
192     uint16_t opcode;
193 
194     /// Destination field (used to find the internal destination task)
195     uint8_t dest_field;
196 
197     #if (HCI_TL_SUPPORT)
198     /// Maximum size of the parameters
199     uint8_t  par_size_max;
200 
201     /// Parameters format string (or special unpacker)
202     void* par_fmt;
203 
204     /// Return parameters format string (or special unpacker)
205     void* ret_par_fmt;
206     #endif //(HCI_TL_SUPPORT)
207 };
208 
209 /// HCI event descriptor structure
210 struct hci_evt_desc_tag
211 {
212     /// Event opcode
213     uint8_t code;
214 
215     /// Destination field (used to find the internal destination task)
216     uint8_t dest_field;
217 
218     #if (HCI_TL_SUPPORT)
219     /// Flag indicating if a special packing is needed
220     uint8_t  special_pack;
221 
222     /// Parameters format string (or special unpacker)
223     void* par_fmt;
224     #endif //(HCI_TL_SUPPORT)
225 };
226 
227 #if (HCI_TL_SUPPORT)
228 /// HCI pack/unpack function pointer type definition
229 typedef uint16_t (*hci_pkupk_func_t)(uint8_t *out, uint8_t *in, uint16_t* out_len, uint16_t in_len);
230 #endif //(HCI_TL_SUPPORT)
231 
232 #if (BT_EMB_PRESENT)
233 /// HCI Environment context structure
234 struct hci_bt_acl_con_tag
235 {
236         /**
237          * BT ACL connection status
238          * - 0x00: Not active
239          * - 0x01: link ID associated with BD address
240          * - 0x02: link ID associated with BD address + connection handle
241          */
242         uint8_t state;
243 
244         /// BD address associated with link ID
245         struct bd_addr bd_addr;
246 };
247 
248 /// Condition based on class of device
249 struct classofdevcondition
250 {
251     /// Class of device
252     struct devclass classofdev;
253     /// Device mask
254     struct devclass class_mask;
255 };
256 
257 /// Condition based on device class
258 union cond
259 {
260     /// Device class
261     struct classofdevcondition device_class;
262     /// BD address
263     struct bd_addr bdaddr;
264 };
265 
266 /// Event Filter Record
267 struct hci_evt_filter_tag
268 {
269     bool        in_use;
270     uint8_t     type;
271     uint8_t     condition;
272     uint8_t     auto_accept;
273     union cond  param;
274 };
275 #elif (BLE_HOST_PRESENT && !BLE_EMB_PRESENT)
276 /// HCI Environment context structure
277 struct hci_ble_acl_con_tag
278 {
279     /// Code
280     uint8_t code;
281 };
282 
283 #endif //(BT_EMB_PRESENT || (BLE_HOST_PRESENT && !BLE_EMB_PRESENT))
284 
285 /// HCI Environment context structure
286 struct hci_env_tag
287 {
288     /// Event mask
289     struct evt_mask evt_msk;
290 
291     /// Event mask page 2
292     struct evt_mask evt_msk_page_2;
293 
294     #if (BT_EMB_PRESENT)
295     /// Link association table for BT link-oriented messages routing
296     struct hci_bt_acl_con_tag bt_acl_con_tab[MAX_NB_ACTIVE_ACL];
297 
298     /// Event filters
299     struct hci_evt_filter_tag evt_filter[HCI_FILTER_NB];
300 
301     /**
302      * Current auto-accept command opcode, used to filter the associated CS event
303      * Note: assume that there would be 1 auto accept command at the same time
304      * Note: could be HCI_Accept_Con, HCI_Accept_sync_Con
305      */
306     uint16_t auto_accept_opcode;
307 
308     #if (MAX_NB_SYNC > 0)
309     /**
310      * Voice settings used when SCO connection is auto-accepted
311      */
312     uint16_t voice_settings;
313     #endif //(MAX_NB_SYNC > 0)
314 
315     /**
316      * Auto-reject flag, used to filter the complete event when a request has been auto-rejected
317      */
318     bool auto_reject;
319 
320     #elif (BLE_HOST_PRESENT && !BLE_EMB_PRESENT && (BLE_CENTRAL || BLE_PERIPHERAL))
321     /// Link association table for BLE link-oriented messages routing
322     struct hci_ble_acl_con_tag ble_acl_con_tab[BLE_CONNECTION_MAX];
323 
324     #endif //(BT_EMB_PRESENT || (BLE_HOST_PRESENT && !BLE_EMB_PRESENT))
325 };
326 
327 /*
328  * GLOBAL VARIABLE DECLARATIONS
329  ****************************************************************************************
330  */
331 
332 #if BLE_HOST_PRESENT
333 extern const uint8_t hl_task_type[];
334 #endif //BLE_HOST_PRESENT
335 
336 ///HCI environment context
337 extern struct hci_env_tag hci_env;
338 
339 
340 /*
341  * FUNCTION DECLARATIONS
342  ****************************************************************************************
343  */
344 
345 /**
346 ****************************************************************************************
347 * @brief Look for a command descriptor that could match with the specified opcode
348 *
349 * @param[in]  opcode   Command opcode
350 *
351 * @return     Pointer the command descriptor (NULL if not found)
352 *****************************************************************************************
353 */
354 const struct hci_cmd_desc_tag* hci_look_for_cmd_desc(uint16_t opcode);
355 
356 /**
357 ****************************************************************************************
358 * @brief Look for an event descriptor that could match with the specified event code
359 *
360 * @param[in]  code   event code
361 *
362 * @return     Pointer the event descriptor (NULL if not found)
363 *****************************************************************************************
364 */
365 const struct hci_evt_desc_tag* hci_look_for_evt_desc(uint8_t code);
366 
367 
368 /**
369 ****************************************************************************************
370 * @brief Look for an event descriptor that could match with the specified DBG subcode
371 *
372 * @param[in]  subcode   DBG event subcode
373 *
374 * @return     Pointer the event descriptor (NULL if not found)
375 *****************************************************************************************
376 */
377 const struct hci_evt_desc_tag* hci_look_for_dbg_evt_desc(uint8_t subcode);
378 
379 #if (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
380 /**
381 ****************************************************************************************
382 * @brief Look for an event descriptor that could match with the specified LE subcode
383 *
384 * @param[in]  subcode   LE event subcode
385 *
386 * @return     Pointer the event descriptor (NULL if not found)
387 *****************************************************************************************
388 */
389 const struct hci_evt_desc_tag* hci_look_for_le_evt_desc(uint8_t subcode);
390 
391 #endif //(BLE_EMB_PRESENT || BLE_HOST_PRESENT)
392 
393 #if (HCI_TL_SUPPORT)
394 /**
395  ****************************************************************************************
396  * @brief Initialize HIC TL part
397  *****************************************************************************************
398  */
399 void hci_tl_init(bool reset);
400 
401 /**
402  ****************************************************************************************
403  * @brief Send an HCI message over TL
404  *
405  * @param[in]   msg   Kernel message carrying the HCI message
406  *****************************************************************************************
407  */
408 void hci_tl_send(struct ke_msg *msg);
409 
410 /**
411  ****************************************************************************************
412  * @brief Pack parameters
413  *
414  * This function packs parameters according to a specific format. It takes care of the
415  * endianess, padding, required by the compiler.
416  *
417  * @param[inout]   inout       Data Buffer
418  * @param[inout]   inout_len   Input: buffer size / Output: size of packed data
419  * @param[in]      format      Parameters format
420  *
421  * @return  Status of the packing operation
422  *****************************************************************************************
423  */
424 enum HCI_PACK_STATUS hci_util_pack(uint8_t* inout, uint16_t* inout_len, const char* format);
425 
426 /**
427  ****************************************************************************************
428  * @brief Unpack parameters
429  *
430  * This function unpacks parameters according to a specific format. It takes care of the
431  * endianess, padding, required by the compiler.
432  *
433  * Note: the buffer provided must be large enough to contain the unpacked data.
434  *
435  * @param[out]    out         Unpacked parameters buffer
436  * @param[in]     in          Packed parameters buffer
437  * @param[inout]  out_len     Input: buffer size / Output: size of unpacked data
438  * @param[in]     in_len      Size of the packed data
439  * @param[in]     format      Parameters format
440  *
441  * @return  Status of the unpacking operation
442  *****************************************************************************************
443  */
444 enum HCI_PACK_STATUS hci_util_unpack(uint8_t* out, uint8_t* in, uint16_t* out_len, uint16_t in_len, const char* format);
445 #endif //(HCI_TL_SUPPORT)
446 
447 /**
448  ****************************************************************************************
449  * @brief Initialize Flow Control Structure
450  *
451  *****************************************************************************************
452  */
453 void hci_fc_init(void);
454 
455 /**
456  ****************************************************************************************
457  * @brief count ACL packets sent to Host
458  *
459  *****************************************************************************************
460  */
461 void hci_fc_acl_packet_sent(void);
462 
463 /**
464  ****************************************************************************************
465  * @brief count SCO packets sent to Host
466  *
467  *****************************************************************************************
468  */
469 void hci_fc_sync_packet_sent(void);
470 
471 /**
472  ****************************************************************************************
473  * @brief Calculate number of ACL packets slots available on Host side
474  *
475  * @return number of packets available
476  *****************************************************************************************
477  */
478 uint16_t hci_fc_check_host_available_nb_acl_packets(void);
479 
480 /**
481  ****************************************************************************************
482  * @brief Calculate number of SCO packets slots available on Host side
483  *
484  * @return number of packets available
485  *****************************************************************************************
486  */
487 uint16_t hci_fc_check_host_available_nb_sync_packets(void);
488 
489 
490 #endif //HCI_PRESENT
491 
492 /// @} HCI
493 
494 #endif // HCI_INT_H_
495