Previous version which works for my stm32f401 Nucleo board

Fork of X_NUCLEO_IDB0XA1 by ST

Committer:
Wolfgang Betz
Date:
Wed Jul 22 11:25:50 2015 +0200
Revision:
90:26c0c9807ab4
Child:
91:97c0c21046b4
Preparing ble_wb

- new gitmodule for BLE_API
- updating ReadMe.txt
- synching X_NUCLEO_IDB0XA1 with mbed
- synching test application

Who changed what in which revision?

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