DIVYA REHANI / X_NUCLEO_IDB0XA1

Dependencies:   mbed-os-example-ble-Advertising

Committer:
Wolfgang Betz
Date:
Tue Oct 06 15:19:19 2015 +0200
Revision:
131:e09947216ccb
Parent:
130:770ce14d3d15
Get a first compilation thru

Who changed what in which revision?

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