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/src/bluenrg_hci.c
- Committer:
- mridup
- Date:
- 2014-07-16
- Revision:
- 0:309c845d289d
- Child:
- 2:a2b623661316
File content as of revision 0:309c845d289d:
/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
* File Name : bluenrg_hci.c
* Author : AMS - HEA&RF BU
* Version : V1.0.0
* Date : 4-Oct-2013
* Description : File with HCI commands for BlueNRG FW6.0 and above.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#include "hal_types.h"
#include "osal.h"
#include "ble_status.h"
#include "hal.h"
#include "osal.h"
#include "hci_internal.h"
#include "bluenrg_hci_internal.h"
#include "gatt_server.h"
tBleStatus aci_gatt_init()
{
struct hci_request rq;
tHalUint8 status;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_INIT;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_gap_init(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle)
{
struct hci_request rq;
gap_init_cp cp;
gap_init_rp resp;
cp.role = role;
Osal_MemSet(&resp, 0, sizeof(resp));
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_INIT;
rq.cparam = &cp;
rq.clen = GAP_INIT_CP_SIZE;
rq.rparam = &resp;
rq.rlen = GAP_INIT_RP_SIZE;
if (hci_send_req(&rq) < 0)
return -1;
if (resp.status) {
return resp.status;
}
*service_handle = resp.service_handle;
*dev_name_char_handle = resp.dev_name_char_handle;
*appearance_char_handle = resp.appearance_char_handle;
return 0;
}
tBleStatus aci_gap_set_non_discoverable(void)
{
struct hci_request rq;
tHalUint8 status;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
const char *LocalName, uint8_t ServiceUUIDLen, const uint8_t* ServiceUUIDList,
uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
buffer[indx] = AdvType;
indx++;
Osal_MemCpy(buffer + indx, &AdvIntervMin, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &AdvIntervMax, 2);
indx += 2;
buffer[indx] = OwnAddrType;
indx++;
buffer[indx] = AdvFilterPolicy;
indx++;
buffer[indx] = LocalNameLen;
indx++;
Osal_MemCpy(buffer + indx, LocalName, LocalNameLen);
indx += LocalNameLen;
buffer[indx] = ServiceUUIDLen;
indx++;
Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen);
indx += ServiceUUIDLen;
Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2);
indx += 2;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_SET_DISCOVERABLE;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
buffer[indx] = AdvLen;
indx++;
Osal_MemCpy(buffer + indx, AdvData, AdvLen);
indx += AdvLen;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_UPDATE_ADV_DATA;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gatt_add_serv(tHalUint8 service_uuid_type, const tHalUint8* service_uuid, tHalUint8 service_type, tHalUint8 max_attr_records, tHalUint16 *serviceHandle)
{
struct hci_request rq;
gatt_add_serv_rp resp;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t uuid_len;
uint8_t indx = 0;
buffer[indx] = service_uuid_type;
indx++;
if(service_uuid_type == 0x01){
uuid_len = 2;
}
else {
uuid_len = 16;
}
Osal_MemCpy(buffer + indx, service_uuid, uuid_len);
indx += uuid_len;
buffer[indx] = service_type;
indx++;
buffer[indx] = max_attr_records;
indx++;
Osal_MemSet(&resp, 0, sizeof(resp));
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_ADD_SERV;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &resp;
rq.rlen = GATT_ADD_SERV_RP_SIZE;
if (hci_send_req(&rq) < 0)
return -1;
if (resp.status) {
return resp.status;
}
*serviceHandle = resp.handle;
return 0;
}
tBleStatus aci_gatt_add_char(tHalUint16 serviceHandle,
tUuidType charUuidType,
const tHalUint8* charUuid,
tHalUint16 charValueLen,
tHalUint8 charProperties,
tAttrSecurityFlags secPermissions,
tGattServerEvent gattEvtMask,
tHalUint8 encryKeySize,
tHalUint8 isVariable,
tHalUint16* charHandle)
{
struct hci_request rq;
gatt_add_serv_rp resp;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t uuid_len;
uint8_t indx = 0;
Osal_MemCpy(buffer + indx, &serviceHandle, 2);
indx += 2;
buffer[indx] = charUuidType;
indx++;
if(charUuidType == 0x01){
uuid_len = 2;
}
else {
uuid_len = 16;
}
Osal_MemCpy(buffer + indx, charUuid, uuid_len);
indx += uuid_len;
buffer[indx] = charValueLen;
indx++;
buffer[indx] = charProperties;
indx++;
buffer[indx] = secPermissions;
indx++;
buffer[indx] = gattEvtMask;
indx++;
buffer[indx] = encryKeySize;
indx++;
buffer[indx] = isVariable;
indx++;
Osal_MemSet(&resp, 0, sizeof(resp));
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_ADD_CHAR;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &resp;
rq.rlen = GATT_ADD_CHAR_RP_SIZE;
if (hci_send_req(&rq) < 0)
return -1;
if (resp.status) {
return resp.status;
}
*charHandle = resp.handle;
return 0;
}
tBleStatus aci_gatt_add_char_desc(tHalUint16 serviceHandle,
tHalUint16 charHandle,
tUuidType descUuidType,
const tHalUint8* uuid,
tHalUint8 descValueMaxLen,
tHalUint8 descValueLen,
const void* descValue,
tAttrSecurityFlags secPermissions,
tAttrSecurityFlags accPermissions,
tGattServerEvent gattEvtMask,
tHalUint8 encryKeySize,
tHalUint8 isVariable,
tHalUint16* descHandle)
{
struct hci_request rq;
gatt_add_char_desc_rp resp;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t uuid_len;
uint8_t indx = 0;
Osal_MemCpy(buffer + indx, &serviceHandle, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &charHandle, 2);
indx += 2;
buffer[indx] = descUuidType;
indx++;
if(descUuidType == 0x01){
uuid_len = 2;
}
else {
uuid_len = 16;
}
Osal_MemCpy(buffer + indx, uuid, uuid_len);
indx += uuid_len;
buffer[indx] = descValueMaxLen;
indx++;
buffer[indx] = descValueLen;
indx++;
Osal_MemCpy(buffer + indx, descValue, descValueLen);
indx += descValueLen;
buffer[indx] = secPermissions;
indx++;
buffer[indx] = accPermissions;
indx++;
buffer[indx] = gattEvtMask;
indx++;
buffer[indx] = encryKeySize;
indx++;
buffer[indx] = isVariable;
indx++;
Osal_MemSet(&resp, 0, sizeof(resp));
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_ADD_CHAR_DESC;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &resp;
rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE;
if (hci_send_req(&rq) < 0)
return -1;
if (resp.status) {
return resp.status;
}
*descHandle = resp.handle;
return 0;
}
tBleStatus aci_gatt_update_char_value(tHalUint16 servHandle,
tHalUint16 charHandle,
tHalUint8 charValOffset,
tHalUint8 charValueLen,
const tHalUint8 *charValue)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
Osal_MemCpy(buffer + indx, &servHandle, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &charHandle, 2);
indx += 2;
buffer[indx] = charValOffset;
indx++;
buffer[indx] = charValueLen;
indx++;
Osal_MemCpy(buffer + indx, charValue, charValueLen);
indx += charValueLen;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_UPD_CHAR_VAL;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_gatt_allow_read(tHalUint16 conn_handle)
{
struct hci_request rq;
gatt_allow_read_cp cp;
tHalUint8 status;
cp.conn_handle = conn_handle;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_ALLOW_READ;
rq.cparam = &cp;
rq.clen = GATT_ALLOW_READ_CP_SIZE;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_gatt_set_desc_value(tHalUint16 servHandle,
tHalUint16 charHandle,
tHalUint16 charDescHandle,
tHalUint16 charDescValOffset,
tHalUint8 charDescValueLen,
const tHalUint8 *charDescValue)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
Osal_MemCpy(buffer + indx, &servHandle, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &charHandle, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &charDescHandle, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &charDescValOffset, 2);
indx += 2;
buffer[indx] = charDescValueLen;
indx++;
Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen);
indx += charDescValueLen;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_SET_DESC_VAL;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle)
{
struct hci_request rq;
uint8_t status;
gatt_disc_all_prim_services_cp cp;
cp.conn_handle = conn_handle;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES;
rq.cparam = &cp;
rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle,
uint16_t end_service_handle)
{
struct hci_request rq;
uint8_t status;
gatt_find_included_services_cp cp;
cp.conn_handle = conn_handle;
cp.start_handle = start_service_handle;
cp.end_handle = end_service_handle;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES;
rq.cparam = &cp;
rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle,
uint16_t end_attr_handle)
{
struct hci_request rq;
uint8_t status;
gatt_disc_all_charac_of_serv_cp cp;
cp.conn_handle = conn_handle;
cp.start_attr_handle = start_attr_handle;
cp.end_attr_handle = end_attr_handle;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV;
rq.cparam = &cp;
rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle,
uint16_t char_end_handle)
{
struct hci_request rq;
uint8_t status;
gatt_disc_all_charac_descriptors_cp cp;
cp.conn_handle = conn_handle;
cp.char_val_handle = char_val_handle;
cp.char_end_handle = char_end_handle;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS;
rq.cparam = &cp;
rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle,
uint8_t value_len, uint8_t *attr_value)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
Osal_MemCpy(buffer + indx, &conn_handle, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &attr_handle, 2);
indx += 2;
buffer[indx] = value_len;
indx++;
Osal_MemCpy(buffer + indx, attr_value, value_len);
indx += value_len;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gatt_write_response(uint16_t conn_handle,
uint16_t attr_handle,
uint8_t write_status,
uint8_t err_code,
uint8_t att_val_len,
uint8_t *att_val)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
Osal_MemCpy(buffer + indx, &conn_handle, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &attr_handle, 2);
indx += 2;
buffer[indx] = write_status;
indx += 1;
buffer[indx] = err_code;
indx += 1;
buffer[indx] = att_val_len;
indx += 1;
Osal_MemCpy(buffer + indx, &att_val, att_val_len);
indx += att_val_len;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_WRITE_RESPONSE;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
{
struct hci_request rq;
uint8_t status;
gatt_read_charac_val_cp cp;
cp.conn_handle = conn_handle;
cp.attr_handle = attr_handle;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_READ_CHARAC_VAL;
rq.cparam = &cp;
rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle,
uint16_t val_offset)
{
struct hci_request rq;
uint8_t status;
gatt_read_long_charac_val_cp cp;
cp.conn_handle = conn_handle;
cp.attr_handle = attr_handle;
cp.val_offset = val_offset;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL;
rq.cparam = &cp;
rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle,
uint8_t value_len, uint8_t *attr_value)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
Osal_MemCpy(buffer + indx, &conn_handle, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &attr_handle, 2);
indx += 2;
buffer[indx] = value_len;
indx++;
Osal_MemCpy(buffer + indx, attr_value, value_len);
indx += value_len;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_WRITE_CHAR_VALUE;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle,
uint8_t value_len, uint8_t *attr_value)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
Osal_MemCpy(buffer + indx, &conn_handle, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &attr_handle, 2);
indx += 2;
buffer[indx] = value_len;
indx++;
Osal_MemCpy(buffer + indx, attr_value, value_len);
indx += value_len;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_hal_write_config_data(tHalUint8 offset,
tHalUint8 len,
const tHalUint8 *val)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
buffer[indx] = offset;
indx++;
buffer[indx] = len;
indx++;
Osal_MemCpy(buffer + indx, val, len);
indx += len;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_HAL_WRITE_CONFIG_DATA;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level)
{
struct hci_request rq;
hal_set_tx_power_level_cp cp;
uint8_t status;
cp.en_high_power = en_high_power;
cp.pa_level = pa_level;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL;
rq.cparam = &cp;
rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode,
uint8_t oob_enable,
uint8_t oob_data[16],
uint8_t min_encryption_key_size,
uint8_t max_encryption_key_size,
uint8_t use_fixed_pin,
uint32_t fixed_pin,
uint8_t bonding_mode)
{
struct hci_request rq;
gap_set_auth_requirement_cp cp;
uint8_t status;
cp.mitm_mode = mitm_mode;
cp.oob_enable = oob_enable;
Osal_MemCpy(cp.oob_data, oob_data, 16);
cp.min_encryption_key_size = min_encryption_key_size;
cp.max_encryption_key_size = max_encryption_key_size;
cp.use_fixed_pin = use_fixed_pin;
cp.fixed_pin = fixed_pin;
cp.bonding_mode = bonding_mode;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT;
rq.cparam = &cp;
rq.clen = GAP_SET_AUTH_REQUIREMENT_CP_SIZE;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
uint8_t own_address_type, uint8_t filterDuplicates)
{
struct hci_request rq;
gap_start_limited_discovery_proc_cp cp;
uint8_t status;
cp.scanInterval = scanInterval;
cp.scanWindow = scanWindow;
cp.own_address_type = own_address_type;
cp.filterDuplicates = filterDuplicates;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC;
rq.cparam = &cp;
rq.clen = GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
uint8_t own_address_type, uint8_t filterDuplicates)
{
struct hci_request rq;
gap_start_general_discovery_proc_cp cp;
uint8_t status;
cp.scanInterval = scanInterval;
cp.scanWindow = scanWindow;
cp.own_address_type = own_address_type;
cp.filterDuplicates = filterDuplicates;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC;
rq.cparam = &cp;
rq.clen = GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gap_start_auto_conn_establishment(uint16_t scanInterval, uint16_t scanWindow,
uint8_t own_bdaddr_type, uint16_t conn_min_interval,
uint16_t conn_max_interval, uint16_t conn_latency,
uint16_t supervision_timeout, uint16_t min_conn_length,
uint16_t max_conn_length, uint8_t num_whitelist_entries,
uint8_t *addr_array)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
Osal_MemCpy(buffer + indx, &scanInterval, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &scanWindow, 2);
indx += 2;
buffer[indx] = own_bdaddr_type;
indx++;
Osal_MemCpy(buffer + indx, &conn_min_interval, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &conn_max_interval, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &conn_latency, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &supervision_timeout, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &min_conn_length, 2);
indx += 2;
Osal_MemCpy(buffer + indx, &max_conn_length, 2);
indx += 2;
buffer[indx] = num_whitelist_entries;
indx++;
Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7));
indx += num_whitelist_entries * 7;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISHMENT;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow,
uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr,
uint8_t own_bdaddr_type, uint16_t conn_min_interval,
uint16_t conn_max_interval, uint16_t conn_latency,
uint16_t supervision_timeout, uint16_t min_conn_length,
uint16_t max_conn_length)
{
struct hci_request rq;
gap_create_connection_cp cp;
uint8_t status;
cp.scanInterval = scanInterval;
cp.scanWindow = scanWindow;
cp.peer_bdaddr_type = peer_bdaddr_type;
Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6);
cp.own_bdaddr_type = own_bdaddr_type;
cp.conn_min_interval = conn_min_interval;
cp.conn_max_interval = conn_max_interval;
cp.conn_latency = conn_latency;
cp.supervision_timeout = supervision_timeout;
cp.min_conn_length = min_conn_length;
cp.max_conn_length = max_conn_length;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_CREATE_CONNECTION;
rq.cparam = &cp;
rq.clen = GAP_CREATE_CONNECTION_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code)
{
struct hci_request rq;
uint8_t status;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE;
rq.cparam = &procedure_code;
rq.clen = 1;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason)
{
struct hci_request rq;
gap_terminate_cp cp;
uint8_t status;
cp.handle = conn_handle;
cp.reason = reason;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GAP_TERMINATE;
rq.cparam = &cp;
rq.clen = GAP_TERMINATE_CP_SIZE;
rq.event = EVT_CMD_STATUS;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, uint16_t interval_max,
uint16_t slave_latency, uint16_t timeout_mult)
{
struct hci_request rq;
l2cap_conn_param_upd_cp cp;
tHalUint8 status;
cp.handle = conn_handle;
cp.interval_min = interval_min;
cp.interval_max = interval_max;
cp.slave_latency = slave_latency;
cp.timeout_multiplier = timeout_mult;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_L2CAP_CONN_PARAM_UPD_REQ;
rq.event = EVT_CMD_STATUS;
rq.cparam = &cp;
rq.clen = L2CAP_CONN_PARAM_UPD_REQ_CP_SIZE;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_hal_tone_start(uint8_t rf_channel)
{
struct hci_request rq;
hal_tone_start_cp cp;
uint8_t status;
cp.rf_channel = rf_channel;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_HAL_TONE_START;
rq.cparam = &cp;
rq.clen = HAL_TONE_START_CP_SIZE;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
if (status) {
return status;
}
return 0;
}
tBleStatus aci_updater_start(void)
{
struct hci_request rq;
tHalUint8 status;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_UPDATER_START;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_updater_reboot()
{
struct hci_request rq;
tHalUint8 status;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_UPDATER_REBOOT;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_get_updater_version(uint8_t *version)
{
struct hci_request rq;
get_updater_version_rp resp;
Osal_MemSet(&resp, 0, sizeof(resp));
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GET_UPDATER_VERSION;
rq.rparam = &resp;
rq.rlen = GET_UPDATER_VERSION_RP_SIZE;
if (hci_send_req(&rq) < 0)
return -1;
*version = resp.version;
return resp.status;
}
tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size)
{
struct hci_request rq;
get_updater_bufsize_rp resp;
Osal_MemSet(&resp, 0, sizeof(resp));
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GET_UPDATER_BUFSIZE;
rq.rparam = &resp;
rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE;
if (hci_send_req(&rq) < 0)
return -1;
*buffer_size = resp.buffer_size;
return resp.status;
}
tBleStatus aci_erase_blue_flag()
{
struct hci_request rq;
tHalUint8 status;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_reset_blue_flag()
{
struct hci_request rq;
tHalUint8 status;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_updater_erase_sector(uint32_t address)
{
struct hci_request rq;
updater_erase_sector_cp cp;
uint8_t status;
cp.address = address;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_UPDATER_ERASE_SECTOR;
rq.cparam = &cp;
rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_updater_program_data_block(uint32_t address,
uint16_t len,
const uint8_t *data)
{
struct hci_request rq;
uint8_t status;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
uint8_t indx = 0;
if(len > HCI_MAX_PACKET_SIZE)
return -1;
Osal_MemCpy(buffer + indx, &address, 4);
indx += 4;
Osal_MemCpy(buffer + indx, &len, 2);
indx += 2;
Osal_MemCpy(buffer + indx, data, len);
indx += len;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &status;
rq.rlen = 1;
if (hci_send_req(&rq) < 0)
return -1;
return status;
}
tBleStatus aci_updater_read_data_block(uint32_t address,
uint16_t data_len,
uint8_t *data)
{
struct hci_request rq;
updater_read_data_block_cp cp;
uint8_t buffer[HCI_MAX_PACKET_SIZE];
if(data_len > HCI_MAX_PACKET_SIZE - 1)
return -1;
cp.address = address;
cp.data_len = data_len;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_UPDATER_READ_DATA_BLOCK;
rq.cparam = &cp;
rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE;
rq.rparam = buffer;
rq.rlen = data_len + 1;
if (hci_send_req(&rq) < 0)
return -1;
Osal_MemCpy(data, buffer+1, data_len);
return buffer[0];
}
tBleStatus aci_updater_calc_crc(uint32_t address,
uint8_t num_sectors,
uint32_t *crc)
{
struct hci_request rq;
updater_calc_crc_cp cp;
updater_calc_crc_rp resp;
Osal_MemSet(&resp, 0, sizeof(resp));
cp.address = address;
cp.num_sectors = num_sectors;
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_UPDATER_CALC_CRC;
rq.cparam = &cp;
rq.clen = UPDATER_CALC_CRC_CP_SIZE;
rq.rparam = &resp;
rq.rlen = UPDATER_CALC_CRC_RP_SIZE;
if (hci_send_req(&rq) < 0)
return -1;
*crc = resp.crc;
return resp.status;
}
tBleStatus aci_updater_hw_version(uint8_t *version)
{
struct hci_request rq;
updater_hw_version_rp resp;
Osal_MemSet(&resp, 0, sizeof(resp));
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_UPDATER_HW_VERSION;
rq.rparam = &resp;
rq.rlen = UPDATER_HW_VERSION_RP_SIZE;
if (hci_send_req(&rq) < 0)
return -1;
*version = resp.version;
return resp.status;
}
