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