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:
Tue Aug 11 11:36:13 2015 +0200
Revision:
105:332f93cd06b7
Parent:
103:12684d94c3a6
Merge branch 'master' of hg::http://wobetz@developer.mbed.org/teams/ST-Expansion-SW-Team/code/X_NUCLEO_IDB0XA1 into idb0xa1-split

Conflicts:
BlueNRGGap.cpp
BlueNRGGattServer.cpp
BlueNRGGattServer.h
platform/src/btle.cpp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wolfgang Betz 90:26c0c9807ab4 1 /**
Wolfgang Betz 90:26c0c9807ab4 2 ******************************************************************************
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 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 105:332f93cd06b7 53 hci_timeout = 1;
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 59 uint8_t index;
Wolfgang Betz 105:332f93cd06b7 60
Wolfgang Betz 105:332f93cd06b7 61 /* Initialize list heads of ready and free hci data packet queues */
Wolfgang Betz 105:332f93cd06b7 62 list_init_head (&hciReadPktPool);
Wolfgang Betz 105:332f93cd06b7 63 list_init_head (&hciReadPktRxQueue);
Wolfgang Betz 105:332f93cd06b7 64
Wolfgang Betz 105:332f93cd06b7 65 /* Initialize the queue of free hci data packets */
Wolfgang Betz 105:332f93cd06b7 66 for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++)
Wolfgang Betz 105:332f93cd06b7 67 {
Wolfgang Betz 105:332f93cd06b7 68 list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]);
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 83 const uint8_t *hci_pckt = hciReadPacket->dataBuff;
Wolfgang Betz 105:332f93cd06b7 84
Wolfgang Betz 105:332f93cd06b7 85 if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT)
Wolfgang Betz 105:332f93cd06b7 86 return 1; /* Incorrect type. */
Wolfgang Betz 105:332f93cd06b7 87
Wolfgang Betz 105:332f93cd06b7 88 if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE))
Wolfgang Betz 105:332f93cd06b7 89 return 2; /* Wrong length (packet truncated or too long). */
Wolfgang Betz 105:332f93cd06b7 90
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 96 uint8_t data_len;
Wolfgang Betz 105:332f93cd06b7 97 uint8_t buffer[HCI_READ_PACKET_SIZE];
Wolfgang Betz 105:332f93cd06b7 98 tHciDataPacket * hciReadPacket = NULL;
Wolfgang Betz 105:332f93cd06b7 99
Wolfgang Betz 105:332f93cd06b7 100 Disable_SPI_IRQ();
Wolfgang Betz 105:332f93cd06b7 101 uint8_t list_empty = list_is_empty(&hciReadPktRxQueue);
Wolfgang Betz 105:332f93cd06b7 102 /* process any pending events read */
Wolfgang Betz 105:332f93cd06b7 103 while(list_empty == FALSE)
Wolfgang Betz 105:332f93cd06b7 104 {
Wolfgang Betz 105:332f93cd06b7 105 list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
Wolfgang Betz 105:332f93cd06b7 106 Enable_SPI_IRQ();
Wolfgang Betz 105:332f93cd06b7 107 HCI_Event_CB(hciReadPacket->dataBuff);
Wolfgang Betz 90:26c0c9807ab4 108 Disable_SPI_IRQ();
Wolfgang Betz 105:332f93cd06b7 109 list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
Wolfgang Betz 105:332f93cd06b7 110 list_empty = list_is_empty(&hciReadPktRxQueue);
Wolfgang Betz 105:332f93cd06b7 111 }
Wolfgang Betz 105:332f93cd06b7 112 if (readPacketListFull) {
Wolfgang Betz 105:332f93cd06b7 113 while(BlueNRG_DataPresent()) {
Wolfgang Betz 105:332f93cd06b7 114 data_len = BlueNRG_SPI_Read_All(buffer, HCI_READ_PACKET_SIZE);
Wolfgang Betz 105:332f93cd06b7 115 if(data_len > 0)
Wolfgang Betz 105:332f93cd06b7 116 HCI_Event_CB(buffer);
Wolfgang Betz 90:26c0c9807ab4 117 }
Wolfgang Betz 105:332f93cd06b7 118 readPacketListFull = FALSE;
Wolfgang Betz 105:332f93cd06b7 119 }
Wolfgang Betz 105:332f93cd06b7 120
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 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 105:332f93cd06b7 131 tHciDataPacket * hciReadPacket = NULL;
Wolfgang Betz 105:332f93cd06b7 132 uint8_t data_len;
Wolfgang Betz 105:332f93cd06b7 133
Wolfgang Betz 105:332f93cd06b7 134 Clear_SPI_EXTI_Flag();
Wolfgang Betz 105:332f93cd06b7 135 while(BlueNRG_DataPresent()){
Wolfgang Betz 105:332f93cd06b7 136 if (list_is_empty (&hciReadPktPool) == FALSE){
Wolfgang Betz 105:332f93cd06b7 137
Wolfgang Betz 105:332f93cd06b7 138 /* enqueueing a packet for read */
Wolfgang Betz 105:332f93cd06b7 139 list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket);
Wolfgang Betz 105:332f93cd06b7 140
Wolfgang Betz 105:332f93cd06b7 141 data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE);
Wolfgang Betz 105:332f93cd06b7 142 if(data_len > 0){
Wolfgang Betz 105:332f93cd06b7 143 hciReadPacket->data_len = data_len;
Wolfgang Betz 105:332f93cd06b7 144 if(HCI_verify(hciReadPacket) == 0)
Wolfgang Betz 105:332f93cd06b7 145 list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket);
Wolfgang Betz 105:332f93cd06b7 146 else
Wolfgang Betz 105:332f93cd06b7 147 list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
Wolfgang Betz 105:332f93cd06b7 148 }
Wolfgang Betz 105:332f93cd06b7 149 else {
Wolfgang Betz 105:332f93cd06b7 150 // Insert the packet back into the pool.
Wolfgang Betz 105:332f93cd06b7 151 list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
Wolfgang Betz 105:332f93cd06b7 152 }
Wolfgang Betz 105:332f93cd06b7 153
Wolfgang Betz 105:332f93cd06b7 154 }
Wolfgang Betz 105:332f93cd06b7 155 else{
Wolfgang Betz 105:332f93cd06b7 156 // HCI Read Packet Pool is empty, wait for a free packet.
Wolfgang Betz 105:332f93cd06b7 157 readPacketListFull = TRUE;
Wolfgang Betz 105:332f93cd06b7 158 Clear_SPI_EXTI_Flag();
Wolfgang Betz 105:332f93cd06b7 159 return;
Wolfgang Betz 105:332f93cd06b7 160 }
Wolfgang Betz 105:332f93cd06b7 161
Wolfgang Betz 103:12684d94c3a6 162 Clear_SPI_EXTI_Flag();
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 168 PRINTF("HCI <- ");
Wolfgang Betz 105:332f93cd06b7 169 for(int i=0; i < n_bytes1; i++)
Wolfgang Betz 105:332f93cd06b7 170 PRINTF("%02X ", *((uint8_t*)data1 + i));
Wolfgang Betz 105:332f93cd06b7 171 for(int i=0; i < n_bytes2; i++)
Wolfgang Betz 105:332f93cd06b7 172 PRINTF("%02X ", *((uint8_t*)data2 + i));
Wolfgang Betz 105:332f93cd06b7 173 PRINTF("\n");
Wolfgang Betz 90:26c0c9807ab4 174 #endif
Wolfgang Betz 105:332f93cd06b7 175
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 181 hci_command_hdr hc;
Wolfgang Betz 105:332f93cd06b7 182
Wolfgang Betz 105:332f93cd06b7 183 hc.opcode = htobs(cmd_opcode_pack(ogf, ocf));
Wolfgang Betz 105:332f93cd06b7 184 hc.plen= plen;
Wolfgang Betz 105:332f93cd06b7 185
Wolfgang Betz 105:332f93cd06b7 186 uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE];
Wolfgang Betz 105:332f93cd06b7 187 header[0] = HCI_COMMAND_PKT;
Wolfgang Betz 105:332f93cd06b7 188 Osal_MemCpy(header+1, &hc, sizeof(hc));
Wolfgang Betz 105:332f93cd06b7 189
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 195 pListNode tmp_node;
Wolfgang Betz 105:332f93cd06b7 196
Wolfgang Betz 105:332f93cd06b7 197 while(!list_is_empty(src_list)){
Wolfgang Betz 105:332f93cd06b7 198 list_remove_head(src_list, &tmp_node);
Wolfgang Betz 105:332f93cd06b7 199 list_insert_tail(dest_list, tmp_node);
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 205 uint8_t *ptr;
Wolfgang Betz 105:332f93cd06b7 206 uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf));
Wolfgang Betz 105:332f93cd06b7 207 hci_event_pckt *event_pckt;
Wolfgang Betz 105:332f93cd06b7 208 hci_uart_pckt *hci_hdr;
Wolfgang Betz 105:332f93cd06b7 209 int to = DEFAULT_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 210 struct timer t;
Wolfgang Betz 105:332f93cd06b7 211 tHciDataPacket * hciReadPacket = NULL;
Wolfgang Betz 105:332f93cd06b7 212 tListNode hciTempQueue;
Wolfgang Betz 105:332f93cd06b7 213
Wolfgang Betz 105:332f93cd06b7 214 list_init_head(&hciTempQueue);
Wolfgang Betz 105:332f93cd06b7 215
Wolfgang Betz 105:332f93cd06b7 216 hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam);
Wolfgang Betz 105:332f93cd06b7 217
Wolfgang Betz 105:332f93cd06b7 218 if(async){
Wolfgang Betz 105:332f93cd06b7 219 goto done;
Wolfgang Betz 105:332f93cd06b7 220 }
Wolfgang Betz 105:332f93cd06b7 221
Wolfgang Betz 105:332f93cd06b7 222 /* Minimum timeout is 1. */
Wolfgang Betz 105:332f93cd06b7 223 if(to == 0)
Wolfgang Betz 105:332f93cd06b7 224 to = 1;
Wolfgang Betz 105:332f93cd06b7 225
Wolfgang Betz 105:332f93cd06b7 226 Timer_Set(&t, to);
Wolfgang Betz 105:332f93cd06b7 227
Wolfgang Betz 105:332f93cd06b7 228 while(1) {
Wolfgang Betz 105:332f93cd06b7 229 evt_cmd_complete *cc;
Wolfgang Betz 105:332f93cd06b7 230 evt_cmd_status *cs;
Wolfgang Betz 105:332f93cd06b7 231 evt_le_meta_event *me;
Wolfgang Betz 105:332f93cd06b7 232 int len;
Wolfgang Betz 105:332f93cd06b7 233
Wolfgang Betz 105:332f93cd06b7 234 #if ENABLE_MICRO_SLEEP
Wolfgang Betz 105:332f93cd06b7 235 while(1){
Wolfgang Betz 105:332f93cd06b7 236 ATOMIC_SECTION_BEGIN();
Wolfgang Betz 105:332f93cd06b7 237 if(Timer_Expired(&t)){
Wolfgang Betz 105:332f93cd06b7 238 ATOMIC_SECTION_END();
Wolfgang Betz 105:332f93cd06b7 239 goto failed;
Wolfgang Betz 105:332f93cd06b7 240 }
Wolfgang Betz 105:332f93cd06b7 241 if(!HCI_Queue_Empty()){
Wolfgang Betz 105:332f93cd06b7 242 ATOMIC_SECTION_END();
Wolfgang Betz 105:332f93cd06b7 243 break;
Wolfgang Betz 105:332f93cd06b7 244 }
Wolfgang Betz 105:332f93cd06b7 245 Enter_Sleep_Mode();
Wolfgang Betz 105:332f93cd06b7 246 ATOMIC_SECTION_END();
Wolfgang Betz 103:12684d94c3a6 247 }
Wolfgang Betz 90:26c0c9807ab4 248 #else
Wolfgang Betz 105:332f93cd06b7 249 while(1){
Wolfgang Betz 105:332f93cd06b7 250 if(Timer_Expired(&t)){
Wolfgang Betz 105:332f93cd06b7 251 goto failed;
Wolfgang Betz 105:332f93cd06b7 252 }
Wolfgang Betz 105:332f93cd06b7 253 if(!HCI_Queue_Empty()){
Wolfgang Betz 105:332f93cd06b7 254 break;
Wolfgang Betz 105:332f93cd06b7 255 }
Wolfgang Betz 105:332f93cd06b7 256 }
Wolfgang Betz 90:26c0c9807ab4 257 #endif
Wolfgang Betz 105:332f93cd06b7 258
Wolfgang Betz 105:332f93cd06b7 259 /* Extract packet from HCI event queue. */
Wolfgang Betz 105:332f93cd06b7 260 Disable_SPI_IRQ();
Wolfgang Betz 105:332f93cd06b7 261 list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
Wolfgang Betz 105:332f93cd06b7 262
Wolfgang Betz 105:332f93cd06b7 263 hci_hdr = (void *)hciReadPacket->dataBuff;
Wolfgang Betz 105:332f93cd06b7 264 if(hci_hdr->type != HCI_EVENT_PKT){
Wolfgang Betz 105:332f93cd06b7 265 list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); // See comment below
Wolfgang Betz 105:332f93cd06b7 266 Enable_SPI_IRQ();
Wolfgang Betz 105:332f93cd06b7 267 continue;
Wolfgang Betz 105:332f93cd06b7 268 }
Wolfgang Betz 105:332f93cd06b7 269
Wolfgang Betz 105:332f93cd06b7 270 event_pckt = (void *) (hci_hdr->data);
Wolfgang Betz 105:332f93cd06b7 271
Wolfgang Betz 105:332f93cd06b7 272 ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE);
Wolfgang Betz 105:332f93cd06b7 273 len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE);
Wolfgang Betz 105:332f93cd06b7 274
Wolfgang Betz 105:332f93cd06b7 275 switch (event_pckt->evt) {
Wolfgang Betz 105:332f93cd06b7 276
Wolfgang Betz 105:332f93cd06b7 277 case EVT_CMD_STATUS:
Wolfgang Betz 105:332f93cd06b7 278 cs = (void *) ptr;
Wolfgang Betz 105:332f93cd06b7 279
Wolfgang Betz 105:332f93cd06b7 280 if (cs->opcode != opcode)
Wolfgang Betz 105:332f93cd06b7 281 goto failed;
Wolfgang Betz 105:332f93cd06b7 282
Wolfgang Betz 105:332f93cd06b7 283 if (r->event != EVT_CMD_STATUS) {
Wolfgang Betz 105:332f93cd06b7 284 if (cs->status) {
Wolfgang Betz 105:332f93cd06b7 285 goto failed;
Wolfgang Betz 90:26c0c9807ab4 286 }
Wolfgang Betz 105:332f93cd06b7 287 break;
Wolfgang Betz 105:332f93cd06b7 288 }
Wolfgang Betz 105:332f93cd06b7 289
Wolfgang Betz 105:332f93cd06b7 290 r->rlen = MIN(len, r->rlen);
Wolfgang Betz 105:332f93cd06b7 291 Osal_MemCpy(r->rparam, ptr, r->rlen);
Wolfgang Betz 105:332f93cd06b7 292 goto done;
Wolfgang Betz 105:332f93cd06b7 293
Wolfgang Betz 105:332f93cd06b7 294 case EVT_CMD_COMPLETE:
Wolfgang Betz 105:332f93cd06b7 295 cc = (void *) ptr;
Wolfgang Betz 105:332f93cd06b7 296
Wolfgang Betz 105:332f93cd06b7 297 if (cc->opcode != opcode)
Wolfgang Betz 105:332f93cd06b7 298 goto failed;
Wolfgang Betz 105:332f93cd06b7 299
Wolfgang Betz 105:332f93cd06b7 300 ptr += EVT_CMD_COMPLETE_SIZE;
Wolfgang Betz 105:332f93cd06b7 301 len -= EVT_CMD_COMPLETE_SIZE;
Wolfgang Betz 105:332f93cd06b7 302
Wolfgang Betz 105:332f93cd06b7 303 r->rlen = MIN(len, r->rlen);
Wolfgang Betz 105:332f93cd06b7 304 Osal_MemCpy(r->rparam, ptr, r->rlen);
Wolfgang Betz 105:332f93cd06b7 305 goto done;
Wolfgang Betz 105:332f93cd06b7 306
Wolfgang Betz 105:332f93cd06b7 307 case EVT_LE_META_EVENT:
Wolfgang Betz 105:332f93cd06b7 308 me = (void *) ptr;
Wolfgang Betz 105:332f93cd06b7 309
Wolfgang Betz 105:332f93cd06b7 310 if (me->subevent != r->event)
Wolfgang Betz 105:332f93cd06b7 311 break;
Wolfgang Betz 105:332f93cd06b7 312
Wolfgang Betz 105:332f93cd06b7 313 len -= 1;
Wolfgang Betz 105:332f93cd06b7 314 r->rlen = MIN(len, r->rlen);
Wolfgang Betz 105:332f93cd06b7 315 Osal_MemCpy(r->rparam, me->data, r->rlen);
Wolfgang Betz 105:332f93cd06b7 316 goto done;
Wolfgang Betz 105:332f93cd06b7 317
Wolfgang Betz 105:332f93cd06b7 318 case EVT_HARDWARE_ERROR:
Wolfgang Betz 105:332f93cd06b7 319 goto failed;
Wolfgang Betz 105:332f93cd06b7 320
Wolfgang Betz 105:332f93cd06b7 321 default:
Wolfgang Betz 105:332f93cd06b7 322 break;
Wolfgang Betz 105:332f93cd06b7 323 }
Wolfgang Betz 105:332f93cd06b7 324
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 329 list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket);
Wolfgang Betz 105:332f93cd06b7 330 /* Be sure there is at list one packet in the pool to process the expected event. */
Wolfgang Betz 105:332f93cd06b7 331 if(list_is_empty(&hciReadPktPool)){
Wolfgang Betz 105:332f93cd06b7 332 pListNode tmp_node;
Wolfgang Betz 105:332f93cd06b7 333 list_remove_head(&hciReadPktRxQueue, &tmp_node);
Wolfgang Betz 105:332f93cd06b7 334 list_insert_tail(&hciReadPktPool, tmp_node);
Wolfgang Betz 90:26c0c9807ab4 335 }
Wolfgang Betz 105:332f93cd06b7 336
Wolfgang Betz 105:332f93cd06b7 337 Enable_SPI_IRQ();
Wolfgang Betz 105:332f93cd06b7 338
Wolfgang Betz 105:332f93cd06b7 339 }
Wolfgang Betz 105:332f93cd06b7 340
Wolfgang Betz 103:12684d94c3a6 341 failed:
Wolfgang Betz 105:332f93cd06b7 342 move_list(&hciReadPktRxQueue, &hciTempQueue);
Wolfgang Betz 105:332f93cd06b7 343 Enable_SPI_IRQ();
Wolfgang Betz 105:332f93cd06b7 344 return -1;
Wolfgang Betz 105:332f93cd06b7 345
Wolfgang Betz 90:26c0c9807ab4 346 done:
Wolfgang Betz 105:332f93cd06b7 347 // Insert the packet back into the pool.
Wolfgang Betz 105:332f93cd06b7 348 list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
Wolfgang Betz 105:332f93cd06b7 349 move_list(&hciReadPktRxQueue, &hciTempQueue);
Wolfgang Betz 105:332f93cd06b7 350
Wolfgang Betz 105:332f93cd06b7 351 Enable_SPI_IRQ();
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 357 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 358 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 359
Wolfgang Betz 105:332f93cd06b7 360 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 361 rq.ogf = OGF_HOST_CTL;
Wolfgang Betz 105:332f93cd06b7 362 rq.ocf = OCF_RESET;
Wolfgang Betz 105:332f93cd06b7 363 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 364 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 365
Wolfgang Betz 105:332f93cd06b7 366 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 367 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 368
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 374 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 375 disconnect_cp cp;
Wolfgang Betz 105:332f93cd06b7 376 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 377
Wolfgang Betz 105:332f93cd06b7 378 cp.handle = handle;
Wolfgang Betz 105:332f93cd06b7 379 cp.reason = reason;
Wolfgang Betz 105:332f93cd06b7 380
Wolfgang Betz 105:332f93cd06b7 381 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 382 rq.ogf = OGF_LINK_CTL;
Wolfgang Betz 105:332f93cd06b7 383 rq.ocf = OCF_DISCONNECT;
Wolfgang Betz 105:332f93cd06b7 384 rq.cparam = &cp;
Wolfgang Betz 105:332f93cd06b7 385 rq.clen = DISCONNECT_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 386 rq.event = EVT_CMD_STATUS;
Wolfgang Betz 105:332f93cd06b7 387 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 388 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 389
Wolfgang Betz 105:332f93cd06b7 390 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 391 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 392
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 399 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 400 read_local_version_rp resp;
Wolfgang Betz 105:332f93cd06b7 401
Wolfgang Betz 105:332f93cd06b7 402 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 403
Wolfgang Betz 105:332f93cd06b7 404 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 405 rq.ogf = OGF_INFO_PARAM;
Wolfgang Betz 105:332f93cd06b7 406 rq.ocf = OCF_READ_LOCAL_VERSION;
Wolfgang Betz 105:332f93cd06b7 407 rq.cparam = NULL;
Wolfgang Betz 105:332f93cd06b7 408 rq.clen = 0;
Wolfgang Betz 105:332f93cd06b7 409 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 410 rq.rlen = READ_LOCAL_VERSION_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 411
Wolfgang Betz 105:332f93cd06b7 412 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 413 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 414
Wolfgang Betz 105:332f93cd06b7 415 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 416 return resp.status;
Wolfgang Betz 105:332f93cd06b7 417 }
Wolfgang Betz 105:332f93cd06b7 418
Wolfgang Betz 105:332f93cd06b7 419
Wolfgang Betz 105:332f93cd06b7 420 *hci_version = resp.hci_version;
Wolfgang Betz 105:332f93cd06b7 421 *hci_revision = btohs(resp.hci_revision);
Wolfgang Betz 105:332f93cd06b7 422 *lmp_pal_version = resp.lmp_pal_version;
Wolfgang Betz 105:332f93cd06b7 423 *manufacturer_name = btohs(resp.manufacturer_name);
Wolfgang Betz 105:332f93cd06b7 424 *lmp_pal_subversion = btohs(resp.lmp_pal_subversion);
Wolfgang Betz 105:332f93cd06b7 425
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 431 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 432 le_read_buffer_size_rp resp;
Wolfgang Betz 105:332f93cd06b7 433
Wolfgang Betz 105:332f93cd06b7 434 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 435
Wolfgang Betz 105:332f93cd06b7 436 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 437 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 438 rq.ocf = OCF_LE_READ_BUFFER_SIZE;
Wolfgang Betz 105:332f93cd06b7 439 rq.cparam = NULL;
Wolfgang Betz 105:332f93cd06b7 440 rq.clen = 0;
Wolfgang Betz 105:332f93cd06b7 441 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 442 rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 443
Wolfgang Betz 105:332f93cd06b7 444 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 445 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 446
Wolfgang Betz 105:332f93cd06b7 447 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 448 return resp.status;
Wolfgang Betz 105:332f93cd06b7 449 }
Wolfgang Betz 105:332f93cd06b7 450
Wolfgang Betz 105:332f93cd06b7 451 *pkt_len = resp.pkt_len;
Wolfgang Betz 105:332f93cd06b7 452 *max_pkt = resp.max_pkt;
Wolfgang Betz 105:332f93cd06b7 453
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 461 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 462 le_set_adv_parameters_cp adv_cp;
Wolfgang Betz 105:332f93cd06b7 463 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 464
Wolfgang Betz 105:332f93cd06b7 465 Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
Wolfgang Betz 105:332f93cd06b7 466 adv_cp.min_interval = min_interval;
Wolfgang Betz 105:332f93cd06b7 467 adv_cp.max_interval = max_interval;
Wolfgang Betz 105:332f93cd06b7 468 adv_cp.advtype = advtype;
Wolfgang Betz 105:332f93cd06b7 469 adv_cp.own_bdaddr_type = own_bdaddr_type;
Wolfgang Betz 105:332f93cd06b7 470 adv_cp.direct_bdaddr_type = direct_bdaddr_type;
Wolfgang Betz 105:332f93cd06b7 471 Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr));
Wolfgang Betz 105:332f93cd06b7 472 adv_cp.chan_map = chan_map;
Wolfgang Betz 105:332f93cd06b7 473 adv_cp.filter = filter;
Wolfgang Betz 105:332f93cd06b7 474
Wolfgang Betz 105:332f93cd06b7 475 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 476 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 477 rq.ocf = OCF_LE_SET_ADV_PARAMETERS;
Wolfgang Betz 105:332f93cd06b7 478 rq.cparam = &adv_cp;
Wolfgang Betz 105:332f93cd06b7 479 rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 480 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 481 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 482
Wolfgang Betz 105:332f93cd06b7 483 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 484 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 485
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 491 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 492 le_set_adv_data_cp adv_cp;
Wolfgang Betz 105:332f93cd06b7 493 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 494
Wolfgang Betz 105:332f93cd06b7 495 Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
Wolfgang Betz 105:332f93cd06b7 496 adv_cp.length = length;
Wolfgang Betz 105:332f93cd06b7 497 Osal_MemCpy(adv_cp.data, data, MIN(31,length));
Wolfgang Betz 105:332f93cd06b7 498
Wolfgang Betz 105:332f93cd06b7 499 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 500 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 501 rq.ocf = OCF_LE_SET_ADV_DATA;
Wolfgang Betz 105:332f93cd06b7 502 rq.cparam = &adv_cp;
Wolfgang Betz 105:332f93cd06b7 503 rq.clen = LE_SET_ADV_DATA_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 504 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 505 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 506
Wolfgang Betz 105:332f93cd06b7 507 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 508 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 509
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 515 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 516 le_set_advertise_enable_cp adv_cp;
Wolfgang Betz 105:332f93cd06b7 517 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 518
Wolfgang Betz 105:332f93cd06b7 519 Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
Wolfgang Betz 105:332f93cd06b7 520 adv_cp.enable = enable?1:0;
Wolfgang Betz 105:332f93cd06b7 521
Wolfgang Betz 105:332f93cd06b7 522 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 523 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 524 rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
Wolfgang Betz 105:332f93cd06b7 525 rq.cparam = &adv_cp;
Wolfgang Betz 105:332f93cd06b7 526 rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 527 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 528 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 529
Wolfgang Betz 105:332f93cd06b7 530 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 531 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 532
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 540 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 541 le_set_scan_parameters_cp scan_cp;
Wolfgang Betz 105:332f93cd06b7 542 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 543
Wolfgang Betz 105:332f93cd06b7 544 Osal_MemSet(&scan_cp, 0, sizeof(scan_cp));
Wolfgang Betz 105:332f93cd06b7 545 scan_cp.type = type;
Wolfgang Betz 105:332f93cd06b7 546 scan_cp.interval = interval;
Wolfgang Betz 105:332f93cd06b7 547 scan_cp.window = window;
Wolfgang Betz 105:332f93cd06b7 548 scan_cp.own_bdaddr_type = own_bdaddr_type;
Wolfgang Betz 105:332f93cd06b7 549 scan_cp.filter = filter;
Wolfgang Betz 105:332f93cd06b7 550
Wolfgang Betz 105:332f93cd06b7 551 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 552 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 553 rq.ocf = OCF_LE_SET_SCAN_PARAMETERS;
Wolfgang Betz 105:332f93cd06b7 554 rq.cparam = &scan_cp;
Wolfgang Betz 105:332f93cd06b7 555 rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 556 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 557 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 558
Wolfgang Betz 105:332f93cd06b7 559 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 560 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 561
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 567 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 568 le_set_scan_enable_cp scan_cp;
Wolfgang Betz 105:332f93cd06b7 569 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 570
Wolfgang Betz 105:332f93cd06b7 571 Osal_MemSet(&scan_cp, 0, sizeof(scan_cp));
Wolfgang Betz 105:332f93cd06b7 572 scan_cp.enable = enable?1:0;
Wolfgang Betz 105:332f93cd06b7 573 scan_cp.filter_dup = filter_dup;
Wolfgang Betz 105:332f93cd06b7 574
Wolfgang Betz 105:332f93cd06b7 575 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 576 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 577 rq.ocf = OCF_LE_SET_SCAN_ENABLE;
Wolfgang Betz 105:332f93cd06b7 578 rq.cparam = &scan_cp;
Wolfgang Betz 105:332f93cd06b7 579 rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 580 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 581 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 582
Wolfgang Betz 105:332f93cd06b7 583 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 584 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 585
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 591 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 592 le_rand_rp resp;
Wolfgang Betz 105:332f93cd06b7 593
Wolfgang Betz 105:332f93cd06b7 594 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 595
Wolfgang Betz 105:332f93cd06b7 596 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 597 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 598 rq.ocf = OCF_LE_RAND;
Wolfgang Betz 105:332f93cd06b7 599 rq.cparam = NULL;
Wolfgang Betz 105:332f93cd06b7 600 rq.clen = 0;
Wolfgang Betz 105:332f93cd06b7 601 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 602 rq.rlen = LE_RAND_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 603
Wolfgang Betz 105:332f93cd06b7 604 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 605 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 606
Wolfgang Betz 105:332f93cd06b7 607 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 608 return resp.status;
Wolfgang Betz 105:332f93cd06b7 609 }
Wolfgang Betz 105:332f93cd06b7 610
Wolfgang Betz 105:332f93cd06b7 611 Osal_MemCpy(random_number, resp.random, 8);
Wolfgang Betz 105:332f93cd06b7 612
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 618 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 619 le_set_scan_response_data_cp scan_resp_cp;
Wolfgang Betz 105:332f93cd06b7 620 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 621
Wolfgang Betz 105:332f93cd06b7 622 Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp));
Wolfgang Betz 105:332f93cd06b7 623 scan_resp_cp.length = length;
Wolfgang Betz 105:332f93cd06b7 624 Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length));
Wolfgang Betz 105:332f93cd06b7 625
Wolfgang Betz 105:332f93cd06b7 626 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 627 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 628 rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA;
Wolfgang Betz 105:332f93cd06b7 629 rq.cparam = &scan_resp_cp;
Wolfgang Betz 105:332f93cd06b7 630 rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 631 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 632 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 633
Wolfgang Betz 105:332f93cd06b7 634 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 635 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 636
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 642 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 643 le_read_adv_channel_tx_power_rp resp;
Wolfgang Betz 105:332f93cd06b7 644
Wolfgang Betz 105:332f93cd06b7 645 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 646
Wolfgang Betz 105:332f93cd06b7 647 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 648 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 649 rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER;
Wolfgang Betz 105:332f93cd06b7 650 rq.cparam = NULL;
Wolfgang Betz 105:332f93cd06b7 651 rq.clen = 0;
Wolfgang Betz 105:332f93cd06b7 652 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 653 rq.rlen = LE_RAND_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 654
Wolfgang Betz 105:332f93cd06b7 655 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 656 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 657
Wolfgang Betz 105:332f93cd06b7 658 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 659 return resp.status;
Wolfgang Betz 105:332f93cd06b7 660 }
Wolfgang Betz 105:332f93cd06b7 661
Wolfgang Betz 105:332f93cd06b7 662 *tx_power_level = resp.level;
Wolfgang Betz 105:332f93cd06b7 663
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 669 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 670 le_set_random_address_cp set_rand_addr_cp;
Wolfgang Betz 105:332f93cd06b7 671 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 672
Wolfgang Betz 105:332f93cd06b7 673 Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp));
Wolfgang Betz 105:332f93cd06b7 674 Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr));
Wolfgang Betz 105:332f93cd06b7 675
Wolfgang Betz 105:332f93cd06b7 676 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 677 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 678 rq.ocf = OCF_LE_SET_RANDOM_ADDRESS;
Wolfgang Betz 105:332f93cd06b7 679 rq.cparam = &set_rand_addr_cp;
Wolfgang Betz 105:332f93cd06b7 680 rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 681 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 682 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 683
Wolfgang Betz 105:332f93cd06b7 684 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 685 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 686
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 692 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 693 read_bd_addr_rp resp;
Wolfgang Betz 105:332f93cd06b7 694
Wolfgang Betz 105:332f93cd06b7 695 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 696
Wolfgang Betz 105:332f93cd06b7 697 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 698 rq.ogf = OGF_INFO_PARAM;
Wolfgang Betz 105:332f93cd06b7 699 rq.ocf = OCF_READ_BD_ADDR;
Wolfgang Betz 105:332f93cd06b7 700 rq.cparam = NULL;
Wolfgang Betz 105:332f93cd06b7 701 rq.clen = 0;
Wolfgang Betz 105:332f93cd06b7 702 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 703 rq.rlen = READ_BD_ADDR_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 704
Wolfgang Betz 105:332f93cd06b7 705 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 706 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 707
Wolfgang Betz 105:332f93cd06b7 708 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 709 return resp.status;
Wolfgang Betz 105:332f93cd06b7 710 }
Wolfgang Betz 105:332f93cd06b7 711 Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr));
Wolfgang Betz 105:332f93cd06b7 712
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 720 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 721 le_create_connection_cp create_cp;
Wolfgang Betz 105:332f93cd06b7 722 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 723
Wolfgang Betz 105:332f93cd06b7 724 Osal_MemSet(&create_cp, 0, sizeof(create_cp));
Wolfgang Betz 105:332f93cd06b7 725 create_cp.interval = interval;
Wolfgang Betz 105:332f93cd06b7 726 create_cp.window = window;
Wolfgang Betz 105:332f93cd06b7 727 create_cp.initiator_filter = initiator_filter;
Wolfgang Betz 105:332f93cd06b7 728 create_cp.peer_bdaddr_type = peer_bdaddr_type;
Wolfgang Betz 105:332f93cd06b7 729 Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr));
Wolfgang Betz 105:332f93cd06b7 730 create_cp.own_bdaddr_type = own_bdaddr_type;
Wolfgang Betz 105:332f93cd06b7 731 create_cp.min_interval=min_interval;
Wolfgang Betz 105:332f93cd06b7 732 create_cp.max_interval=max_interval;
Wolfgang Betz 105:332f93cd06b7 733 create_cp.latency = latency;
Wolfgang Betz 105:332f93cd06b7 734 create_cp.supervision_timeout=supervision_timeout;
Wolfgang Betz 105:332f93cd06b7 735 create_cp.min_ce_length=min_ce_length;
Wolfgang Betz 105:332f93cd06b7 736 create_cp.max_ce_length=max_ce_length;
Wolfgang Betz 105:332f93cd06b7 737
Wolfgang Betz 105:332f93cd06b7 738 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 739 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 740 rq.ocf = OCF_LE_CREATE_CONN;
Wolfgang Betz 105:332f93cd06b7 741 rq.cparam = &create_cp;
Wolfgang Betz 105:332f93cd06b7 742 rq.clen = LE_CREATE_CONN_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 743 rq.event = EVT_CMD_STATUS;
Wolfgang Betz 105:332f93cd06b7 744 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 745 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 746
Wolfgang Betz 105:332f93cd06b7 747 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 748 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 749
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 755 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 756 le_encrypt_cp params;
Wolfgang Betz 105:332f93cd06b7 757 le_encrypt_rp resp;
Wolfgang Betz 105:332f93cd06b7 758
Wolfgang Betz 105:332f93cd06b7 759 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 760
Wolfgang Betz 105:332f93cd06b7 761 Osal_MemCpy(params.key, key, 16);
Wolfgang Betz 105:332f93cd06b7 762 Osal_MemCpy(params.plaintext, plaintextData, 16);
Wolfgang Betz 105:332f93cd06b7 763
Wolfgang Betz 105:332f93cd06b7 764 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 765 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 766 rq.ocf = OCF_LE_ENCRYPT;
Wolfgang Betz 105:332f93cd06b7 767 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 768 rq.clen = LE_ENCRYPT_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 769 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 770 rq.rlen = LE_ENCRYPT_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 771
Wolfgang Betz 105:332f93cd06b7 772 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 773 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 774 }
Wolfgang Betz 105:332f93cd06b7 775
Wolfgang Betz 105:332f93cd06b7 776 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 777 return resp.status;
Wolfgang Betz 105:332f93cd06b7 778 }
Wolfgang Betz 105:332f93cd06b7 779
Wolfgang Betz 105:332f93cd06b7 780 Osal_MemCpy(encryptedData, resp.encdata, 16);
Wolfgang Betz 105:332f93cd06b7 781
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 787 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 788 le_ltk_reply_cp params;
Wolfgang Betz 105:332f93cd06b7 789 le_ltk_reply_rp resp;
Wolfgang Betz 105:332f93cd06b7 790
Wolfgang Betz 105:332f93cd06b7 791 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 792
Wolfgang Betz 105:332f93cd06b7 793 params.handle = 1;
Wolfgang Betz 105:332f93cd06b7 794 Osal_MemCpy(params.key, key, 16);
Wolfgang Betz 105:332f93cd06b7 795
Wolfgang Betz 105:332f93cd06b7 796 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 797 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 798 rq.ocf = OCF_LE_LTK_REPLY;
Wolfgang Betz 105:332f93cd06b7 799 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 800 rq.clen = LE_LTK_REPLY_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 801 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 802 rq.rlen = LE_LTK_REPLY_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 803
Wolfgang Betz 105:332f93cd06b7 804 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 805 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 806
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 812 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 813 le_ltk_neg_reply_cp params;
Wolfgang Betz 105:332f93cd06b7 814 le_ltk_neg_reply_rp resp;
Wolfgang Betz 105:332f93cd06b7 815
Wolfgang Betz 105:332f93cd06b7 816 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 817
Wolfgang Betz 105:332f93cd06b7 818 params.handle = 1;
Wolfgang Betz 105:332f93cd06b7 819
Wolfgang Betz 105:332f93cd06b7 820 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 821 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 822 rq.ocf = OCF_LE_LTK_NEG_REPLY;
Wolfgang Betz 105:332f93cd06b7 823 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 824 rq.clen = LE_LTK_NEG_REPLY_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 825 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 826 rq.rlen = LE_LTK_NEG_REPLY_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 827
Wolfgang Betz 105:332f93cd06b7 828 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 105:332f93cd06b7 829 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 830
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 836 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 837 le_read_white_list_size_rp resp;
Wolfgang Betz 105:332f93cd06b7 838
Wolfgang Betz 105:332f93cd06b7 839 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 840
Wolfgang Betz 105:332f93cd06b7 841 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 842 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 843 rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
Wolfgang Betz 105:332f93cd06b7 844 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 845 rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 846
Wolfgang Betz 105:332f93cd06b7 847 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 848 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 849 }
Wolfgang Betz 105:332f93cd06b7 850
Wolfgang Betz 105:332f93cd06b7 851 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 852 return resp.status;
Wolfgang Betz 105:332f93cd06b7 853 }
Wolfgang Betz 105:332f93cd06b7 854
Wolfgang Betz 105:332f93cd06b7 855 *size = resp.size;
Wolfgang Betz 105:332f93cd06b7 856
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 862 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 863 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 864
Wolfgang Betz 105:332f93cd06b7 865 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 866 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 867 rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
Wolfgang Betz 105:332f93cd06b7 868 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 869 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 870
Wolfgang Betz 105:332f93cd06b7 871 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 872 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 873 }
Wolfgang Betz 105:332f93cd06b7 874
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 880 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 881 le_add_device_to_white_list_cp params;
Wolfgang Betz 105:332f93cd06b7 882 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 883
Wolfgang Betz 105:332f93cd06b7 884 params.bdaddr_type = bdaddr_type;
Wolfgang Betz 105:332f93cd06b7 885 Osal_MemCpy(params.bdaddr, bdaddr, 6);
Wolfgang Betz 105:332f93cd06b7 886
Wolfgang Betz 105:332f93cd06b7 887 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 888 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 889 rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
Wolfgang Betz 105:332f93cd06b7 890 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 891 rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 892 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 893 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 894
Wolfgang Betz 105:332f93cd06b7 895 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 896 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 897 }
Wolfgang Betz 105:332f93cd06b7 898
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 904 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 905 le_remove_device_from_white_list_cp params;
Wolfgang Betz 105:332f93cd06b7 906 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 907
Wolfgang Betz 105:332f93cd06b7 908 params.bdaddr_type = bdaddr_type;
Wolfgang Betz 105:332f93cd06b7 909 Osal_MemCpy(params.bdaddr, bdaddr, 6);
Wolfgang Betz 105:332f93cd06b7 910
Wolfgang Betz 105:332f93cd06b7 911 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 912 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 913 rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
Wolfgang Betz 105:332f93cd06b7 914 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 915 rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 916 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 917 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 918
Wolfgang Betz 105:332f93cd06b7 919 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 920 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 921 }
Wolfgang Betz 105:332f93cd06b7 922
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 928 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 929 read_transmit_power_level_cp params;
Wolfgang Betz 105:332f93cd06b7 930 read_transmit_power_level_rp resp;
Wolfgang Betz 105:332f93cd06b7 931
Wolfgang Betz 105:332f93cd06b7 932 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 933
Wolfgang Betz 105:332f93cd06b7 934 params.handle = *conn_handle;
Wolfgang Betz 105:332f93cd06b7 935 params.type = type;
Wolfgang Betz 105:332f93cd06b7 936
Wolfgang Betz 105:332f93cd06b7 937 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 938 rq.ogf = OGF_HOST_CTL;
Wolfgang Betz 105:332f93cd06b7 939 rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL;
Wolfgang Betz 105:332f93cd06b7 940 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 941 rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 942 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 943 rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 944
Wolfgang Betz 105:332f93cd06b7 945 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 946 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 947 }
Wolfgang Betz 105:332f93cd06b7 948
Wolfgang Betz 105:332f93cd06b7 949 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 950 return resp.status;
Wolfgang Betz 105:332f93cd06b7 951 }
Wolfgang Betz 105:332f93cd06b7 952
Wolfgang Betz 105:332f93cd06b7 953 *conn_handle = resp.handle;
Wolfgang Betz 105:332f93cd06b7 954 *tx_level = resp.level;
Wolfgang Betz 105:332f93cd06b7 955
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 961 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 962 read_rssi_cp params;
Wolfgang Betz 105:332f93cd06b7 963 read_rssi_rp resp;
Wolfgang Betz 105:332f93cd06b7 964
Wolfgang Betz 105:332f93cd06b7 965 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 966
Wolfgang Betz 105:332f93cd06b7 967 params.handle = *conn_handle;
Wolfgang Betz 105:332f93cd06b7 968
Wolfgang Betz 105:332f93cd06b7 969 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 970 rq.ogf = OGF_STATUS_PARAM;
Wolfgang Betz 105:332f93cd06b7 971 rq.ocf = OCF_READ_RSSI;
Wolfgang Betz 105:332f93cd06b7 972 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 973 rq.clen = READ_RSSI_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 974 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 975 rq.rlen = READ_RSSI_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 976
Wolfgang Betz 105:332f93cd06b7 977 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 978 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 979 }
Wolfgang Betz 105:332f93cd06b7 980
Wolfgang Betz 105:332f93cd06b7 981 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 982 return resp.status;
Wolfgang Betz 105:332f93cd06b7 983 }
Wolfgang Betz 105:332f93cd06b7 984
Wolfgang Betz 105:332f93cd06b7 985 *conn_handle = resp.handle;
Wolfgang Betz 105:332f93cd06b7 986 *rssi = resp.rssi;
Wolfgang Betz 105:332f93cd06b7 987
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 993 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 994 le_read_local_supported_features_rp resp;
Wolfgang Betz 105:332f93cd06b7 995
Wolfgang Betz 105:332f93cd06b7 996 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 997
Wolfgang Betz 105:332f93cd06b7 998 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 999 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 1000 rq.ocf = OCF_LE_READ_LOCAL_SUPPORTED_FEATURES;
Wolfgang Betz 105:332f93cd06b7 1001 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 1002 rq.rlen = LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 1003
Wolfgang Betz 105:332f93cd06b7 1004 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 1005 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 1006 }
Wolfgang Betz 105:332f93cd06b7 1007
Wolfgang Betz 105:332f93cd06b7 1008 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 1009 return resp.status;
Wolfgang Betz 105:332f93cd06b7 1010 }
Wolfgang Betz 105:332f93cd06b7 1011
Wolfgang Betz 105:332f93cd06b7 1012 Osal_MemCpy(features, resp.features, sizeof(resp.features));
Wolfgang Betz 105:332f93cd06b7 1013
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 1019 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 1020 le_read_channel_map_cp params;
Wolfgang Betz 105:332f93cd06b7 1021 le_read_channel_map_rp resp;
Wolfgang Betz 105:332f93cd06b7 1022
Wolfgang Betz 105:332f93cd06b7 1023 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 1024
Wolfgang Betz 105:332f93cd06b7 1025 params.handle = conn_handle;
Wolfgang Betz 105:332f93cd06b7 1026
Wolfgang Betz 105:332f93cd06b7 1027 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 1028 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 1029 rq.ocf = OCF_LE_READ_CHANNEL_MAP;
Wolfgang Betz 105:332f93cd06b7 1030 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 1031 rq.clen = LE_READ_CHANNEL_MAP_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 1032 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 1033 rq.rlen = LE_READ_CHANNEL_MAP_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 1034
Wolfgang Betz 105:332f93cd06b7 1035 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 1036 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 1037 }
Wolfgang Betz 105:332f93cd06b7 1038
Wolfgang Betz 105:332f93cd06b7 1039 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 1040 return resp.status;
Wolfgang Betz 105:332f93cd06b7 1041 }
Wolfgang Betz 105:332f93cd06b7 1042
Wolfgang Betz 105:332f93cd06b7 1043 Osal_MemCpy(ch_map, resp.map, 5);
Wolfgang Betz 105:332f93cd06b7 1044
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 1050 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 1051 le_read_supported_states_rp resp;
Wolfgang Betz 105:332f93cd06b7 1052
Wolfgang Betz 105:332f93cd06b7 1053 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 1054
Wolfgang Betz 105:332f93cd06b7 1055 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 1056 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 1057 rq.ocf = OCF_LE_READ_SUPPORTED_STATES;
Wolfgang Betz 105:332f93cd06b7 1058 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 1059 rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 1060
Wolfgang Betz 105:332f93cd06b7 1061 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 1062 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 1063 }
Wolfgang Betz 105:332f93cd06b7 1064
Wolfgang Betz 105:332f93cd06b7 1065 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 1066 return resp.status;
Wolfgang Betz 105:332f93cd06b7 1067 }
Wolfgang Betz 105:332f93cd06b7 1068
Wolfgang Betz 105:332f93cd06b7 1069 Osal_MemCpy(states, resp.states, 8);
Wolfgang Betz 105:332f93cd06b7 1070
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 1076 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 1077 le_receiver_test_cp params;
Wolfgang Betz 105:332f93cd06b7 1078 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 1079
Wolfgang Betz 105:332f93cd06b7 1080 params.frequency = frequency;
Wolfgang Betz 105:332f93cd06b7 1081
Wolfgang Betz 105:332f93cd06b7 1082 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 1083 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 1084 rq.ocf = OCF_LE_RECEIVER_TEST;
Wolfgang Betz 105:332f93cd06b7 1085 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 1086 rq.clen = LE_RECEIVER_TEST_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 1087 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 1088 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 1089
Wolfgang Betz 105:332f93cd06b7 1090 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 1091 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 1092 }
Wolfgang Betz 105:332f93cd06b7 1093
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 1099 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 1100 le_transmitter_test_cp params;
Wolfgang Betz 105:332f93cd06b7 1101 uint8_t status;
Wolfgang Betz 105:332f93cd06b7 1102
Wolfgang Betz 105:332f93cd06b7 1103 params.frequency = frequency;
Wolfgang Betz 105:332f93cd06b7 1104 params.length = length;
Wolfgang Betz 105:332f93cd06b7 1105 params.payload = payload;
Wolfgang Betz 105:332f93cd06b7 1106
Wolfgang Betz 105:332f93cd06b7 1107 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 1108 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 1109 rq.ocf = OCF_LE_TRANSMITTER_TEST;
Wolfgang Betz 105:332f93cd06b7 1110 rq.cparam = &params;
Wolfgang Betz 105:332f93cd06b7 1111 rq.clen = LE_TRANSMITTER_TEST_CP_SIZE;
Wolfgang Betz 105:332f93cd06b7 1112 rq.rparam = &status;
Wolfgang Betz 105:332f93cd06b7 1113 rq.rlen = 1;
Wolfgang Betz 105:332f93cd06b7 1114
Wolfgang Betz 105:332f93cd06b7 1115 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 1116 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 1117 }
Wolfgang Betz 105:332f93cd06b7 1118
Wolfgang Betz 105:332f93cd06b7 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 105:332f93cd06b7 1124 struct hci_request rq;
Wolfgang Betz 105:332f93cd06b7 1125 le_test_end_rp resp;
Wolfgang Betz 105:332f93cd06b7 1126
Wolfgang Betz 105:332f93cd06b7 1127 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 105:332f93cd06b7 1128
Wolfgang Betz 105:332f93cd06b7 1129 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 105:332f93cd06b7 1130 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 105:332f93cd06b7 1131 rq.ocf = OCF_LE_TEST_END;
Wolfgang Betz 105:332f93cd06b7 1132 rq.rparam = &resp;
Wolfgang Betz 105:332f93cd06b7 1133 rq.rlen = LE_TEST_END_RP_SIZE;
Wolfgang Betz 105:332f93cd06b7 1134
Wolfgang Betz 105:332f93cd06b7 1135 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 105:332f93cd06b7 1136 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 105:332f93cd06b7 1137 }
Wolfgang Betz 105:332f93cd06b7 1138
Wolfgang Betz 105:332f93cd06b7 1139 if (resp.status) {
Wolfgang Betz 105:332f93cd06b7 1140 return resp.status;
Wolfgang Betz 105:332f93cd06b7 1141 }
Wolfgang Betz 105:332f93cd06b7 1142
Wolfgang Betz 105:332f93cd06b7 1143 *num_pkts = resp.num_pkts;
Wolfgang Betz 105:332f93cd06b7 1144
Wolfgang Betz 105:332f93cd06b7 1145 return 0;
Wolfgang Betz 90:26c0c9807ab4 1146 }
Wolfgang Betz 90:26c0c9807ab4 1147