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:
mridup
Date:
Wed Jul 16 04:59:51 2014 +0000
Revision:
0:309c845d289d
Full BlueNRG library

Who changed what in which revision?

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