HW layer for the Nucleo board, it only work with old BLE_API
Dependents: Hello_BLE F446RE-BLE
Fork of X_NUCLEO_IDB0XA1 by
BlueNRG_HCI/hci/hci.c@70:d20d30f59b1c, 2015-06-08 (annotated)
- Committer:
- Silvio Lucio Oliva
- Date:
- Mon Jun 08 17:08:01 2015 +0200
- Revision:
- 70:d20d30f59b1c
- Child:
- 74:c4526f8284d5
Initial commit for mbed support
Signed-off-by: Silvio Lucio Oliva <silvio.oliva@st.com>
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Silvio Lucio Oliva |
70:d20d30f59b1c | 1 | /** |
Silvio Lucio Oliva |
70:d20d30f59b1c | 2 | ****************************************************************************** |
Silvio Lucio Oliva |
70:d20d30f59b1c | 3 | * @file hci.c |
Silvio Lucio Oliva |
70:d20d30f59b1c | 4 | * @author AMS/HESA Application Team |
Silvio Lucio Oliva |
70:d20d30f59b1c | 5 | * @brief Function for managing HCI interface. |
Silvio Lucio Oliva |
70:d20d30f59b1c | 6 | ****************************************************************************** |
Silvio Lucio Oliva |
70:d20d30f59b1c | 7 | * |
Silvio Lucio Oliva |
70:d20d30f59b1c | 8 | * |
Silvio Lucio Oliva |
70:d20d30f59b1c | 9 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS |
Silvio Lucio Oliva |
70:d20d30f59b1c | 10 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE |
Silvio Lucio Oliva |
70:d20d30f59b1c | 11 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY |
Silvio Lucio Oliva |
70:d20d30f59b1c | 12 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING |
Silvio Lucio Oliva |
70:d20d30f59b1c | 13 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE |
Silvio Lucio Oliva |
70:d20d30f59b1c | 14 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. |
Silvio Lucio Oliva |
70:d20d30f59b1c | 15 | * |
Silvio Lucio Oliva |
70:d20d30f59b1c | 16 | * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> |
Silvio Lucio Oliva |
70:d20d30f59b1c | 17 | */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 18 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 19 | #include "hal_types.h" |
Silvio Lucio Oliva |
70:d20d30f59b1c | 20 | #include "osal.h" |
Silvio Lucio Oliva |
70:d20d30f59b1c | 21 | #include "ble_status.h" |
Silvio Lucio Oliva |
70:d20d30f59b1c | 22 | #include "hal.h" |
Silvio Lucio Oliva |
70:d20d30f59b1c | 23 | #include "hci_const.h" |
Silvio Lucio Oliva |
70:d20d30f59b1c | 24 | #include "gp_timer.h" |
Silvio Lucio Oliva |
70:d20d30f59b1c | 25 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 26 | #include "stm32_bluenrg_ble.h" |
Silvio Lucio Oliva |
70:d20d30f59b1c | 27 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 28 | extern SPI_HandleTypeDef SpiHandle; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 29 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 30 | #if BLE_CONFIG_DBG_ENABLE |
Silvio Lucio Oliva |
70:d20d30f59b1c | 31 | #define PRINTF(...) printf(__VA_ARGS__) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 32 | #else |
Silvio Lucio Oliva |
70:d20d30f59b1c | 33 | #define PRINTF(...) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 34 | #endif |
Silvio Lucio Oliva |
70:d20d30f59b1c | 35 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 36 | #define HCI_LOG_ON 0 |
Silvio Lucio Oliva |
70:d20d30f59b1c | 37 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 38 | #define HCI_READ_PACKET_NUM_MAX (5) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 39 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 40 | #define MIN(a,b) ((a) < (b) )? (a) : (b) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 41 | #define MAX(a,b) ((a) > (b) )? (a) : (b) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 42 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 43 | tListNode hciReadPktPool; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 44 | tListNode hciReadPktRxQueue; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 45 | /* pool of hci read packets */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 46 | static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 47 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 48 | static volatile uint8_t readPacketListFull=FALSE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 49 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 50 | static volatile uint8_t hci_timer_id; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 51 | static volatile uint8_t hci_timeout; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 52 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 53 | void hci_timeout_callback(void) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 54 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 55 | hci_timeout = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 56 | return; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 57 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 58 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 59 | void HCI_Init(void) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 60 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 61 | uint8_t index; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 62 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 63 | /* Initialize list heads of ready and free hci data packet queues */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 64 | list_init_head (&hciReadPktPool); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 65 | list_init_head (&hciReadPktRxQueue); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 66 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 67 | /* Initialize the queue of free hci data packets */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 68 | for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 69 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 70 | list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 71 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 72 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 73 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 74 | #define HCI_PCK_TYPE_OFFSET 0 |
Silvio Lucio Oliva |
70:d20d30f59b1c | 75 | #define EVENT_PARAMETER_TOT_LEN_OFFSET 2 |
Silvio Lucio Oliva |
70:d20d30f59b1c | 76 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 77 | /** |
Silvio Lucio Oliva |
70:d20d30f59b1c | 78 | * Verify if HCI packet is correctly formatted.. |
Silvio Lucio Oliva |
70:d20d30f59b1c | 79 | * |
Silvio Lucio Oliva |
70:d20d30f59b1c | 80 | * @param[in] hciReadPacket The packet that is received from HCI interface. |
Silvio Lucio Oliva |
70:d20d30f59b1c | 81 | * @return 0 if HCI packet is as expected |
Silvio Lucio Oliva |
70:d20d30f59b1c | 82 | */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 83 | int HCI_verify(const tHciDataPacket * hciReadPacket) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 84 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 85 | const uint8_t *hci_pckt = hciReadPacket->dataBuff; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 86 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 87 | if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 88 | return 1; /* Incorrect type. */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 89 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 90 | if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 91 | return 2; /* Wrong length (packet truncated or too long). */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 92 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 93 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 94 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 95 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 96 | void HCI_Process(void) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 97 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 98 | uint8_t data_len; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 99 | uint8_t buffer[HCI_READ_PACKET_SIZE]; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 100 | tHciDataPacket * hciReadPacket = NULL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 101 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 102 | Disable_SPI_IRQ(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 103 | uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 104 | /* process any pending events read */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 105 | while(list_empty == FALSE) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 106 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 107 | list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 108 | Enable_SPI_IRQ(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 109 | HCI_Event_CB(hciReadPacket->dataBuff); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 110 | Disable_SPI_IRQ(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 111 | list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 112 | list_empty = list_is_empty(&hciReadPktRxQueue); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 113 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 114 | if (readPacketListFull) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 115 | while(BlueNRG_DataPresent()) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 116 | data_len = BlueNRG_SPI_Read_All(&SpiHandle, buffer, HCI_READ_PACKET_SIZE); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 117 | if(data_len > 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 118 | HCI_Event_CB(buffer); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 119 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 120 | readPacketListFull = FALSE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 121 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 122 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 123 | Enable_SPI_IRQ(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 124 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 125 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 126 | BOOL HCI_Queue_Empty(void) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 127 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 128 | return list_is_empty(&hciReadPktRxQueue); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 129 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 130 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 131 | void HCI_Isr(void) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 132 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 133 | tHciDataPacket * hciReadPacket = NULL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 134 | uint8_t data_len; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 135 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 136 | Clear_SPI_EXTI_Flag(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 137 | while(BlueNRG_DataPresent()){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 138 | if (list_is_empty (&hciReadPktPool) == FALSE){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 139 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 140 | /* enqueueing a packet for read */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 141 | list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 142 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 143 | data_len = BlueNRG_SPI_Read_All(&SpiHandle, hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 144 | if(data_len > 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 145 | hciReadPacket->data_len = data_len; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 146 | if(HCI_verify(hciReadPacket) == 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 147 | list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 148 | else |
Silvio Lucio Oliva |
70:d20d30f59b1c | 149 | list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 150 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 151 | else { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 152 | // Insert the packet back into the pool. |
Silvio Lucio Oliva |
70:d20d30f59b1c | 153 | list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 154 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 155 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 156 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 157 | else{ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 158 | // HCI Read Packet Pool is empty, wait for a free packet. |
Silvio Lucio Oliva |
70:d20d30f59b1c | 159 | readPacketListFull = TRUE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 160 | Clear_SPI_EXTI_Flag(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 161 | return; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 162 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 163 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 164 | Clear_SPI_EXTI_Flag(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 165 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 166 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 167 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 168 | void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 169 | #if HCI_LOG_ON |
Silvio Lucio Oliva |
70:d20d30f59b1c | 170 | PRINTF("HCI <- "); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 171 | for(int i=0; i < n_bytes1; i++) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 172 | PRINTF("%02X ", *((uint8_t*)data1 + i)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 173 | for(int i=0; i < n_bytes2; i++) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 174 | PRINTF("%02X ", *((uint8_t*)data2 + i)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 175 | PRINTF("\n"); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 176 | #endif |
Silvio Lucio Oliva |
70:d20d30f59b1c | 177 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 178 | Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 179 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 180 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 181 | void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 182 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 183 | hci_command_hdr hc; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 184 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 185 | hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 186 | hc.plen= plen; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 187 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 188 | uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 189 | header[0] = HCI_COMMAND_PKT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 190 | Osal_MemCpy(header+1, &hc, sizeof(hc)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 191 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 192 | hci_write(header, param, sizeof(header), plen); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 193 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 194 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 195 | static void move_list(tListNode * dest_list, tListNode * src_list) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 196 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 197 | pListNode tmp_node; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 198 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 199 | while(!list_is_empty(src_list)){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 200 | list_remove_head(src_list, &tmp_node); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 201 | list_insert_tail(dest_list, tmp_node); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 202 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 203 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 204 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 205 | int hci_send_req(struct hci_request *r, BOOL async) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 206 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 207 | uint8_t *ptr; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 208 | uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 209 | hci_event_pckt *event_pckt; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 210 | hci_uart_pckt *hci_hdr; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 211 | int to = DEFAULT_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 212 | struct timer t; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 213 | tHciDataPacket * hciReadPacket = NULL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 214 | tListNode hciTempQueue; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 215 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 216 | list_init_head(&hciTempQueue); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 217 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 218 | hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 219 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 220 | if(async){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 221 | goto done; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 222 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 223 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 224 | /* Minimum timeout is 1. */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 225 | if(to == 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 226 | to = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 227 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 228 | Timer_Set(&t, to); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 229 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 230 | while(1) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 231 | evt_cmd_complete *cc; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 232 | evt_cmd_status *cs; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 233 | evt_le_meta_event *me; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 234 | int len; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 235 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 236 | #if ENABLE_MICRO_SLEEP |
Silvio Lucio Oliva |
70:d20d30f59b1c | 237 | while(1){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 238 | ATOMIC_SECTION_BEGIN(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 239 | if(Timer_Expired(&t)){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 240 | ATOMIC_SECTION_END(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 241 | goto failed; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 242 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 243 | if(!HCI_Queue_Empty()){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 244 | ATOMIC_SECTION_END(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 245 | break; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 246 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 247 | Enter_Sleep_Mode(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 248 | ATOMIC_SECTION_END(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 249 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 250 | #else |
Silvio Lucio Oliva |
70:d20d30f59b1c | 251 | while(1){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 252 | if(Timer_Expired(&t)){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 253 | goto failed; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 254 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 255 | if(!HCI_Queue_Empty()){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 256 | break; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 257 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 258 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 259 | #endif |
Silvio Lucio Oliva |
70:d20d30f59b1c | 260 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 261 | /* Extract packet from HCI event queue. */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 262 | Disable_SPI_IRQ(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 263 | list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 264 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 265 | hci_hdr = (void *)hciReadPacket->dataBuff; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 266 | if(hci_hdr->type != HCI_EVENT_PKT){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 267 | list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); // See comment below |
Silvio Lucio Oliva |
70:d20d30f59b1c | 268 | Enable_SPI_IRQ(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 269 | continue; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 270 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 271 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 272 | event_pckt = (void *) (hci_hdr->data); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 273 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 274 | ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 275 | len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 276 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 277 | switch (event_pckt->evt) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 278 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 279 | case EVT_CMD_STATUS: |
Silvio Lucio Oliva |
70:d20d30f59b1c | 280 | cs = (void *) ptr; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 281 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 282 | if (cs->opcode != opcode) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 283 | goto failed; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 284 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 285 | if (r->event != EVT_CMD_STATUS) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 286 | if (cs->status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 287 | goto failed; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 288 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 289 | break; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 290 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 291 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 292 | r->rlen = MIN(len, r->rlen); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 293 | Osal_MemCpy(r->rparam, ptr, r->rlen); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 294 | goto done; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 295 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 296 | case EVT_CMD_COMPLETE: |
Silvio Lucio Oliva |
70:d20d30f59b1c | 297 | cc = (void *) ptr; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 298 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 299 | if (cc->opcode != opcode) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 300 | goto failed; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 301 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 302 | ptr += EVT_CMD_COMPLETE_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 303 | len -= EVT_CMD_COMPLETE_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 304 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 305 | r->rlen = MIN(len, r->rlen); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 306 | Osal_MemCpy(r->rparam, ptr, r->rlen); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 307 | goto done; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 308 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 309 | case EVT_LE_META_EVENT: |
Silvio Lucio Oliva |
70:d20d30f59b1c | 310 | me = (void *) ptr; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 311 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 312 | if (me->subevent != r->event) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 313 | break; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 314 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 315 | len -= 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 316 | r->rlen = MIN(len, r->rlen); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 317 | Osal_MemCpy(r->rparam, me->data, r->rlen); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 318 | goto done; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 319 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 320 | case EVT_HARDWARE_ERROR: |
Silvio Lucio Oliva |
70:d20d30f59b1c | 321 | goto failed; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 322 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 323 | default: |
Silvio Lucio Oliva |
70:d20d30f59b1c | 324 | break; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 325 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 326 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 327 | /* In the meantime there could be other events from the controller. |
Silvio Lucio Oliva |
70:d20d30f59b1c | 328 | In this case, insert the packet in a different queue. These packets will be |
Silvio Lucio Oliva |
70:d20d30f59b1c | 329 | inserted back in the main queue just before exiting from send_req(). |
Silvio Lucio Oliva |
70:d20d30f59b1c | 330 | */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 331 | list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 332 | /* Be sure there is at list one packet in the pool to process the expected event. */ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 333 | if(list_is_empty(&hciReadPktPool)){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 334 | pListNode tmp_node; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 335 | list_remove_head(&hciReadPktRxQueue, &tmp_node); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 336 | list_insert_tail(&hciReadPktPool, tmp_node); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 337 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 338 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 339 | Enable_SPI_IRQ(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 340 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 341 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 342 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 343 | failed: |
Silvio Lucio Oliva |
70:d20d30f59b1c | 344 | move_list(&hciReadPktRxQueue, &hciTempQueue); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 345 | Enable_SPI_IRQ(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 346 | return -1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 347 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 348 | done: |
Silvio Lucio Oliva |
70:d20d30f59b1c | 349 | // Insert the packet back into the pool. |
Silvio Lucio Oliva |
70:d20d30f59b1c | 350 | list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 351 | move_list(&hciReadPktRxQueue, &hciTempQueue); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 352 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 353 | Enable_SPI_IRQ(); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 354 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 355 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 356 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 357 | int hci_reset() |
Silvio Lucio Oliva |
70:d20d30f59b1c | 358 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 359 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 360 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 361 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 362 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 363 | rq.ogf = OGF_HOST_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 364 | rq.ocf = OCF_RESET; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 365 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 366 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 367 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 368 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 369 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 370 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 371 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 372 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 373 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 374 | int hci_disconnect(uint16_t handle, uint8_t reason) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 375 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 376 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 377 | disconnect_cp cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 378 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 379 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 380 | cp.handle = handle; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 381 | cp.reason = reason; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 382 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 383 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 384 | rq.ogf = OGF_LINK_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 385 | rq.ocf = OCF_DISCONNECT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 386 | rq.cparam = &cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 387 | rq.clen = DISCONNECT_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 388 | rq.event = EVT_CMD_STATUS; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 389 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 390 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 391 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 392 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 393 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 394 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 395 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 396 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 397 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 398 | int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, |
Silvio Lucio Oliva |
70:d20d30f59b1c | 399 | uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 400 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 401 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 402 | read_local_version_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 403 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 404 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 405 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 406 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 407 | rq.ogf = OGF_INFO_PARAM; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 408 | rq.ocf = OCF_READ_LOCAL_VERSION; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 409 | rq.cparam = NULL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 410 | rq.clen = 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 411 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 412 | rq.rlen = READ_LOCAL_VERSION_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 413 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 414 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 415 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 416 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 417 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 418 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 419 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 420 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 421 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 422 | *hci_version = resp.hci_version; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 423 | *hci_revision = btohs(resp.hci_revision); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 424 | *lmp_pal_version = resp.lmp_pal_version; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 425 | *manufacturer_name = btohs(resp.manufacturer_name); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 426 | *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 427 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 428 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 429 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 430 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 431 | int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 432 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 433 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 434 | le_read_buffer_size_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 435 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 436 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 437 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 438 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 439 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 440 | rq.ocf = OCF_LE_READ_BUFFER_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 441 | rq.cparam = NULL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 442 | rq.clen = 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 443 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 444 | rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 445 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 446 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 447 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 448 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 449 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 450 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 451 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 452 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 453 | *pkt_len = resp.pkt_len; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 454 | *max_pkt = resp.max_pkt; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 455 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 456 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 457 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 458 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 459 | int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, |
Silvio Lucio Oliva |
70:d20d30f59b1c | 460 | uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, |
Silvio Lucio Oliva |
70:d20d30f59b1c | 461 | uint8_t filter) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 462 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 463 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 464 | le_set_adv_parameters_cp adv_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 465 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 466 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 467 | Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 468 | adv_cp.min_interval = min_interval; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 469 | adv_cp.max_interval = max_interval; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 470 | adv_cp.advtype = advtype; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 471 | adv_cp.own_bdaddr_type = own_bdaddr_type; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 472 | adv_cp.direct_bdaddr_type = direct_bdaddr_type; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 473 | Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 474 | adv_cp.chan_map = chan_map; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 475 | adv_cp.filter = filter; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 476 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 477 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 478 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 479 | rq.ocf = OCF_LE_SET_ADV_PARAMETERS; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 480 | rq.cparam = &adv_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 481 | rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 482 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 483 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 484 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 485 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 486 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 487 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 488 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 489 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 490 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 491 | int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 492 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 493 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 494 | le_set_adv_data_cp adv_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 495 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 496 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 497 | Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 498 | adv_cp.length = length; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 499 | Osal_MemCpy(adv_cp.data, data, MIN(31,length)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 500 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 501 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 502 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 503 | rq.ocf = OCF_LE_SET_ADV_DATA; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 504 | rq.cparam = &adv_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 505 | rq.clen = LE_SET_ADV_DATA_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 506 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 507 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 508 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 509 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 510 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 511 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 512 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 513 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 514 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 515 | int hci_le_set_advertise_enable(uint8_t enable) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 516 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 517 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 518 | le_set_advertise_enable_cp adv_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 519 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 520 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 521 | Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 522 | adv_cp.enable = enable?1:0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 523 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 524 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 525 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 526 | rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 527 | rq.cparam = &adv_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 528 | rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 529 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 530 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 531 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 532 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 533 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 534 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 535 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 536 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 537 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 538 | int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, |
Silvio Lucio Oliva |
70:d20d30f59b1c | 539 | uint16_t window, uint8_t own_bdaddr_type, |
Silvio Lucio Oliva |
70:d20d30f59b1c | 540 | uint8_t filter) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 541 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 542 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 543 | le_set_scan_parameters_cp scan_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 544 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 545 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 546 | Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 547 | scan_cp.type = type; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 548 | scan_cp.interval = interval; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 549 | scan_cp.window = window; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 550 | scan_cp.own_bdaddr_type = own_bdaddr_type; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 551 | scan_cp.filter = filter; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 552 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 553 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 554 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 555 | rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 556 | rq.cparam = &scan_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 557 | rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 558 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 559 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 560 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 561 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 562 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 563 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 564 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 565 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 566 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 567 | int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 568 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 569 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 570 | le_set_scan_enable_cp scan_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 571 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 572 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 573 | Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 574 | scan_cp.enable = enable?1:0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 575 | scan_cp.filter_dup = filter_dup; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 576 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 577 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 578 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 579 | rq.ocf = OCF_LE_SET_SCAN_ENABLE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 580 | rq.cparam = &scan_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 581 | rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 582 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 583 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 584 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 585 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 586 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 587 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 588 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 589 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 590 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 591 | int hci_le_rand(uint8_t random_number[8]) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 592 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 593 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 594 | le_rand_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 595 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 596 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 597 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 598 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 599 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 600 | rq.ocf = OCF_LE_RAND; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 601 | rq.cparam = NULL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 602 | rq.clen = 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 603 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 604 | rq.rlen = LE_RAND_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 605 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 606 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 607 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 608 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 609 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 610 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 611 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 612 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 613 | Osal_MemCpy(random_number, resp.random, 8); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 614 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 615 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 616 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 617 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 618 | int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 619 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 620 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 621 | le_set_scan_response_data_cp scan_resp_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 622 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 623 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 624 | Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 625 | scan_resp_cp.length = length; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 626 | Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 627 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 628 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 629 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 630 | rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 631 | rq.cparam = &scan_resp_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 632 | rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 633 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 634 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 635 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 636 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 637 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 638 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 639 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 640 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 641 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 642 | int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 643 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 644 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 645 | le_read_adv_channel_tx_power_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 646 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 647 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 648 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 649 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 650 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 651 | rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 652 | rq.cparam = NULL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 653 | rq.clen = 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 654 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 655 | rq.rlen = LE_RAND_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 656 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 657 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 658 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 659 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 660 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 661 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 662 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 663 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 664 | *tx_power_level = resp.level; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 665 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 666 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 667 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 668 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 669 | int hci_le_set_random_address(tBDAddr bdaddr) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 670 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 671 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 672 | le_set_random_address_cp set_rand_addr_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 673 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 674 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 675 | Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 676 | Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 677 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 678 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 679 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 680 | rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 681 | rq.cparam = &set_rand_addr_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 682 | rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 683 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 684 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 685 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 686 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 687 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 688 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 689 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 690 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 691 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 692 | int hci_read_bd_addr(tBDAddr bdaddr) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 693 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 694 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 695 | read_bd_addr_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 696 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 697 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 698 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 699 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 700 | rq.ogf = OGF_INFO_PARAM; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 701 | rq.ocf = OCF_READ_BD_ADDR; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 702 | rq.cparam = NULL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 703 | rq.clen = 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 704 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 705 | rq.rlen = READ_BD_ADDR_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 706 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 707 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 708 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 709 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 710 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 711 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 712 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 713 | Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 714 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 715 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 716 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 717 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 718 | int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, |
Silvio Lucio Oliva |
70:d20d30f59b1c | 719 | const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, |
Silvio Lucio Oliva |
70:d20d30f59b1c | 720 | uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 721 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 722 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 723 | le_create_connection_cp create_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 724 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 725 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 726 | Osal_MemSet(&create_cp, 0, sizeof(create_cp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 727 | create_cp.interval = interval; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 728 | create_cp.window = window; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 729 | create_cp.initiator_filter = initiator_filter; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 730 | create_cp.peer_bdaddr_type = peer_bdaddr_type; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 731 | Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 732 | create_cp.own_bdaddr_type = own_bdaddr_type; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 733 | create_cp.min_interval=min_interval; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 734 | create_cp.max_interval=max_interval; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 735 | create_cp.latency = latency; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 736 | create_cp.supervision_timeout=supervision_timeout; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 737 | create_cp.min_ce_length=min_ce_length; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 738 | create_cp.max_ce_length=max_ce_length; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 739 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 740 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 741 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 742 | rq.ocf = OCF_LE_CREATE_CONN; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 743 | rq.cparam = &create_cp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 744 | rq.clen = LE_CREATE_CONN_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 745 | rq.event = EVT_CMD_STATUS; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 746 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 747 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 748 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 749 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 750 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 751 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 752 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 753 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 754 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 755 | int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 756 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 757 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 758 | le_encrypt_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 759 | le_encrypt_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 760 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 761 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 762 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 763 | Osal_MemCpy(params.key, key, 16); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 764 | Osal_MemCpy(params.plaintext, plaintextData, 16); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 765 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 766 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 767 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 768 | rq.ocf = OCF_LE_ENCRYPT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 769 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 770 | rq.clen = LE_ENCRYPT_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 771 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 772 | rq.rlen = LE_ENCRYPT_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 773 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 774 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 775 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 776 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 777 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 778 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 779 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 780 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 781 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 782 | Osal_MemCpy(encryptedData, resp.encdata, 16); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 783 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 784 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 785 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 786 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 787 | int hci_le_ltk_request_reply(uint8_t key[16]) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 788 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 789 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 790 | le_ltk_reply_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 791 | le_ltk_reply_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 792 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 793 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 794 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 795 | params.handle = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 796 | Osal_MemCpy(params.key, key, 16); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 797 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 798 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 799 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 800 | rq.ocf = OCF_LE_LTK_REPLY; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 801 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 802 | rq.clen = LE_LTK_REPLY_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 803 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 804 | rq.rlen = LE_LTK_REPLY_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 805 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 806 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 807 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 808 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 809 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 810 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 811 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 812 | int hci_le_ltk_request_neg_reply() |
Silvio Lucio Oliva |
70:d20d30f59b1c | 813 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 814 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 815 | le_ltk_neg_reply_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 816 | le_ltk_neg_reply_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 817 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 818 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 819 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 820 | params.handle = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 821 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 822 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 823 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 824 | rq.ocf = OCF_LE_LTK_NEG_REPLY; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 825 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 826 | rq.clen = LE_LTK_NEG_REPLY_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 827 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 828 | rq.rlen = LE_LTK_NEG_REPLY_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 829 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 830 | if (hci_send_req(&rq, FALSE) < 0) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 831 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 832 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 833 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 834 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 835 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 836 | int hci_le_read_white_list_size(uint8_t *size) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 837 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 838 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 839 | le_read_white_list_size_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 840 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 841 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 842 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 843 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 844 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 845 | rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 846 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 847 | rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 848 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 849 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 850 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 851 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 852 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 853 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 854 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 855 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 856 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 857 | *size = resp.size; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 858 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 859 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 860 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 861 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 862 | int hci_le_clear_white_list() |
Silvio Lucio Oliva |
70:d20d30f59b1c | 863 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 864 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 865 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 866 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 867 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 868 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 869 | rq.ocf = OCF_LE_CLEAR_WHITE_LIST; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 870 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 871 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 872 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 873 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 874 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 875 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 876 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 877 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 878 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 879 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 880 | int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 881 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 882 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 883 | le_add_device_to_white_list_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 884 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 885 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 886 | params.bdaddr_type = bdaddr_type; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 887 | Osal_MemCpy(params.bdaddr, bdaddr, 6); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 888 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 889 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 890 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 891 | rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 892 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 893 | rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 894 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 895 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 896 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 897 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 898 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 899 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 900 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 901 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 902 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 903 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 904 | int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 905 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 906 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 907 | le_remove_device_from_white_list_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 908 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 909 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 910 | params.bdaddr_type = bdaddr_type; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 911 | Osal_MemCpy(params.bdaddr, bdaddr, 6); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 912 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 913 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 914 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 915 | rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 916 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 917 | rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 918 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 919 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 920 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 921 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 922 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 923 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 924 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 925 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 926 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 927 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 928 | int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 929 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 930 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 931 | read_transmit_power_level_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 932 | read_transmit_power_level_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 933 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 934 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 935 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 936 | params.handle = *conn_handle; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 937 | params.type = type; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 938 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 939 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 940 | rq.ogf = OGF_HOST_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 941 | rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 942 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 943 | rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 944 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 945 | rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 946 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 947 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 948 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 949 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 950 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 951 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 952 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 953 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 954 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 955 | *conn_handle = resp.handle; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 956 | *tx_level = resp.level; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 957 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 958 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 959 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 960 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 961 | int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 962 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 963 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 964 | read_rssi_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 965 | read_rssi_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 966 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 967 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 968 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 969 | params.handle = *conn_handle; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 970 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 971 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 972 | rq.ogf = OGF_STATUS_PARAM; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 973 | rq.ocf = OCF_READ_RSSI; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 974 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 975 | rq.clen = READ_RSSI_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 976 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 977 | rq.rlen = READ_RSSI_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 978 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 979 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 980 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 981 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 982 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 983 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 984 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 985 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 986 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 987 | *conn_handle = resp.handle; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 988 | *rssi = resp.rssi; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 989 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 990 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 991 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 992 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 993 | int hci_le_read_local_supported_features(uint8_t *features) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 994 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 995 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 996 | le_read_local_supported_features_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 997 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 998 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 999 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1000 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1001 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1002 | rq.ocf = OCF_LE_READ_LOCAL_SUPPORTED_FEATURES; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1003 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1004 | rq.rlen = LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1005 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1006 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1007 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1008 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1009 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1010 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1011 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1012 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1013 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1014 | Osal_MemCpy(features, resp.features, sizeof(resp.features)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1015 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1016 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1017 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1018 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1019 | int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1020 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1021 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1022 | le_read_channel_map_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1023 | le_read_channel_map_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1024 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1025 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1026 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1027 | params.handle = conn_handle; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1028 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1029 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1030 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1031 | rq.ocf = OCF_LE_READ_CHANNEL_MAP; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1032 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1033 | rq.clen = LE_READ_CHANNEL_MAP_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1034 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1035 | rq.rlen = LE_READ_CHANNEL_MAP_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1036 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1037 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1038 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1039 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1040 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1041 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1042 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1043 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1044 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1045 | Osal_MemCpy(ch_map, resp.map, 5); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1046 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1047 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1048 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1049 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1050 | int hci_le_read_supported_states(uint8_t states[8]) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1051 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1052 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1053 | le_read_supported_states_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1054 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1055 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1056 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1057 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1058 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1059 | rq.ocf = OCF_LE_READ_SUPPORTED_STATES; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1060 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1061 | rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1062 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1063 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1064 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1065 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1066 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1067 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1068 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1069 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1070 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1071 | Osal_MemCpy(states, resp.states, 8); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1072 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1073 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1074 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1075 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1076 | int hci_le_receiver_test(uint8_t frequency) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1077 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1078 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1079 | le_receiver_test_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1080 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1081 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1082 | params.frequency = frequency; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1083 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1084 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1085 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1086 | rq.ocf = OCF_LE_RECEIVER_TEST; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1087 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1088 | rq.clen = LE_RECEIVER_TEST_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1089 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1090 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1091 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1092 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1093 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1094 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1095 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1096 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1097 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1098 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1099 | int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1100 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1101 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1102 | le_transmitter_test_cp params; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1103 | uint8_t status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1104 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1105 | params.frequency = frequency; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1106 | params.length = length; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1107 | params.payload = payload; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1108 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1109 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1110 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1111 | rq.ocf = OCF_LE_TRANSMITTER_TEST; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1112 | rq.cparam = ¶ms; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1113 | rq.clen = LE_TRANSMITTER_TEST_CP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1114 | rq.rparam = &status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1115 | rq.rlen = 1; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1116 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1117 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1118 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1119 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1120 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1121 | return status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1122 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1123 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1124 | int hci_le_test_end(uint16_t *num_pkts) |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1125 | { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1126 | struct hci_request rq; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1127 | le_test_end_rp resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1128 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1129 | Osal_MemSet(&resp, 0, sizeof(resp)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1130 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1131 | Osal_MemSet(&rq, 0, sizeof(rq)); |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1132 | rq.ogf = OGF_LE_CTL; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1133 | rq.ocf = OCF_LE_TEST_END; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1134 | rq.rparam = &resp; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1135 | rq.rlen = LE_TEST_END_RP_SIZE; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1136 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1137 | if (hci_send_req(&rq, FALSE) < 0){ |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1138 | return BLE_STATUS_TIMEOUT; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1139 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1140 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1141 | if (resp.status) { |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1142 | return resp.status; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1143 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1144 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1145 | *num_pkts = resp.num_pkts; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1146 | |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1147 | return 0; |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1148 | } |
Silvio Lucio Oliva |
70:d20d30f59b1c | 1149 |