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