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:
Andrea Palmieri
Date:
Mon May 16 17:22:03 2016 +0200
Revision:
229:9981f62cdb1a
Parent:
165:3576598c0889
Child:
264:1e754a01869e
Fix issues and add features

- Fix handles management
- Fix UUIDs management
- Implement API to read random address
- Fix clearing/setting of ADV payload
- Fix scanning behaviour
- Fix scanning while a connection is ongoing
- Implement Char Descriptor discovery
- Implement scanning/advertising filter policy (White List partial management)
- Update underlying BlueNRG stack
- Cosmetics

Signed-off-by: Andrea Palmieri <andrea.palmieri@st.com>

Who changed what in which revision?

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