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 08:39:04 2015 +0200
Revision:
132:51056160fa4a
Child:
133:1bb8df697f7f
Andrea's version as of mail from 10/06/2015 05:56 PM

From: Andrea PALMIERI <andrea.palmieri@st.com>
To: Wolfgang BETZ <wolfgang.betz@st.com>, Rohit Grover <rohit.grover@arm.com>,
Antonio VILEI <antonio.vilei@st.com>, Mihail Stoyanov
<Mihail.Stoyanov@arm.com>
CC: Nicola CAPOVILLA <nicola.capovilla@st.com>, Silvio Lucio OLIVA
<silvio.oliva@st.com>, "jonathan.austin@arm.com" <jonathan.austin@arm.com>
Content-Class: urn:content-classes:message
Date: Tue, 6 Oct 2015 17:56:34 +0200
Subject: RE: Arduino Compatibility of X-NUCLEO-IDB04A1

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