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:
Wolfgang Betz
Date:
Thu Jul 23 09:44:24 2015 +0200
Revision:
91:97c0c21046b4
Parent:
90:26c0c9807ab4
Child:
95:e1f7ce04e71b
Improve waitForEvent()

- Enable also debug messages on console

Who changed what in which revision?

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