NUCLEO-F401RE + BlueNRG shield client test (TI Sensortag reading)

Dependencies:   mbed-src

Committer:
ostapsky
Date:
Sat Aug 16 11:00:04 2014 +0000
Revision:
0:aa1e012ec210
CLIENT mode first revision

Who changed what in which revision?

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