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