my fork
Embed:
(wiki syntax)
Show/hide line numbers
hci.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file hci.c 00004 * @author AMS/HESA Application Team 00005 * @brief Function for managing HCI interface. 00006 ****************************************************************************** 00007 * 00008 * 00009 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 00010 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 00011 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 00012 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 00013 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 00014 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 00015 * 00016 * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> 00017 */ 00018 00019 #include "hal_types.h" 00020 #include "osal.h" 00021 #include "ble_status.h" 00022 #include "hal.h" 00023 #include "hci_const.h" 00024 #include "gp_timer.h" 00025 00026 #include "stm32_bluenrg_ble.h " 00027 00028 extern SPI_HandleTypeDef SpiHandle; 00029 00030 #if BLE_CONFIG_DBG_ENABLE 00031 #define PRINTF(...) printf(__VA_ARGS__) 00032 #else 00033 #define PRINTF(...) 00034 #endif 00035 00036 #define HCI_LOG_ON 0 00037 00038 #define HCI_READ_PACKET_NUM_MAX (5) 00039 00040 #define MIN(a,b) ((a) < (b) )? (a) : (b) 00041 #define MAX(a,b) ((a) > (b) )? (a) : (b) 00042 00043 static void enqueue_packet(tHciDataPacket * hciReadPacket); 00044 00045 tListNode hciReadPktPool; 00046 tListNode hciReadPktRxQueue; 00047 /* pool of hci read packets */ 00048 static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; 00049 00050 static uint8_t *hci_buffer = NULL; 00051 static volatile uint16_t hci_pckt_len; 00052 00053 volatile uint8_t readPacketListFull=FALSE; 00054 00055 void HCI_Init(void) 00056 { 00057 uint8_t index; 00058 00059 /* Initialize list heads of ready and free hci data packet queues */ 00060 list_init_head (&hciReadPktPool); 00061 list_init_head (&hciReadPktRxQueue); 00062 00063 /* Initialize the queue of free hci data packets */ 00064 for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) 00065 { 00066 list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); 00067 } 00068 } 00069 00070 static volatile hci_packet_complete_callback packet_complete_callback = NULL; 00071 00072 static void hci_set_packet_complete_callback(hci_packet_complete_callback cb) 00073 { 00074 packet_complete_callback = cb; 00075 } 00076 00077 void HCI_Input(tHciDataPacket * hciReadPacket) 00078 { 00079 uint8_t byte; 00080 hci_acl_hdr *acl_hdr; 00081 00082 static hci_state state = WAITING_TYPE; 00083 00084 uint16_t collected_payload_len = 0; 00085 uint16_t payload_len; 00086 00087 hci_buffer = hciReadPacket->dataBuff; 00088 00089 if(state == WAITING_TYPE) 00090 hci_pckt_len = 0; 00091 00092 while(hci_pckt_len < HCI_PACKET_SIZE){ 00093 00094 byte = hci_buffer[hci_pckt_len++]; 00095 00096 if(state == WAITING_TYPE){ 00097 /* Only ACL Data and Events packets are accepted. */ 00098 if(byte == HCI_EVENT_PKT){ 00099 state = WAITING_EVENT_CODE; 00100 } 00101 // else if(byte == HCI_ACLDATA_PKT){ 00102 // state = WAITING_HANDLE; 00103 // } 00104 else{ 00105 /* Incorrect type. Reset state machine. */ 00106 state = WAITING_TYPE; 00107 break; 00108 } 00109 } 00110 else if(state == WAITING_EVENT_CODE) 00111 state = WAITING_PARAM_LEN; 00112 else if(state == WAITING_HANDLE) 00113 state = WAITING_HANDLE_FLAG; 00114 else if(state == WAITING_HANDLE_FLAG) 00115 state = WAITING_DATA_LEN1; 00116 else if(state == WAITING_DATA_LEN1) 00117 state = WAITING_DATA_LEN2; 00118 00119 else if(state == WAITING_DATA_LEN2){ 00120 acl_hdr = (void *)&hci_buffer[HCI_HDR_SIZE]; 00121 payload_len = acl_hdr->dlen; 00122 collected_payload_len = 0; 00123 state = WAITING_PAYLOAD; 00124 } 00125 else if(state == WAITING_PARAM_LEN){ 00126 payload_len = byte; 00127 collected_payload_len = 0; 00128 state = WAITING_PAYLOAD; 00129 } 00130 else if(state == WAITING_PAYLOAD){ 00131 collected_payload_len += 1; 00132 if(collected_payload_len >= payload_len){ 00133 /* Reset state machine. */ 00134 state = WAITING_TYPE; 00135 enqueue_packet(hciReadPacket); 00136 00137 if(packet_complete_callback){ 00138 uint16_t len = hci_pckt_len; 00139 packet_complete_callback(hci_buffer, len); 00140 } 00141 break; 00142 } 00143 } 00144 } 00145 } 00146 00147 void enqueue_packet(tHciDataPacket * hciReadPacket) 00148 { 00149 hci_uart_pckt *hci_pckt = (void*)hciReadPacket->dataBuff; 00150 hci_event_pckt *event_pckt = (void*)hci_pckt->data; 00151 00152 // Do not enqueue Command Complete or Command Status events 00153 00154 if((hci_pckt->type != HCI_EVENT_PKT) || 00155 event_pckt->evt == EVT_CMD_COMPLETE || 00156 event_pckt->evt == EVT_CMD_STATUS){ 00157 // Insert the packet back into the pool. 00158 list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); 00159 } 00160 else { 00161 // Insert the packet into the queue of events to be processed. 00162 list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); 00163 } 00164 } 00165 00166 void HCI_Process(void) 00167 { 00168 uint8_t data_len; 00169 uint8_t buffer[HCI_PACKET_SIZE]; 00170 tHciDataPacket * hciReadPacket = NULL; 00171 00172 Disable_SPI_IRQ(); 00173 uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); 00174 /* process any pending events read */ 00175 while(list_empty == FALSE) 00176 { 00177 list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); 00178 Enable_SPI_IRQ(); 00179 HCI_Event_CB(hciReadPacket->dataBuff); 00180 Disable_SPI_IRQ(); 00181 list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); 00182 list_empty = list_is_empty(&hciReadPktRxQueue); 00183 } 00184 if (readPacketListFull) { 00185 while(BlueNRG_DataPresent()) { 00186 data_len = BlueNRG_SPI_Read_All(&SpiHandle, buffer, HCI_PACKET_SIZE); 00187 if(data_len > 0) 00188 HCI_Event_CB(buffer); 00189 } 00190 readPacketListFull = FALSE; 00191 } 00192 00193 Enable_SPI_IRQ(); 00194 } 00195 00196 void HCI_Isr(void) 00197 { 00198 tHciDataPacket * hciReadPacket = NULL; 00199 uint8_t data_len; 00200 00201 Clear_SPI_EXTI_Flag(); 00202 while(BlueNRG_DataPresent()){ 00203 if (list_is_empty (&hciReadPktPool) == FALSE){ 00204 00205 /* enqueueing a packet for read */ 00206 list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); 00207 00208 data_len = BlueNRG_SPI_Read_All(&SpiHandle, hciReadPacket->dataBuff, HCI_PACKET_SIZE); 00209 if(data_len > 0){ 00210 HCI_Input(hciReadPacket); 00211 // Packet will be inserted to te correct queue by 00212 } 00213 else { 00214 // Insert the packet back into the pool. 00215 list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); 00216 } 00217 00218 } 00219 else{ 00220 // HCI Read Packet Pool is empty, wait for a free packet. 00221 readPacketListFull = TRUE; 00222 Clear_SPI_EXTI_Flag(); 00223 return; 00224 } 00225 00226 Clear_SPI_EXTI_Flag(); 00227 } 00228 } 00229 00230 void hci_write(const void* data1, const void* data2, uint16_t n_bytes1, uint16_t n_bytes2){ 00231 #if HCI_LOG_ON 00232 PRINTF("HCI <- "); 00233 for(int i=0; i < n_bytes1; i++) 00234 PRINTF("%02X ", *((uint8_t*)data1 + i)); 00235 for(int i=0; i < n_bytes2; i++) 00236 PRINTF("%02X ", *((uint8_t*)data2 + i)); 00237 PRINTF("\n"); 00238 #endif 00239 00240 Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); 00241 } 00242 00243 int hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) 00244 { 00245 hci_command_hdr hc; 00246 00247 hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); 00248 hc.plen= plen; 00249 00250 uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; 00251 header[0] = HCI_COMMAND_PKT; 00252 Osal_MemCpy(header+1, &hc, sizeof(hc)); 00253 00254 hci_write(header, param, sizeof(header), plen); 00255 00256 return 0; 00257 } 00258 00259 static uint8_t new_packet; 00260 00261 void new_hci_event(void *pckt, uint16_t len) 00262 { 00263 Disable_SPI_IRQ(); /* Must be re-enabled after packet processing. */ 00264 00265 new_packet = TRUE; 00266 } 00267 00268 /* 'to' is timeout in system clock ticks. */ 00269 int hci_send_req(struct hci_request *r) 00270 { 00271 uint8_t *ptr; 00272 uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); 00273 hci_event_pckt *event_pckt; 00274 hci_uart_pckt *hci_hdr; 00275 int try; 00276 int to = DEFAULT_TIMEOUT; 00277 00278 new_packet = FALSE; 00279 hci_set_packet_complete_callback(new_hci_event); 00280 if (hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam) < 0) 00281 goto failed; 00282 00283 try = 10; 00284 while (try--) { 00285 evt_cmd_complete *cc; 00286 evt_cmd_status *cs; 00287 evt_le_meta_event *me; 00288 int len; 00289 00290 /* Minimum timeout is 1. */ 00291 if(to == 0) 00292 to = 1; 00293 00294 if (to > 0) { 00295 struct timer t; 00296 00297 Timer_Set(&t, to); 00298 00299 while(1){ 00300 if(Timer_Expired(&t)){ 00301 goto failed; 00302 } 00303 if(new_packet){ 00304 break; 00305 } 00306 } 00307 } 00308 00309 hci_hdr = (void *)hci_buffer; 00310 if(hci_hdr->type != HCI_EVENT_PKT){ 00311 new_packet = FALSE; 00312 Enable_SPI_IRQ(); 00313 continue; 00314 } 00315 00316 event_pckt = (void *) (hci_hdr->data); 00317 00318 ptr = hci_buffer + (1 + HCI_EVENT_HDR_SIZE); 00319 len = hci_pckt_len - (1 + HCI_EVENT_HDR_SIZE); 00320 00321 switch (event_pckt->evt) { 00322 00323 case EVT_CMD_STATUS: 00324 cs = (void *) ptr; 00325 00326 if (cs->opcode != opcode) 00327 break; 00328 00329 if (r->event != EVT_CMD_STATUS) { 00330 if (cs->status) { 00331 goto failed; 00332 } 00333 break; 00334 } 00335 00336 r->rlen = MIN(len, r->rlen); 00337 Osal_MemCpy(r->rparam, ptr, r->rlen); 00338 goto done; 00339 00340 case EVT_CMD_COMPLETE: 00341 cc = (void *) ptr; 00342 00343 if (cc->opcode != opcode) 00344 break; 00345 00346 ptr += EVT_CMD_COMPLETE_SIZE; 00347 len -= EVT_CMD_COMPLETE_SIZE; 00348 00349 r->rlen = MIN(len, r->rlen); 00350 Osal_MemCpy(r->rparam, ptr, r->rlen); 00351 goto done; 00352 00353 case EVT_LE_META_EVENT: 00354 me = (void *) ptr; 00355 00356 if (me->subevent != r->event) 00357 break; 00358 00359 len -= 1; 00360 r->rlen = MIN(len, r->rlen); 00361 Osal_MemCpy(r->rparam, me->data, r->rlen); 00362 goto done; 00363 00364 case EVT_HARDWARE_ERROR: 00365 goto failed; 00366 00367 default: 00368 break; // In the meantime there could be other events from the controller. 00369 } 00370 00371 new_packet = FALSE; 00372 Enable_SPI_IRQ(); 00373 00374 } 00375 00376 failed: 00377 hci_set_packet_complete_callback(NULL); 00378 Enable_SPI_IRQ(); 00379 return -1; 00380 00381 done: 00382 hci_set_packet_complete_callback(NULL); 00383 Enable_SPI_IRQ(); 00384 return 0; 00385 } 00386 00387 int hci_reset() 00388 { 00389 struct hci_request rq; 00390 uint8_t status; 00391 00392 Osal_MemSet(&rq, 0, sizeof(rq)); 00393 rq.ogf = OGF_HOST_CTL; 00394 rq.ocf = OCF_RESET; 00395 rq.rparam = &status; 00396 rq.rlen = 1; 00397 00398 if (hci_send_req(&rq) < 0) 00399 return -1; 00400 00401 if (status) { 00402 return -1; 00403 } 00404 00405 return 0; 00406 } 00407 00408 int hci_disconnect(uint16_t handle, uint8_t reason) 00409 { 00410 struct hci_request rq; 00411 disconnect_cp cp; 00412 uint8_t status; 00413 00414 cp.handle = handle; 00415 cp.reason = reason; 00416 00417 Osal_MemSet(&rq, 0, sizeof(rq)); 00418 rq.ogf = OGF_LINK_CTL; 00419 rq.ocf = OCF_DISCONNECT; 00420 rq.cparam = &cp; 00421 rq.clen = DISCONNECT_CP_SIZE; 00422 rq.event = EVT_CMD_STATUS; 00423 rq.rparam = &status; 00424 rq.rlen = 1; 00425 00426 if (hci_send_req(&rq) < 0) 00427 return -1; 00428 00429 if (status) { 00430 return -1; 00431 } 00432 00433 return 0; 00434 } 00435 00436 int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, 00437 uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) 00438 { 00439 struct hci_request rq; 00440 read_local_version_rp resp; 00441 00442 Osal_MemSet(&resp, 0, sizeof(resp)); 00443 00444 Osal_MemSet(&rq, 0, sizeof(rq)); 00445 rq.ogf = OGF_INFO_PARAM; 00446 rq.ocf = OCF_READ_LOCAL_VERSION; 00447 rq.cparam = NULL; 00448 rq.clen = 0; 00449 rq.rparam = &resp; 00450 rq.rlen = READ_LOCAL_VERSION_RP_SIZE; 00451 00452 if (hci_send_req(&rq) < 0) 00453 return -1; 00454 00455 if (resp.status) { 00456 return -1; 00457 } 00458 00459 00460 *hci_version = resp.hci_version; 00461 *hci_revision = btohs(resp.hci_revision); 00462 *lmp_pal_version = resp.lmp_pal_version; 00463 *manufacturer_name = btohs(resp.manufacturer_name); 00464 *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); 00465 00466 return 0; 00467 } 00468 00469 int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) 00470 { 00471 struct hci_request rq; 00472 le_read_buffer_size_rp resp; 00473 00474 Osal_MemSet(&resp, 0, sizeof(resp)); 00475 00476 Osal_MemSet(&rq, 0, sizeof(rq)); 00477 rq.ogf = OGF_LE_CTL; 00478 rq.ocf = OCF_LE_READ_BUFFER_SIZE; 00479 rq.cparam = NULL; 00480 rq.clen = 0; 00481 rq.rparam = &resp; 00482 rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; 00483 00484 if (hci_send_req(&rq) < 0) 00485 return -1; 00486 00487 if (resp.status) { 00488 return -1; 00489 } 00490 00491 *pkt_len = resp.pkt_len; 00492 *max_pkt = resp.max_pkt; 00493 00494 return 0; 00495 } 00496 00497 int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, 00498 uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, tBDAddr direct_bdaddr, uint8_t chan_map, 00499 uint8_t filter) 00500 { 00501 struct hci_request rq; 00502 le_set_adv_parameters_cp adv_cp; 00503 uint8_t status; 00504 00505 Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); 00506 adv_cp.min_interval = min_interval; 00507 adv_cp.max_interval = max_interval; 00508 adv_cp.advtype = advtype; 00509 adv_cp.own_bdaddr_type = own_bdaddr_type; 00510 adv_cp.direct_bdaddr_type = direct_bdaddr_type; 00511 Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); 00512 adv_cp.chan_map = chan_map; 00513 adv_cp.filter = filter; 00514 00515 Osal_MemSet(&rq, 0, sizeof(rq)); 00516 rq.ogf = OGF_LE_CTL; 00517 rq.ocf = OCF_LE_SET_ADV_PARAMETERS; 00518 rq.cparam = &adv_cp; 00519 rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; 00520 rq.rparam = &status; 00521 rq.rlen = 1; 00522 00523 if (hci_send_req(&rq) < 0) 00524 return -1; 00525 00526 if (status) { 00527 return -1; 00528 } 00529 00530 return 0; 00531 } 00532 00533 int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) 00534 { 00535 struct hci_request rq; 00536 le_set_adv_data_cp adv_cp; 00537 uint8_t status; 00538 00539 Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); 00540 adv_cp.length = length; 00541 Osal_MemCpy(adv_cp.data, data, MIN(31,length)); 00542 00543 Osal_MemSet(&rq, 0, sizeof(rq)); 00544 rq.ogf = OGF_LE_CTL; 00545 rq.ocf = OCF_LE_SET_ADV_DATA; 00546 rq.cparam = &adv_cp; 00547 rq.clen = LE_SET_ADV_DATA_CP_SIZE; 00548 rq.rparam = &status; 00549 rq.rlen = 1; 00550 00551 if (hci_send_req(&rq) < 0) 00552 return -1; 00553 00554 if (status) { 00555 return -1; 00556 } 00557 00558 return 0; 00559 } 00560 00561 int hci_le_set_advertise_enable(uint8_t enable) 00562 { 00563 struct hci_request rq; 00564 le_set_advertise_enable_cp adv_cp; 00565 uint8_t status; 00566 00567 Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); 00568 adv_cp.enable = enable?1:0; 00569 00570 Osal_MemSet(&rq, 0, sizeof(rq)); 00571 rq.ogf = OGF_LE_CTL; 00572 rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; 00573 rq.cparam = &adv_cp; 00574 rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; 00575 rq.rparam = &status; 00576 rq.rlen = 1; 00577 00578 if (hci_send_req(&rq) < 0) 00579 return -1; 00580 00581 if (status) { 00582 return -1; 00583 } 00584 00585 return 0; 00586 } 00587 00588 int hci_le_rand(uint8_t random_number[8]) 00589 { 00590 struct hci_request rq; 00591 le_rand_rp resp; 00592 00593 Osal_MemSet(&resp, 0, sizeof(resp)); 00594 00595 Osal_MemSet(&rq, 0, sizeof(rq)); 00596 rq.ogf = OGF_LE_CTL; 00597 rq.ocf = OCF_LE_RAND; 00598 rq.cparam = NULL; 00599 rq.clen = 0; 00600 rq.rparam = &resp; 00601 rq.rlen = LE_RAND_RP_SIZE; 00602 00603 if (hci_send_req(&rq) < 0) 00604 return -1; 00605 00606 if (resp.status) { 00607 return -1; 00608 } 00609 00610 Osal_MemCpy(random_number, resp.random, 8); 00611 00612 return 0; 00613 } 00614 00615 int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) 00616 { 00617 struct hci_request rq; 00618 le_set_scan_response_data_cp scan_resp_cp; 00619 uint8_t status; 00620 00621 Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); 00622 scan_resp_cp.length = length; 00623 Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); 00624 00625 Osal_MemSet(&rq, 0, sizeof(rq)); 00626 rq.ogf = OGF_LE_CTL; 00627 rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; 00628 rq.cparam = &scan_resp_cp; 00629 rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; 00630 rq.rparam = &status; 00631 rq.rlen = 1; 00632 00633 if (hci_send_req(&rq) < 0) 00634 return -1; 00635 00636 if (status) { 00637 return -1; 00638 } 00639 00640 return 0; 00641 } 00642 00643 int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) 00644 { 00645 struct hci_request rq; 00646 le_read_adv_channel_tx_power_rp resp; 00647 00648 Osal_MemSet(&resp, 0, sizeof(resp)); 00649 00650 Osal_MemSet(&rq, 0, sizeof(rq)); 00651 rq.ogf = OGF_LE_CTL; 00652 rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; 00653 rq.cparam = NULL; 00654 rq.clen = 0; 00655 rq.rparam = &resp; 00656 rq.rlen = LE_RAND_RP_SIZE; 00657 00658 if (hci_send_req(&rq) < 0) 00659 return -1; 00660 00661 if (resp.status) { 00662 return -1; 00663 } 00664 00665 *tx_power_level = resp.level; 00666 00667 return 0; 00668 } 00669 00670 int hci_le_set_random_address(tBDAddr bdaddr) 00671 { 00672 struct hci_request rq; 00673 le_set_random_address_cp set_rand_addr_cp; 00674 uint8_t status; 00675 00676 Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); 00677 Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); 00678 00679 Osal_MemSet(&rq, 0, sizeof(rq)); 00680 rq.ogf = OGF_LE_CTL; 00681 rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; 00682 rq.cparam = &set_rand_addr_cp; 00683 rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; 00684 rq.rparam = &status; 00685 rq.rlen = 1; 00686 00687 if (hci_send_req(&rq) < 0) 00688 return -1; 00689 00690 if (status) { 00691 return -1; 00692 } 00693 00694 return 0; 00695 } 00696 00697 int hci_read_bd_addr(tBDAddr bdaddr) 00698 { 00699 struct hci_request rq; 00700 read_bd_addr_rp resp; 00701 00702 Osal_MemSet(&resp, 0, sizeof(resp)); 00703 00704 Osal_MemSet(&rq, 0, sizeof(rq)); 00705 rq.ogf = OGF_INFO_PARAM; 00706 rq.ocf = OCF_READ_BD_ADDR; 00707 rq.cparam = NULL; 00708 rq.clen = 0; 00709 rq.rparam = &resp; 00710 rq.rlen = READ_BD_ADDR_RP_SIZE; 00711 00712 if (hci_send_req(&rq) < 0) 00713 return -1; 00714 00715 if (resp.status) { 00716 return -1; 00717 } 00718 Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); 00719 00720 return 0; 00721 } 00722 00723 int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, 00724 const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, 00725 uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) 00726 { 00727 struct hci_request rq; 00728 le_create_connection_cp create_cp; 00729 uint8_t status; 00730 00731 Osal_MemSet(&create_cp, 0, sizeof(create_cp)); 00732 create_cp.interval = interval; 00733 create_cp.window = window; 00734 create_cp.initiator_filter = initiator_filter; 00735 create_cp.peer_bdaddr_type = peer_bdaddr_type; 00736 Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); 00737 create_cp.own_bdaddr_type = own_bdaddr_type; 00738 create_cp.min_interval=min_interval; 00739 create_cp.max_interval=max_interval; 00740 create_cp.latency = latency; 00741 create_cp.supervision_timeout=supervision_timeout; 00742 create_cp.min_ce_length=min_ce_length; 00743 create_cp.max_ce_length=max_ce_length; 00744 00745 Osal_MemSet(&rq, 0, sizeof(rq)); 00746 rq.ogf = OGF_LE_CTL; 00747 rq.ocf = OCF_LE_CREATE_CONN; 00748 rq.cparam = &create_cp; 00749 rq.clen = LE_CREATE_CONN_CP_SIZE; 00750 rq.event = EVT_CMD_STATUS; 00751 rq.rparam = &status; 00752 rq.rlen = 1; 00753 00754 if (hci_send_req(&rq) < 0) 00755 return -1; 00756 00757 if (status) { 00758 return -1; 00759 } 00760 00761 return 0; 00762 } 00763 00764 int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) 00765 { 00766 struct hci_request rq; 00767 le_encrypt_cp params; 00768 le_encrypt_rp resp; 00769 00770 Osal_MemSet(&resp, 0, sizeof(resp)); 00771 00772 Osal_MemCpy(params.key, key, 16); 00773 Osal_MemCpy(params.plaintext, plaintextData, 16); 00774 00775 Osal_MemSet(&rq, 0, sizeof(rq)); 00776 rq.ogf = OGF_LE_CTL; 00777 rq.ocf = OCF_LE_ENCRYPT; 00778 rq.cparam = ¶ms; 00779 rq.clen = LE_ENCRYPT_CP_SIZE; 00780 rq.rparam = &resp; 00781 rq.rlen = LE_ENCRYPT_RP_SIZE; 00782 00783 if (hci_send_req(&rq) < 0){ 00784 return -1; 00785 } 00786 00787 if (resp.status) { 00788 return -1; 00789 } 00790 00791 Osal_MemCpy(encryptedData, resp.encdata, 16); 00792 00793 return 0; 00794 } 00795 00796 int hci_le_ltk_request_reply(uint8_t key[16]) 00797 { 00798 struct hci_request rq; 00799 le_ltk_reply_cp params; 00800 le_ltk_reply_rp resp; 00801 00802 Osal_MemSet(&resp, 0, sizeof(resp)); 00803 00804 params.handle = 1; 00805 Osal_MemCpy(params.key, key, 16); 00806 00807 Osal_MemSet(&rq, 0, sizeof(rq)); 00808 rq.ogf = OGF_LE_CTL; 00809 rq.ocf = OCF_LE_LTK_REPLY; 00810 rq.cparam = ¶ms; 00811 rq.clen = LE_LTK_REPLY_CP_SIZE; 00812 rq.rparam = &resp; 00813 rq.rlen = LE_LTK_REPLY_RP_SIZE; 00814 00815 if (hci_send_req(&rq) < 0) 00816 return -1; 00817 00818 if (resp.status) { 00819 return -1; 00820 } 00821 00822 return 0; 00823 } 00824 00825 int hci_le_ltk_request_neg_reply() 00826 { 00827 struct hci_request rq; 00828 le_ltk_neg_reply_cp params; 00829 le_ltk_neg_reply_rp resp; 00830 00831 Osal_MemSet(&resp, 0, sizeof(resp)); 00832 00833 params.handle = 1; 00834 00835 Osal_MemSet(&rq, 0, sizeof(rq)); 00836 rq.ogf = OGF_LE_CTL; 00837 rq.ocf = OCF_LE_LTK_NEG_REPLY; 00838 rq.cparam = ¶ms; 00839 rq.clen = LE_LTK_NEG_REPLY_CP_SIZE; 00840 rq.rparam = &resp; 00841 rq.rlen = LE_LTK_NEG_REPLY_RP_SIZE; 00842 00843 if (hci_send_req(&rq) < 0) 00844 return -1; 00845 00846 if (resp.status) { 00847 return -1; 00848 } 00849 00850 return 0; 00851 } 00852 00853 int hci_le_read_white_list_size(uint8_t *size) 00854 { 00855 struct hci_request rq; 00856 le_read_white_list_size_rp resp; 00857 00858 Osal_MemSet(&resp, 0, sizeof(resp)); 00859 00860 Osal_MemSet(&rq, 0, sizeof(rq)); 00861 rq.ogf = OGF_LE_CTL; 00862 rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE; 00863 rq.rparam = &resp; 00864 rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE; 00865 00866 if (hci_send_req(&rq) < 0){ 00867 return -1; 00868 } 00869 00870 if (resp.status) { 00871 return -1; 00872 } 00873 00874 *size = resp.size; 00875 00876 return 0; 00877 } 00878 00879 int hci_le_clear_white_list() 00880 { 00881 struct hci_request rq; 00882 uint8_t status; 00883 00884 Osal_MemSet(&rq, 0, sizeof(rq)); 00885 rq.ogf = OGF_LE_CTL; 00886 rq.ocf = OCF_LE_CLEAR_WHITE_LIST; 00887 rq.rparam = &status; 00888 rq.rlen = 1; 00889 00890 if (hci_send_req(&rq) < 0){ 00891 return -1; 00892 } 00893 00894 if (status) { 00895 return -1; 00896 } 00897 00898 return 0; 00899 } 00900 00901 int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) 00902 { 00903 struct hci_request rq; 00904 le_add_device_to_white_list_cp params; 00905 uint8_t status; 00906 00907 params.bdaddr_type = bdaddr_type; 00908 Osal_MemCpy(params.bdaddr, bdaddr, 6); 00909 00910 Osal_MemSet(&rq, 0, sizeof(rq)); 00911 rq.ogf = OGF_LE_CTL; 00912 rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; 00913 rq.cparam = ¶ms; 00914 rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE; 00915 rq.rparam = &status; 00916 rq.rlen = 1; 00917 00918 if (hci_send_req(&rq) < 0){ 00919 return -1; 00920 } 00921 00922 if (status) { 00923 return -1; 00924 } 00925 00926 return 0; 00927 } 00928 00929 int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) 00930 { 00931 struct hci_request rq; 00932 le_remove_device_from_white_list_cp params; 00933 uint8_t status; 00934 00935 params.bdaddr_type = bdaddr_type; 00936 Osal_MemCpy(params.bdaddr, bdaddr, 6); 00937 00938 Osal_MemSet(&rq, 0, sizeof(rq)); 00939 rq.ogf = OGF_LE_CTL; 00940 rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST; 00941 rq.cparam = ¶ms; 00942 rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE; 00943 rq.rparam = &status; 00944 rq.rlen = 1; 00945 00946 if (hci_send_req(&rq) < 0){ 00947 return -1; 00948 } 00949 00950 if (status) { 00951 return -1; 00952 } 00953 00954 return 0; 00955 } 00956 00957 int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level) 00958 { 00959 struct hci_request rq; 00960 read_transmit_power_level_cp params; 00961 read_transmit_power_level_rp resp; 00962 00963 Osal_MemSet(&resp, 0, sizeof(resp)); 00964 00965 params.handle = *conn_handle; 00966 params.type = type; 00967 00968 Osal_MemSet(&rq, 0, sizeof(rq)); 00969 rq.ogf = OGF_HOST_CTL; 00970 rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; 00971 rq.cparam = ¶ms; 00972 rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; 00973 rq.rparam = &resp; 00974 rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; 00975 00976 if (hci_send_req(&rq) < 0){ 00977 return -1; 00978 } 00979 00980 if (resp.status) { 00981 return -1; 00982 } 00983 00984 *conn_handle = resp.handle; 00985 *tx_level = resp.handle; 00986 00987 return 0; 00988 } 00989 00990 int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi) 00991 { 00992 struct hci_request rq; 00993 read_rssi_cp params; 00994 read_rssi_rp resp; 00995 00996 Osal_MemSet(&resp, 0, sizeof(resp)); 00997 00998 params.handle = *conn_handle; 00999 01000 Osal_MemSet(&rq, 0, sizeof(rq)); 01001 rq.ogf = OGF_STATUS_PARAM; 01002 rq.ocf = OCF_READ_RSSI; 01003 rq.cparam = ¶ms; 01004 rq.clen = READ_RSSI_CP_SIZE; 01005 rq.rparam = &resp; 01006 rq.rlen = READ_RSSI_RP_SIZE; 01007 01008 if (hci_send_req(&rq) < 0){ 01009 return -1; 01010 } 01011 01012 if (resp.status) { 01013 return -1; 01014 } 01015 01016 *conn_handle = resp.handle; 01017 *rssi = resp.rssi; 01018 01019 return 0; 01020 } 01021 01022 int hci_le_read_local_supported_features(uint8_t *features) 01023 { 01024 struct hci_request rq; 01025 le_read_local_supported_features_rp resp; 01026 01027 Osal_MemSet(&resp, 0, sizeof(resp)); 01028 01029 Osal_MemSet(&rq, 0, sizeof(rq)); 01030 rq.ogf = OGF_LE_CTL; 01031 rq.ocf = OCF_LE_READ_LOCAL_SUPPORTED_FEATURES; 01032 rq.rparam = &resp; 01033 rq.rlen = LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE; 01034 01035 if (hci_send_req(&rq) < 0){ 01036 return -1; 01037 } 01038 01039 if (resp.status) { 01040 return -1; 01041 } 01042 01043 Osal_MemCpy(features, resp.features, sizeof(resp.features)); 01044 01045 return 0; 01046 } 01047 01048 int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]) 01049 { 01050 struct hci_request rq; 01051 le_read_channel_map_cp params; 01052 le_read_channel_map_rp resp; 01053 01054 Osal_MemSet(&resp, 0, sizeof(resp)); 01055 01056 params.handle = conn_handle; 01057 01058 Osal_MemSet(&rq, 0, sizeof(rq)); 01059 rq.ogf = OGF_LE_CTL; 01060 rq.ocf = OCF_LE_READ_CHANNEL_MAP; 01061 rq.cparam = ¶ms; 01062 rq.clen = LE_READ_CHANNEL_MAP_CP_SIZE; 01063 rq.rparam = &resp; 01064 rq.rlen = LE_READ_CHANNEL_MAP_RP_SIZE; 01065 01066 if (hci_send_req(&rq) < 0){ 01067 return -1; 01068 } 01069 01070 if (resp.status) { 01071 return -1; 01072 } 01073 01074 Osal_MemCpy(ch_map, resp.map, 5); 01075 01076 return 0; 01077 } 01078 01079 int hci_le_read_supported_states(uint8_t states[8]) 01080 { 01081 struct hci_request rq; 01082 le_read_supported_states_rp resp; 01083 01084 Osal_MemSet(&resp, 0, sizeof(resp)); 01085 01086 Osal_MemSet(&rq, 0, sizeof(rq)); 01087 rq.ogf = OGF_LE_CTL; 01088 rq.ocf = OCF_LE_READ_SUPPORTED_STATES; 01089 rq.rparam = &resp; 01090 rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE; 01091 01092 if (hci_send_req(&rq) < 0){ 01093 return -1; 01094 } 01095 01096 if (resp.status) { 01097 return -1; 01098 } 01099 01100 Osal_MemCpy(states, resp.states, 8); 01101 01102 return 0; 01103 } 01104 01105 int hci_le_receiver_test(uint8_t frequency) 01106 { 01107 struct hci_request rq; 01108 le_receiver_test_cp params; 01109 uint8_t status; 01110 01111 params.frequency = frequency; 01112 01113 Osal_MemSet(&rq, 0, sizeof(rq)); 01114 rq.ogf = OGF_LE_CTL; 01115 rq.ocf = OCF_LE_RECEIVER_TEST; 01116 rq.cparam = ¶ms; 01117 rq.clen = LE_RECEIVER_TEST_CP_SIZE; 01118 rq.rparam = &status; 01119 rq.rlen = 1; 01120 01121 if (hci_send_req(&rq) < 0){ 01122 return -1; 01123 } 01124 01125 if (status) { 01126 return -1; 01127 } 01128 01129 return 0; 01130 } 01131 01132 int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload) 01133 { 01134 struct hci_request rq; 01135 le_transmitter_test_cp params; 01136 uint8_t status; 01137 01138 params.frequency = frequency; 01139 params.length = length; 01140 params.payload = payload; 01141 01142 Osal_MemSet(&rq, 0, sizeof(rq)); 01143 rq.ogf = OGF_LE_CTL; 01144 rq.ocf = OCF_LE_TRANSMITTER_TEST; 01145 rq.cparam = ¶ms; 01146 rq.clen = LE_TRANSMITTER_TEST_CP_SIZE; 01147 rq.rparam = &status; 01148 rq.rlen = 1; 01149 01150 if (hci_send_req(&rq) < 0){ 01151 return -1; 01152 } 01153 01154 if (status) { 01155 return -1; 01156 } 01157 01158 return 0; 01159 } 01160 01161 int hci_le_test_end(uint16_t *num_pkts) 01162 { 01163 struct hci_request rq; 01164 le_test_end_rp resp; 01165 01166 Osal_MemSet(&resp, 0, sizeof(resp)); 01167 01168 Osal_MemSet(&rq, 0, sizeof(rq)); 01169 rq.ogf = OGF_LE_CTL; 01170 rq.ocf = OCF_LE_TEST_END; 01171 rq.rparam = &resp; 01172 rq.rlen = LE_TEST_END_RP_SIZE; 01173 01174 if (hci_send_req(&rq) < 0){ 01175 return -1; 01176 } 01177 01178 if (resp.status) { 01179 return -1; 01180 } 01181 01182 *num_pkts = resp.num_pkts; 01183 01184 return 0; 01185 } 01186
Generated on Tue Jul 12 2022 17:28:29 by
1.7.2