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:
Wed Oct 07 09:08:22 2015 +0200
Revision:
133:1bb8df697f7f
Parent:
132:51056160fa4a
Child:
135:f0b6cf8ac4fc
Add callback after IRQ

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