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