project
Fork of X_NUCLEO_IDB0XA1 by
Embed:
(wiki syntax)
Show/hide line numbers
hci_dma_lp.c
Go to the documentation of this file.
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