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