ST / X_NUCLEO_IDB0XA1

Dependents:   Nucleo_Zumo_BLE_IDB04A1 contest_IOT5 contest_IOT6 contest_IOT_10 ... more

Fork of X_NUCLEO_IDB0XA1 by ST Expansion SW Team

Arduino Connector Compatibility Warning

X-NUCLEO-IDB04A1 and X-NUCLEO-IDB05A1 are Arduino compatible with an exception: instead of using pin D13 for the SPI clock, they use pin D3. The default configuration for this library is having the SPI clock on pin D3.

To be fully Arduino compatible, X-NUCLEO-IDB04A1 and X-NUCLEO-IDB05A1 need a small HW patch.

For X-NUCLEO-IDB04A1 this patch consists in removing zero resistor R10 and instead soldering zero resistor R11. For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor R4 and instead soldering zero resistor R6.

In case you patch your board, then you also have to configure this library to use pin D13 to drive the SPI clock (see macro IDB0XA1_D13_PATCH in file x_nucleo_idb0xa1_targets.h).

If you use pin D13 for the SPI clock, please be aware that on STM32 Nucleo boards you may not drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin D13.

Referring to the current list of tested platforms (see X-NUCLEO-IDB04A1 and X-NUCLEO-IDB05A1 pages), the patch is required by ST-Nucleo-F103RB; ST-Nucleo-F302R8; ST-Nucleo-F411RE; and ST-Nucleo-F446RE.

Committer:
Wolfgang Betz
Date:
Thu Oct 08 07:29:43 2015 +0200
Revision:
138:32e3c4ca7a45
Parent:
137:5baea3b414d9
Child:
140:0cd922dca83c
Use 'AST_FOR_MBED_OS' instead of 'YOTTA_CFG_MBED_OS'

Who changed what in which revision?

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