Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
hci.c
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