X_NUCLEO_IDB0XA1

Dependents:   BLE_HeartRate_IDB0XA1

Fork of X_NUCLEO_IDB0XA1 by ST

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