Программа считывает показания датчиков и управляет сервомашинками.
Fork of NUCLEO_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 } 01148
Generated on Tue Jul 12 2022 22:44:50 by 1.7.2