ver:init

Committer:
iv123
Date:
Sun Jun 18 16:10:28 2017 +0000
Revision:
0:88b85febcb45
Initial commit

Who changed what in which revision?

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