HW layer for the Nucleo board, it only work with old BLE_API

Dependents:   Hello_BLE F446RE-BLE

Fork of X_NUCLEO_IDB0XA1 by ST

Committer:
Silvio Lucio Oliva
Date:
Mon Jun 08 17:08:01 2015 +0200
Revision:
70:d20d30f59b1c
Child:
74:c4526f8284d5
Initial commit for mbed support

Signed-off-by: Silvio Lucio Oliva <silvio.oliva@st.com>

Who changed what in which revision?

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