ST / X_NUCLEO_IDB0XA1

Dependents:   Nucleo_Zumo_BLE_IDB04A1 contest_IOT5 contest_IOT6 contest_IOT_10 ... more

Fork of X_NUCLEO_IDB0XA1 by ST Expansion SW Team

Arduino Connector Compatibility Warning

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

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

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

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

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

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

Committer:
Wolfgang Betz
Date:
Fri Oct 30 14:08:52 2015 +0100
Revision:
164:51bba7d36eb4
Parent:
163:4c008b1089e9
Child:
165:3576598c0889
Perform a saver queue handling

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 164:51bba7d36eb4 35 #define HCI_READ_PACKET_NUM_MAX (0x20)
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;
Wolfgang Betz 132:51056160fa4a 538 Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr));
Wolfgang Betz 132:51056160fa4a 539 adv_cp.chan_map = chan_map;
Wolfgang Betz 132:51056160fa4a 540 adv_cp.filter = filter;
Wolfgang Betz 132:51056160fa4a 541
Wolfgang Betz 132:51056160fa4a 542 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 543 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 544 rq.ocf = OCF_LE_SET_ADV_PARAMETERS;
Wolfgang Betz 132:51056160fa4a 545 rq.cparam = &adv_cp;
Wolfgang Betz 132:51056160fa4a 546 rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 547 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 548 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 549
Wolfgang Betz 132:51056160fa4a 550 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 551 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 552
Wolfgang Betz 132:51056160fa4a 553 return status;
Wolfgang Betz 132:51056160fa4a 554 }
Wolfgang Betz 132:51056160fa4a 555
Wolfgang Betz 132:51056160fa4a 556 int hci_le_set_advertising_data(uint8_t length, const uint8_t data[])
Wolfgang Betz 132:51056160fa4a 557 {
Wolfgang Betz 132:51056160fa4a 558 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 559 le_set_adv_data_cp adv_cp;
Wolfgang Betz 132:51056160fa4a 560 uint8_t status;
Wolfgang Betz 132:51056160fa4a 561
Wolfgang Betz 132:51056160fa4a 562 Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
Wolfgang Betz 132:51056160fa4a 563 adv_cp.length = length;
Wolfgang Betz 132:51056160fa4a 564 Osal_MemCpy(adv_cp.data, data, MIN(31,length));
Wolfgang Betz 132:51056160fa4a 565
Wolfgang Betz 132:51056160fa4a 566 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 567 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 568 rq.ocf = OCF_LE_SET_ADV_DATA;
Wolfgang Betz 132:51056160fa4a 569 rq.cparam = &adv_cp;
Wolfgang Betz 132:51056160fa4a 570 rq.clen = LE_SET_ADV_DATA_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 571 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 572 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 573
Wolfgang Betz 132:51056160fa4a 574 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 575 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 576
Wolfgang Betz 132:51056160fa4a 577 return status;
Wolfgang Betz 132:51056160fa4a 578 }
Wolfgang Betz 132:51056160fa4a 579
Wolfgang Betz 132:51056160fa4a 580 int hci_le_set_advertise_enable(uint8_t enable)
Wolfgang Betz 132:51056160fa4a 581 {
Wolfgang Betz 132:51056160fa4a 582 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 583 le_set_advertise_enable_cp adv_cp;
Wolfgang Betz 132:51056160fa4a 584 uint8_t status;
Wolfgang Betz 132:51056160fa4a 585
Wolfgang Betz 132:51056160fa4a 586 Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
Wolfgang Betz 132:51056160fa4a 587 adv_cp.enable = enable?1:0;
Wolfgang Betz 132:51056160fa4a 588
Wolfgang Betz 132:51056160fa4a 589 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 590 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 591 rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
Wolfgang Betz 132:51056160fa4a 592 rq.cparam = &adv_cp;
Wolfgang Betz 132:51056160fa4a 593 rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 594 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 595 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 596
Wolfgang Betz 132:51056160fa4a 597 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 598 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 599
Wolfgang Betz 132:51056160fa4a 600 return status;
Wolfgang Betz 132:51056160fa4a 601 }
Wolfgang Betz 132:51056160fa4a 602
Wolfgang Betz 132:51056160fa4a 603 int hci_le_set_scan_parameters(uint8_t type, uint16_t interval,
Wolfgang Betz 132:51056160fa4a 604 uint16_t window, uint8_t own_bdaddr_type,
Wolfgang Betz 132:51056160fa4a 605 uint8_t filter)
Wolfgang Betz 132:51056160fa4a 606 {
Wolfgang Betz 132:51056160fa4a 607 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 608 le_set_scan_parameters_cp scan_cp;
Wolfgang Betz 132:51056160fa4a 609 uint8_t status;
Wolfgang Betz 132:51056160fa4a 610
Wolfgang Betz 132:51056160fa4a 611 Osal_MemSet(&scan_cp, 0, sizeof(scan_cp));
Wolfgang Betz 132:51056160fa4a 612 scan_cp.type = type;
Wolfgang Betz 132:51056160fa4a 613 scan_cp.interval = interval;
Wolfgang Betz 132:51056160fa4a 614 scan_cp.window = window;
Wolfgang Betz 132:51056160fa4a 615 scan_cp.own_bdaddr_type = own_bdaddr_type;
Wolfgang Betz 132:51056160fa4a 616 scan_cp.filter = filter;
Wolfgang Betz 132:51056160fa4a 617
Wolfgang Betz 132:51056160fa4a 618 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 619 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 620 rq.ocf = OCF_LE_SET_SCAN_PARAMETERS;
Wolfgang Betz 132:51056160fa4a 621 rq.cparam = &scan_cp;
Wolfgang Betz 132:51056160fa4a 622 rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 623 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 624 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 625
Wolfgang Betz 132:51056160fa4a 626 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 627 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 628
Wolfgang Betz 132:51056160fa4a 629 return status;
Wolfgang Betz 132:51056160fa4a 630 }
Wolfgang Betz 132:51056160fa4a 631
Wolfgang Betz 132:51056160fa4a 632 int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup)
Wolfgang Betz 132:51056160fa4a 633 {
Wolfgang Betz 132:51056160fa4a 634 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 635 le_set_scan_enable_cp scan_cp;
Wolfgang Betz 132:51056160fa4a 636 uint8_t status;
Wolfgang Betz 132:51056160fa4a 637
Wolfgang Betz 132:51056160fa4a 638 Osal_MemSet(&scan_cp, 0, sizeof(scan_cp));
Wolfgang Betz 132:51056160fa4a 639 scan_cp.enable = enable?1:0;
Wolfgang Betz 132:51056160fa4a 640 scan_cp.filter_dup = filter_dup;
Wolfgang Betz 132:51056160fa4a 641
Wolfgang Betz 132:51056160fa4a 642 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 643 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 644 rq.ocf = OCF_LE_SET_SCAN_ENABLE;
Wolfgang Betz 132:51056160fa4a 645 rq.cparam = &scan_cp;
Wolfgang Betz 132:51056160fa4a 646 rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 647 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 648 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 649
Wolfgang Betz 132:51056160fa4a 650 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 651 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 652
Wolfgang Betz 132:51056160fa4a 653 return status;
Wolfgang Betz 132:51056160fa4a 654 }
Wolfgang Betz 132:51056160fa4a 655
Wolfgang Betz 132:51056160fa4a 656 int hci_le_rand(uint8_t random_number[8])
Wolfgang Betz 132:51056160fa4a 657 {
Wolfgang Betz 132:51056160fa4a 658 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 659 le_rand_rp resp;
Wolfgang Betz 132:51056160fa4a 660
Wolfgang Betz 132:51056160fa4a 661 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 662
Wolfgang Betz 132:51056160fa4a 663 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 664 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 665 rq.ocf = OCF_LE_RAND;
Wolfgang Betz 132:51056160fa4a 666 rq.cparam = NULL;
Wolfgang Betz 132:51056160fa4a 667 rq.clen = 0;
Wolfgang Betz 132:51056160fa4a 668 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 669 rq.rlen = LE_RAND_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 670
Wolfgang Betz 132:51056160fa4a 671 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 672 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 673
Wolfgang Betz 132:51056160fa4a 674 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 675 return resp.status;
Wolfgang Betz 132:51056160fa4a 676 }
Wolfgang Betz 132:51056160fa4a 677
Wolfgang Betz 132:51056160fa4a 678 Osal_MemCpy(random_number, resp.random, 8);
Wolfgang Betz 132:51056160fa4a 679
Wolfgang Betz 132:51056160fa4a 680 return 0;
Wolfgang Betz 132:51056160fa4a 681 }
Wolfgang Betz 132:51056160fa4a 682
Wolfgang Betz 132:51056160fa4a 683 int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[])
Wolfgang Betz 132:51056160fa4a 684 {
Wolfgang Betz 132:51056160fa4a 685 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 686 le_set_scan_response_data_cp scan_resp_cp;
Wolfgang Betz 132:51056160fa4a 687 uint8_t status;
Wolfgang Betz 132:51056160fa4a 688
Wolfgang Betz 132:51056160fa4a 689 Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp));
Wolfgang Betz 132:51056160fa4a 690 scan_resp_cp.length = length;
Wolfgang Betz 132:51056160fa4a 691 Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length));
Wolfgang Betz 132:51056160fa4a 692
Wolfgang Betz 132:51056160fa4a 693 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 694 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 695 rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA;
Wolfgang Betz 132:51056160fa4a 696 rq.cparam = &scan_resp_cp;
Wolfgang Betz 132:51056160fa4a 697 rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 698 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 699 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 700
Wolfgang Betz 132:51056160fa4a 701 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 702 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 703
Wolfgang Betz 132:51056160fa4a 704 return status;
Wolfgang Betz 132:51056160fa4a 705 }
Wolfgang Betz 132:51056160fa4a 706
Wolfgang Betz 132:51056160fa4a 707 int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level)
Wolfgang Betz 132:51056160fa4a 708 {
Wolfgang Betz 132:51056160fa4a 709 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 710 le_read_adv_channel_tx_power_rp resp;
Wolfgang Betz 132:51056160fa4a 711
Wolfgang Betz 132:51056160fa4a 712 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 713
Wolfgang Betz 132:51056160fa4a 714 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 715 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 716 rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER;
Wolfgang Betz 132:51056160fa4a 717 rq.cparam = NULL;
Wolfgang Betz 132:51056160fa4a 718 rq.clen = 0;
Wolfgang Betz 132:51056160fa4a 719 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 720 rq.rlen = LE_RAND_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 721
Wolfgang Betz 132:51056160fa4a 722 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 723 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 724
Wolfgang Betz 132:51056160fa4a 725 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 726 return resp.status;
Wolfgang Betz 132:51056160fa4a 727 }
Wolfgang Betz 132:51056160fa4a 728
Wolfgang Betz 132:51056160fa4a 729 *tx_power_level = resp.level;
Wolfgang Betz 132:51056160fa4a 730
Wolfgang Betz 132:51056160fa4a 731 return 0;
Wolfgang Betz 132:51056160fa4a 732 }
Wolfgang Betz 132:51056160fa4a 733
Wolfgang Betz 132:51056160fa4a 734 int hci_le_set_random_address(tBDAddr bdaddr)
Wolfgang Betz 132:51056160fa4a 735 {
Wolfgang Betz 132:51056160fa4a 736 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 737 le_set_random_address_cp set_rand_addr_cp;
Wolfgang Betz 132:51056160fa4a 738 uint8_t status;
Wolfgang Betz 132:51056160fa4a 739
Wolfgang Betz 132:51056160fa4a 740 Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp));
Wolfgang Betz 132:51056160fa4a 741 Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr));
Wolfgang Betz 132:51056160fa4a 742
Wolfgang Betz 132:51056160fa4a 743 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 744 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 745 rq.ocf = OCF_LE_SET_RANDOM_ADDRESS;
Wolfgang Betz 132:51056160fa4a 746 rq.cparam = &set_rand_addr_cp;
Wolfgang Betz 132:51056160fa4a 747 rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 748 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 749 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 750
Wolfgang Betz 132:51056160fa4a 751 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 752 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 753
Wolfgang Betz 132:51056160fa4a 754 return status;
Wolfgang Betz 132:51056160fa4a 755 }
Wolfgang Betz 132:51056160fa4a 756
Wolfgang Betz 132:51056160fa4a 757 int hci_read_bd_addr(tBDAddr bdaddr)
Wolfgang Betz 132:51056160fa4a 758 {
Wolfgang Betz 132:51056160fa4a 759 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 760 read_bd_addr_rp resp;
Wolfgang Betz 132:51056160fa4a 761
Wolfgang Betz 132:51056160fa4a 762 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 763
Wolfgang Betz 132:51056160fa4a 764 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 765 rq.ogf = OGF_INFO_PARAM;
Wolfgang Betz 132:51056160fa4a 766 rq.ocf = OCF_READ_BD_ADDR;
Wolfgang Betz 132:51056160fa4a 767 rq.cparam = NULL;
Wolfgang Betz 132:51056160fa4a 768 rq.clen = 0;
Wolfgang Betz 132:51056160fa4a 769 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 770 rq.rlen = READ_BD_ADDR_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 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 776 return resp.status;
Wolfgang Betz 132:51056160fa4a 777 }
Wolfgang Betz 132:51056160fa4a 778 Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr));
Wolfgang Betz 132:51056160fa4a 779
Wolfgang Betz 132:51056160fa4a 780 return 0;
Wolfgang Betz 132:51056160fa4a 781 }
Wolfgang Betz 132:51056160fa4a 782
Wolfgang Betz 132:51056160fa4a 783 int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type,
Wolfgang Betz 132:51056160fa4a 784 const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval,
Wolfgang Betz 132:51056160fa4a 785 uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length)
Wolfgang Betz 132:51056160fa4a 786 {
Wolfgang Betz 132:51056160fa4a 787 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 788 le_create_connection_cp create_cp;
Wolfgang Betz 132:51056160fa4a 789 uint8_t status;
Wolfgang Betz 132:51056160fa4a 790
Wolfgang Betz 132:51056160fa4a 791 Osal_MemSet(&create_cp, 0, sizeof(create_cp));
Wolfgang Betz 132:51056160fa4a 792 create_cp.interval = interval;
Wolfgang Betz 132:51056160fa4a 793 create_cp.window = window;
Wolfgang Betz 132:51056160fa4a 794 create_cp.initiator_filter = initiator_filter;
Wolfgang Betz 132:51056160fa4a 795 create_cp.peer_bdaddr_type = peer_bdaddr_type;
Wolfgang Betz 132:51056160fa4a 796 Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr));
Wolfgang Betz 132:51056160fa4a 797 create_cp.own_bdaddr_type = own_bdaddr_type;
Wolfgang Betz 132:51056160fa4a 798 create_cp.min_interval=min_interval;
Wolfgang Betz 132:51056160fa4a 799 create_cp.max_interval=max_interval;
Wolfgang Betz 132:51056160fa4a 800 create_cp.latency = latency;
Wolfgang Betz 132:51056160fa4a 801 create_cp.supervision_timeout=supervision_timeout;
Wolfgang Betz 132:51056160fa4a 802 create_cp.min_ce_length=min_ce_length;
Wolfgang Betz 132:51056160fa4a 803 create_cp.max_ce_length=max_ce_length;
Wolfgang Betz 132:51056160fa4a 804
Wolfgang Betz 132:51056160fa4a 805 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 806 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 807 rq.ocf = OCF_LE_CREATE_CONN;
Wolfgang Betz 132:51056160fa4a 808 rq.cparam = &create_cp;
Wolfgang Betz 132:51056160fa4a 809 rq.clen = LE_CREATE_CONN_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 810 rq.event = EVT_CMD_STATUS;
Wolfgang Betz 132:51056160fa4a 811 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 812 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 813
Wolfgang Betz 132:51056160fa4a 814 if (hci_send_req(&rq, FALSE) < 0)
Wolfgang Betz 132:51056160fa4a 815 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 816
Wolfgang Betz 132:51056160fa4a 817 return status;
Wolfgang Betz 132:51056160fa4a 818 }
Wolfgang Betz 132:51056160fa4a 819
Wolfgang Betz 132:51056160fa4a 820 int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16])
Wolfgang Betz 132:51056160fa4a 821 {
Wolfgang Betz 132:51056160fa4a 822 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 823 le_encrypt_cp params;
Wolfgang Betz 132:51056160fa4a 824 le_encrypt_rp resp;
Wolfgang Betz 132:51056160fa4a 825
Wolfgang Betz 132:51056160fa4a 826 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 827
Wolfgang Betz 132:51056160fa4a 828 Osal_MemCpy(params.key, key, 16);
Wolfgang Betz 132:51056160fa4a 829 Osal_MemCpy(params.plaintext, plaintextData, 16);
Wolfgang Betz 132:51056160fa4a 830
Wolfgang Betz 132:51056160fa4a 831 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 832 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 833 rq.ocf = OCF_LE_ENCRYPT;
Wolfgang Betz 132:51056160fa4a 834 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 835 rq.clen = LE_ENCRYPT_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 836 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 837 rq.rlen = LE_ENCRYPT_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 838
Wolfgang Betz 132:51056160fa4a 839 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 840 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 841 }
Wolfgang Betz 132:51056160fa4a 842
Wolfgang Betz 132:51056160fa4a 843 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 844 return resp.status;
Wolfgang Betz 132:51056160fa4a 845 }
Wolfgang Betz 132:51056160fa4a 846
Wolfgang Betz 132:51056160fa4a 847 Osal_MemCpy(encryptedData, resp.encdata, 16);
Wolfgang Betz 132:51056160fa4a 848
Wolfgang Betz 132:51056160fa4a 849 return 0;
Wolfgang Betz 132:51056160fa4a 850 }
Wolfgang Betz 132:51056160fa4a 851
Wolfgang Betz 132:51056160fa4a 852 int hci_le_ltk_request_reply(uint8_t key[16])
Wolfgang Betz 132:51056160fa4a 853 {
Wolfgang Betz 132:51056160fa4a 854 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 855 le_ltk_reply_cp params;
Wolfgang Betz 132:51056160fa4a 856 le_ltk_reply_rp resp;
Wolfgang Betz 132:51056160fa4a 857
Wolfgang Betz 132:51056160fa4a 858 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 859
Wolfgang Betz 132:51056160fa4a 860 params.handle = 1;
Wolfgang Betz 132:51056160fa4a 861 Osal_MemCpy(params.key, key, 16);
Wolfgang Betz 132:51056160fa4a 862
Wolfgang Betz 132:51056160fa4a 863 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 864 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 865 rq.ocf = OCF_LE_LTK_REPLY;
Wolfgang Betz 132:51056160fa4a 866 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 867 rq.clen = LE_LTK_REPLY_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 868 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 869 rq.rlen = LE_LTK_REPLY_RP_SIZE;
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 return resp.status;
Wolfgang Betz 132:51056160fa4a 875 }
Wolfgang Betz 132:51056160fa4a 876
Wolfgang Betz 132:51056160fa4a 877 int hci_le_ltk_request_neg_reply()
Wolfgang Betz 132:51056160fa4a 878 {
Wolfgang Betz 132:51056160fa4a 879 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 880 le_ltk_neg_reply_cp params;
Wolfgang Betz 132:51056160fa4a 881 le_ltk_neg_reply_rp resp;
Wolfgang Betz 132:51056160fa4a 882
Wolfgang Betz 132:51056160fa4a 883 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 884
Wolfgang Betz 132:51056160fa4a 885 params.handle = 1;
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_LTK_NEG_REPLY;
Wolfgang Betz 132:51056160fa4a 890 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 891 rq.clen = LE_LTK_NEG_REPLY_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 892 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 893 rq.rlen = LE_LTK_NEG_REPLY_RP_SIZE;
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 return resp.status;
Wolfgang Betz 132:51056160fa4a 899 }
Wolfgang Betz 132:51056160fa4a 900
Wolfgang Betz 132:51056160fa4a 901 int hci_le_read_white_list_size(uint8_t *size)
Wolfgang Betz 132:51056160fa4a 902 {
Wolfgang Betz 132:51056160fa4a 903 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 904 le_read_white_list_size_rp resp;
Wolfgang Betz 132:51056160fa4a 905
Wolfgang Betz 132:51056160fa4a 906 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 907
Wolfgang Betz 132:51056160fa4a 908 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 909 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 910 rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
Wolfgang Betz 132:51056160fa4a 911 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 912 rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 913
Wolfgang Betz 132:51056160fa4a 914 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 915 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 916 }
Wolfgang Betz 132:51056160fa4a 917
Wolfgang Betz 132:51056160fa4a 918 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 919 return resp.status;
Wolfgang Betz 132:51056160fa4a 920 }
Wolfgang Betz 132:51056160fa4a 921
Wolfgang Betz 132:51056160fa4a 922 *size = resp.size;
Wolfgang Betz 132:51056160fa4a 923
Wolfgang Betz 132:51056160fa4a 924 return 0;
Wolfgang Betz 132:51056160fa4a 925 }
Wolfgang Betz 132:51056160fa4a 926
Wolfgang Betz 132:51056160fa4a 927 int hci_le_clear_white_list()
Wolfgang Betz 132:51056160fa4a 928 {
Wolfgang Betz 132:51056160fa4a 929 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 930 uint8_t status;
Wolfgang Betz 132:51056160fa4a 931
Wolfgang Betz 132:51056160fa4a 932 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 933 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 934 rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
Wolfgang Betz 132:51056160fa4a 935 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 936 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 937
Wolfgang Betz 132:51056160fa4a 938 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 939 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 940 }
Wolfgang Betz 132:51056160fa4a 941
Wolfgang Betz 132:51056160fa4a 942 return status;
Wolfgang Betz 132:51056160fa4a 943 }
Wolfgang Betz 132:51056160fa4a 944
Wolfgang Betz 132:51056160fa4a 945 int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr)
Wolfgang Betz 132:51056160fa4a 946 {
Wolfgang Betz 132:51056160fa4a 947 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 948 le_add_device_to_white_list_cp params;
Wolfgang Betz 132:51056160fa4a 949 uint8_t status;
Wolfgang Betz 132:51056160fa4a 950
Wolfgang Betz 132:51056160fa4a 951 params.bdaddr_type = bdaddr_type;
Wolfgang Betz 132:51056160fa4a 952 Osal_MemCpy(params.bdaddr, bdaddr, 6);
Wolfgang Betz 132:51056160fa4a 953
Wolfgang Betz 132:51056160fa4a 954 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 955 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 956 rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
Wolfgang Betz 132:51056160fa4a 957 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 958 rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 959 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 960 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 961
Wolfgang Betz 132:51056160fa4a 962 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 963 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 964 }
Wolfgang Betz 132:51056160fa4a 965
Wolfgang Betz 132:51056160fa4a 966 return status;
Wolfgang Betz 132:51056160fa4a 967 }
Wolfgang Betz 132:51056160fa4a 968
Wolfgang Betz 132:51056160fa4a 969 int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr)
Wolfgang Betz 132:51056160fa4a 970 {
Wolfgang Betz 132:51056160fa4a 971 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 972 le_remove_device_from_white_list_cp params;
Wolfgang Betz 132:51056160fa4a 973 uint8_t status;
Wolfgang Betz 132:51056160fa4a 974
Wolfgang Betz 132:51056160fa4a 975 params.bdaddr_type = bdaddr_type;
Wolfgang Betz 132:51056160fa4a 976 Osal_MemCpy(params.bdaddr, bdaddr, 6);
Wolfgang Betz 132:51056160fa4a 977
Wolfgang Betz 132:51056160fa4a 978 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 979 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 980 rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
Wolfgang Betz 132:51056160fa4a 981 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 982 rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 983 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 984 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 985
Wolfgang Betz 132:51056160fa4a 986 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 987 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 988 }
Wolfgang Betz 132:51056160fa4a 989
Wolfgang Betz 132:51056160fa4a 990 return status;
Wolfgang Betz 132:51056160fa4a 991 }
Wolfgang Betz 132:51056160fa4a 992
Wolfgang Betz 132:51056160fa4a 993 int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level)
Wolfgang Betz 132:51056160fa4a 994 {
Wolfgang Betz 132:51056160fa4a 995 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 996 read_transmit_power_level_cp params;
Wolfgang Betz 132:51056160fa4a 997 read_transmit_power_level_rp resp;
Wolfgang Betz 132:51056160fa4a 998
Wolfgang Betz 132:51056160fa4a 999 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 1000
Wolfgang Betz 132:51056160fa4a 1001 params.handle = *conn_handle;
Wolfgang Betz 132:51056160fa4a 1002 params.type = type;
Wolfgang Betz 132:51056160fa4a 1003
Wolfgang Betz 132:51056160fa4a 1004 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 1005 rq.ogf = OGF_HOST_CTL;
Wolfgang Betz 132:51056160fa4a 1006 rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL;
Wolfgang Betz 132:51056160fa4a 1007 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 1008 rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 1009 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 1010 rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 1011
Wolfgang Betz 132:51056160fa4a 1012 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 1013 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 1014 }
Wolfgang Betz 132:51056160fa4a 1015
Wolfgang Betz 132:51056160fa4a 1016 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 1017 return resp.status;
Wolfgang Betz 132:51056160fa4a 1018 }
Wolfgang Betz 132:51056160fa4a 1019
Wolfgang Betz 132:51056160fa4a 1020 *conn_handle = resp.handle;
Wolfgang Betz 132:51056160fa4a 1021 *tx_level = resp.level;
Wolfgang Betz 132:51056160fa4a 1022
Wolfgang Betz 132:51056160fa4a 1023 return 0;
Wolfgang Betz 132:51056160fa4a 1024 }
Wolfgang Betz 132:51056160fa4a 1025
Wolfgang Betz 132:51056160fa4a 1026 int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi)
Wolfgang Betz 132:51056160fa4a 1027 {
Wolfgang Betz 132:51056160fa4a 1028 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 1029 read_rssi_cp params;
Wolfgang Betz 132:51056160fa4a 1030 read_rssi_rp resp;
Wolfgang Betz 132:51056160fa4a 1031
Wolfgang Betz 132:51056160fa4a 1032 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 1033
Wolfgang Betz 132:51056160fa4a 1034 params.handle = *conn_handle;
Wolfgang Betz 132:51056160fa4a 1035
Wolfgang Betz 132:51056160fa4a 1036 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 1037 rq.ogf = OGF_STATUS_PARAM;
Wolfgang Betz 132:51056160fa4a 1038 rq.ocf = OCF_READ_RSSI;
Wolfgang Betz 132:51056160fa4a 1039 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 1040 rq.clen = READ_RSSI_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 1041 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 1042 rq.rlen = READ_RSSI_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 1043
Wolfgang Betz 132:51056160fa4a 1044 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 1045 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 1046 }
Wolfgang Betz 132:51056160fa4a 1047
Wolfgang Betz 132:51056160fa4a 1048 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 1049 return resp.status;
Wolfgang Betz 132:51056160fa4a 1050 }
Wolfgang Betz 132:51056160fa4a 1051
Wolfgang Betz 132:51056160fa4a 1052 *conn_handle = resp.handle;
Wolfgang Betz 132:51056160fa4a 1053 *rssi = resp.rssi;
Wolfgang Betz 132:51056160fa4a 1054
Wolfgang Betz 132:51056160fa4a 1055 return 0;
Wolfgang Betz 132:51056160fa4a 1056 }
Wolfgang Betz 132:51056160fa4a 1057
Wolfgang Betz 132:51056160fa4a 1058 int hci_le_read_local_supported_features(uint8_t *features)
Wolfgang Betz 132:51056160fa4a 1059 {
Wolfgang Betz 132:51056160fa4a 1060 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 1061 le_read_local_supported_features_rp resp;
Wolfgang Betz 132:51056160fa4a 1062
Wolfgang Betz 132:51056160fa4a 1063 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 1064
Wolfgang Betz 132:51056160fa4a 1065 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 1066 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 1067 rq.ocf = OCF_LE_READ_LOCAL_SUPPORTED_FEATURES;
Wolfgang Betz 132:51056160fa4a 1068 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 1069 rq.rlen = LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 1070
Wolfgang Betz 132:51056160fa4a 1071 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 1072 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 1073 }
Wolfgang Betz 132:51056160fa4a 1074
Wolfgang Betz 132:51056160fa4a 1075 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 1076 return resp.status;
Wolfgang Betz 132:51056160fa4a 1077 }
Wolfgang Betz 132:51056160fa4a 1078
Wolfgang Betz 132:51056160fa4a 1079 Osal_MemCpy(features, resp.features, sizeof(resp.features));
Wolfgang Betz 132:51056160fa4a 1080
Wolfgang Betz 132:51056160fa4a 1081 return 0;
Wolfgang Betz 132:51056160fa4a 1082 }
Wolfgang Betz 132:51056160fa4a 1083
Wolfgang Betz 132:51056160fa4a 1084 int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5])
Wolfgang Betz 132:51056160fa4a 1085 {
Wolfgang Betz 132:51056160fa4a 1086 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 1087 le_read_channel_map_cp params;
Wolfgang Betz 132:51056160fa4a 1088 le_read_channel_map_rp resp;
Wolfgang Betz 132:51056160fa4a 1089
Wolfgang Betz 132:51056160fa4a 1090 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 1091
Wolfgang Betz 132:51056160fa4a 1092 params.handle = conn_handle;
Wolfgang Betz 132:51056160fa4a 1093
Wolfgang Betz 132:51056160fa4a 1094 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 1095 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 1096 rq.ocf = OCF_LE_READ_CHANNEL_MAP;
Wolfgang Betz 132:51056160fa4a 1097 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 1098 rq.clen = LE_READ_CHANNEL_MAP_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 1099 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 1100 rq.rlen = LE_READ_CHANNEL_MAP_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 1101
Wolfgang Betz 132:51056160fa4a 1102 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 1103 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 1104 }
Wolfgang Betz 132:51056160fa4a 1105
Wolfgang Betz 132:51056160fa4a 1106 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 1107 return resp.status;
Wolfgang Betz 132:51056160fa4a 1108 }
Wolfgang Betz 132:51056160fa4a 1109
Wolfgang Betz 132:51056160fa4a 1110 Osal_MemCpy(ch_map, resp.map, 5);
Wolfgang Betz 132:51056160fa4a 1111
Wolfgang Betz 132:51056160fa4a 1112 return 0;
Wolfgang Betz 132:51056160fa4a 1113 }
Wolfgang Betz 132:51056160fa4a 1114
Wolfgang Betz 132:51056160fa4a 1115 int hci_le_read_supported_states(uint8_t states[8])
Wolfgang Betz 132:51056160fa4a 1116 {
Wolfgang Betz 132:51056160fa4a 1117 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 1118 le_read_supported_states_rp resp;
Wolfgang Betz 132:51056160fa4a 1119
Wolfgang Betz 132:51056160fa4a 1120 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 1121
Wolfgang Betz 132:51056160fa4a 1122 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 1123 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 1124 rq.ocf = OCF_LE_READ_SUPPORTED_STATES;
Wolfgang Betz 132:51056160fa4a 1125 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 1126 rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 1127
Wolfgang Betz 132:51056160fa4a 1128 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 1129 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 1130 }
Wolfgang Betz 132:51056160fa4a 1131
Wolfgang Betz 132:51056160fa4a 1132 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 1133 return resp.status;
Wolfgang Betz 132:51056160fa4a 1134 }
Wolfgang Betz 132:51056160fa4a 1135
Wolfgang Betz 132:51056160fa4a 1136 Osal_MemCpy(states, resp.states, 8);
Wolfgang Betz 132:51056160fa4a 1137
Wolfgang Betz 132:51056160fa4a 1138 return 0;
Wolfgang Betz 132:51056160fa4a 1139 }
Wolfgang Betz 132:51056160fa4a 1140
Wolfgang Betz 132:51056160fa4a 1141 int hci_le_receiver_test(uint8_t frequency)
Wolfgang Betz 132:51056160fa4a 1142 {
Wolfgang Betz 132:51056160fa4a 1143 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 1144 le_receiver_test_cp params;
Wolfgang Betz 132:51056160fa4a 1145 uint8_t status;
Wolfgang Betz 132:51056160fa4a 1146
Wolfgang Betz 132:51056160fa4a 1147 params.frequency = frequency;
Wolfgang Betz 132:51056160fa4a 1148
Wolfgang Betz 132:51056160fa4a 1149 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 1150 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 1151 rq.ocf = OCF_LE_RECEIVER_TEST;
Wolfgang Betz 132:51056160fa4a 1152 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 1153 rq.clen = LE_RECEIVER_TEST_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 1154 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 1155 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 1156
Wolfgang Betz 132:51056160fa4a 1157 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 1158 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 1159 }
Wolfgang Betz 132:51056160fa4a 1160
Wolfgang Betz 132:51056160fa4a 1161 return status;
Wolfgang Betz 132:51056160fa4a 1162 }
Wolfgang Betz 132:51056160fa4a 1163
Wolfgang Betz 132:51056160fa4a 1164 int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload)
Wolfgang Betz 132:51056160fa4a 1165 {
Wolfgang Betz 132:51056160fa4a 1166 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 1167 le_transmitter_test_cp params;
Wolfgang Betz 132:51056160fa4a 1168 uint8_t status;
Wolfgang Betz 132:51056160fa4a 1169
Wolfgang Betz 132:51056160fa4a 1170 params.frequency = frequency;
Wolfgang Betz 132:51056160fa4a 1171 params.length = length;
Wolfgang Betz 132:51056160fa4a 1172 params.payload = payload;
Wolfgang Betz 132:51056160fa4a 1173
Wolfgang Betz 132:51056160fa4a 1174 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 1175 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 1176 rq.ocf = OCF_LE_TRANSMITTER_TEST;
Wolfgang Betz 132:51056160fa4a 1177 rq.cparam = &params;
Wolfgang Betz 132:51056160fa4a 1178 rq.clen = LE_TRANSMITTER_TEST_CP_SIZE;
Wolfgang Betz 132:51056160fa4a 1179 rq.rparam = &status;
Wolfgang Betz 132:51056160fa4a 1180 rq.rlen = 1;
Wolfgang Betz 132:51056160fa4a 1181
Wolfgang Betz 132:51056160fa4a 1182 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 1183 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 1184 }
Wolfgang Betz 132:51056160fa4a 1185
Wolfgang Betz 132:51056160fa4a 1186 return status;
Wolfgang Betz 132:51056160fa4a 1187 }
Wolfgang Betz 132:51056160fa4a 1188
Wolfgang Betz 132:51056160fa4a 1189 int hci_le_test_end(uint16_t *num_pkts)
Wolfgang Betz 132:51056160fa4a 1190 {
Wolfgang Betz 132:51056160fa4a 1191 struct hci_request rq;
Wolfgang Betz 132:51056160fa4a 1192 le_test_end_rp resp;
Wolfgang Betz 132:51056160fa4a 1193
Wolfgang Betz 132:51056160fa4a 1194 Osal_MemSet(&resp, 0, sizeof(resp));
Wolfgang Betz 132:51056160fa4a 1195
Wolfgang Betz 132:51056160fa4a 1196 Osal_MemSet(&rq, 0, sizeof(rq));
Wolfgang Betz 132:51056160fa4a 1197 rq.ogf = OGF_LE_CTL;
Wolfgang Betz 132:51056160fa4a 1198 rq.ocf = OCF_LE_TEST_END;
Wolfgang Betz 132:51056160fa4a 1199 rq.rparam = &resp;
Wolfgang Betz 132:51056160fa4a 1200 rq.rlen = LE_TEST_END_RP_SIZE;
Wolfgang Betz 132:51056160fa4a 1201
Wolfgang Betz 132:51056160fa4a 1202 if (hci_send_req(&rq, FALSE) < 0){
Wolfgang Betz 132:51056160fa4a 1203 return BLE_STATUS_TIMEOUT;
Wolfgang Betz 132:51056160fa4a 1204 }
Wolfgang Betz 132:51056160fa4a 1205
Wolfgang Betz 132:51056160fa4a 1206 if (resp.status) {
Wolfgang Betz 132:51056160fa4a 1207 return resp.status;
Wolfgang Betz 132:51056160fa4a 1208 }
Wolfgang Betz 132:51056160fa4a 1209
Wolfgang Betz 132:51056160fa4a 1210 *num_pkts = resp.num_pkts;
Wolfgang Betz 132:51056160fa4a 1211
Wolfgang Betz 132:51056160fa4a 1212 return 0;
Wolfgang Betz 132:51056160fa4a 1213 }
Wolfgang Betz 132:51056160fa4a 1214