HW layer for the Nucleo board, it only work with old BLE_API

Dependents:   Hello_BLE F446RE-BLE

Fork of X_NUCLEO_IDB0XA1 by ST

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?

UserRevisionLine numberNew 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>&copy; 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 = &params;
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 = &params;
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 = &params;
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 = &params;
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 = &params;
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 = &params;
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 = &params;
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 = &params;
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 = &params;
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 = &params;
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