/*************************************************************************** * * Copyright 2015-2019 BES. * All rights reserved. All unpublished rights reserved. * * No part of this work may be used or reproduced in any form or by any * means, or stored in a database or retrieval system, without prior written * permission of BES. * * Use of this work is governed by a license granted by BES. * This work contains confidential and proprietary information of * BES. which is protected by copyright, trade secret, * trademark and other intellectual property rights. * ****************************************************************************/ #if defined(NEW_NV_RECORD_ENABLED) #include #include #include #include "nvrecord_extension.h" #include "nvrecord_bt.h" #include "hal_trace.h" void ram_record_ddbrec_init(void) { } void nvrecord_rebuild_paired_bt_dev_info(NV_RECORD_PAIRED_BT_DEV_INFO_T* pPairedBtInfo) { memset((uint8_t *)pPairedBtInfo, 0, sizeof(NV_RECORD_PAIRED_BT_DEV_INFO_T)); pPairedBtInfo->pairedDevNum = 0; } void nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_profile* device_plf, bool isActive) { uint32_t lock = nv_record_pre_write_operation(); if (isActive != device_plf->a2dp_act) { nv_record_update_runtime_userdata(); } device_plf->a2dp_act = isActive; nv_record_post_write_operation(lock); } void nv_record_btdevicerecord_set_hfp_profile_active_state(btdevice_profile* device_plf, bool isActive) { uint32_t lock = nv_record_pre_write_operation(); if (isActive != device_plf->hfp_act) { nv_record_update_runtime_userdata(); } device_plf->hfp_act = isActive; nv_record_post_write_operation(lock); } void nv_record_btdevicerecord_set_hsp_profile_active_state(btdevice_profile* device_plf, bool isActive) { uint32_t lock = nv_record_pre_write_operation(); if (isActive != device_plf->hsp_act) { nv_record_update_runtime_userdata(); } device_plf->hsp_act = isActive; nv_record_post_write_operation(lock); } void nv_record_btdevicerecord_set_a2dp_profile_codec(btdevice_profile* device_plf, uint8_t a2dpCodec) { uint32_t lock = nv_record_pre_write_operation(); if (a2dpCodec != device_plf->a2dp_codectype) { nv_record_update_runtime_userdata(); } device_plf->a2dp_codectype = a2dpCodec; nv_record_post_write_operation(lock); } int nv_record_get_paired_dev_count(void) { if (NULL == nvrecord_extension_p) { return 0; } return nvrecord_extension_p->bt_pair_info.pairedDevNum; } /* return: -1: enum dev failure. 0: without paired dev. 1: only 1 paired dev,store@record1. 2: get 2 paired dev.notice:record1 is the latest record. */ int nv_record_enum_latest_two_paired_dev(btif_device_record_t* record1,btif_device_record_t* record2) { if((NULL == record1) || (NULL == record2) || (NULL == nvrecord_extension_p)) { return -1; } if (nvrecord_extension_p->bt_pair_info.pairedDevNum > 0) { if (1 == nvrecord_extension_p->bt_pair_info.pairedDevNum) { memcpy((uint8_t *)record1, (uint8_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[0]), sizeof(btif_device_record_t)); return 1; } else { memcpy((uint8_t *)record1, (uint8_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[0]), sizeof(btif_device_record_t)); memcpy((uint8_t *)record2, (uint8_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[1]), sizeof(btif_device_record_t)); return 2; } } else { return 0; } } static void nv_record_print_dev_record(const btif_device_record_t* record) { TRACE(0,"nv record bdAddr = "); DUMP8("%02x ",record->bdAddr.address,sizeof(record->bdAddr.address)); TRACE(0,"record_trusted = "); DUMP8("%d ",&record->trusted,sizeof((uint8_t)record->trusted)); TRACE(0,"record_linkKey = "); DUMP8("%02x ",record->linkKey,sizeof(record->linkKey)); TRACE(0,"record_keyType = "); DUMP8("%x ",&record->keyType,sizeof(record->keyType)); TRACE(0,"record_pinLen = "); DUMP8("%x ",&record->pinLen,sizeof(record->pinLen)); } void nv_record_all_ddbrec_print(void) { if (NULL == nvrecord_extension_p) { TRACE(0,"No BT paired dev."); return; } if (nvrecord_extension_p->bt_pair_info.pairedDevNum > 0) { for(uint8_t tmp_i=0; tmp_i < nvrecord_extension_p->bt_pair_info.pairedDevNum; tmp_i++) { btif_device_record_t record; bt_status_t ret_status; ret_status = nv_record_enum_dev_records(tmp_i, &record); if (BT_STS_SUCCESS == ret_status) { nv_record_print_dev_record(&record); } } } else { TRACE(0,"No BT paired dev."); } } /* this function should be surrounded by OS_LockStack and OS_UnlockStack when call. */ bt_status_t nv_record_enum_dev_records(unsigned short index,btif_device_record_t* record) { btif_device_record_t *recaddr = NULL; if((index >= nvrecord_extension_p->bt_pair_info.pairedDevNum) || (NULL == nvrecord_extension_p)) { return BT_STS_FAILED; } recaddr = (btif_device_record_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[index].record); memcpy(record, recaddr, sizeof(btif_device_record_t)); nv_record_print_dev_record(record); return BT_STS_SUCCESS; } static int8_t nv_record_get_bt_pairing_info_index(const uint8_t* btAddr) { NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); for (uint8_t index = 0; index < pBtDevInfo->pairedDevNum; index++) { if (!memcmp(pBtDevInfo->pairedBtDevInfo[index].record.bdAddr.address, btAddr, BTIF_BD_ADDR_SIZE)) { return (int8_t)index; } } return -1; } /********************************************** this function should be surrounded by OS_LockStack and OS_UnlockStack when call. **********************************************/ static bt_status_t POSSIBLY_UNUSED nv_record_ddbrec_add(const btif_device_record_t* param_rec) { if ((NULL == param_rec) || (NULL == nvrecord_extension_p)) { return BT_STS_FAILED; } uint32_t lock = nv_record_pre_write_operation(); bool isFlushNv = false; // try to find the entry int8_t indexOfEntry = -1; NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); indexOfEntry = nv_record_get_bt_pairing_info_index(param_rec->bdAddr.address); if (-1 == indexOfEntry) { // don't exist, need to add to the head of the entry list if (MAX_BT_PAIRED_DEVICE_COUNT == pBtDevInfo->pairedDevNum) { for (uint8_t k = 0; k < MAX_BT_PAIRED_DEVICE_COUNT - 1; k++) { memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[MAX_BT_PAIRED_DEVICE_COUNT - 1 - k]), (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[MAX_BT_PAIRED_DEVICE_COUNT - 2 - k]), sizeof(nvrec_btdevicerecord)); } pBtDevInfo->pairedDevNum--; } else { for (uint8_t k = 0; k < pBtDevInfo->pairedDevNum; k++) { memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[pBtDevInfo->pairedDevNum - k]), (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[pBtDevInfo->pairedDevNum - 1 - k]), sizeof(nvrec_btdevicerecord)); } } // fill the default value nvrec_btdevicerecord* nvrec_pool_record = &(pBtDevInfo->pairedBtDevInfo[0]); memcpy((uint8_t *)&(nvrec_pool_record->record), (uint8_t *)param_rec, sizeof(btif_device_record_t)); nvrec_pool_record->device_vol.a2dp_vol = NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT; nvrec_pool_record->device_vol.hfp_vol = NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT; nvrec_pool_record->device_plf.hfp_act = false; nvrec_pool_record->device_plf.hsp_act = false; nvrec_pool_record->device_plf.a2dp_act = false; #ifdef BTIF_DIP_DEVICE nvrec_pool_record->vend_id = 0; nvrec_pool_record->vend_id_source = 0; #endif pBtDevInfo->pairedDevNum++; // need to flush the nv record isFlushNv = true; } else { // exist // check whether it's already at the head // if not, move it to the head if (indexOfEntry > 0) { nvrec_btdevicerecord record; memcpy((uint8_t *)&record, (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry]), sizeof(record)); // if not, move it to the head for (uint8_t k = 0; k < indexOfEntry; k++) { memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry - k]), (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry - 1 - k]), sizeof(nvrec_btdevicerecord)); } memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0]), (uint8_t *)&record, sizeof(record)); // update the link info memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0].record), (uint8_t *)param_rec, sizeof(btif_device_record_t)); // need to flush the nv record isFlushNv = true; } // else, check whether the link info needs to be updated else { if (memcmp((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0].record), (uint8_t *)param_rec, sizeof(btif_device_record_t))) { // update the link info memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0].record), (uint8_t *)param_rec, sizeof(btif_device_record_t)); // need to flush the nv record isFlushNv = true; } } } TRACE(1,"paired Bt dev:%d", pBtDevInfo->pairedDevNum); TRACE(1,"Is to flush nv: %d", isFlushNv); nv_record_all_ddbrec_print(); if (isFlushNv) { nv_record_update_runtime_userdata(); } nv_record_post_write_operation(lock); return BT_STS_SUCCESS; } /* this function should be surrounded by OS_LockStack and OS_UnlockStack when call. */ bt_status_t nv_record_add(SECTIONS_ADP_ENUM type, void *record) { bt_status_t retstatus = BT_STS_FAILED; if ((NULL == record) || (section_none == type)) { return BT_STS_FAILED; } switch(type) { case section_usrdata_ddbrecord: retstatus = nv_record_ddbrec_add(record); break; default: break; } return retstatus; } /* this function should be surrounded by OS_LockStack and OS_UnlockStack when call. */ bt_status_t nv_record_ddbrec_find(const bt_bdaddr_t* bd_ddr, btif_device_record_t *record) { if ((NULL == bd_ddr) || (NULL == record) || (NULL == nvrecord_extension_p)) { return BT_STS_FAILED; } int8_t indexOfEntry = -1; NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); indexOfEntry = nv_record_get_bt_pairing_info_index(bd_ddr->address); if (-1 == indexOfEntry) { return BT_STS_FAILED; } else { memcpy((uint8_t *)record, (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry].record), sizeof(btif_device_record_t)); return BT_STS_SUCCESS; } } /* this function should be surrounded by OS_LockStack and OS_UnlockStack when call. */ bt_status_t nv_record_ddbrec_delete(const bt_bdaddr_t *bdaddr) { if (NULL == nvrecord_extension_p) { return BT_STS_FAILED; } int8_t indexOfEntry = -1; NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); indexOfEntry = nv_record_get_bt_pairing_info_index(bdaddr->address); if (-1 == indexOfEntry) { return BT_STS_FAILED; } uint32_t lock = nv_record_pre_write_operation(); for (uint8_t k = 0; k < pBtDevInfo->pairedDevNum - indexOfEntry - 1; k++) { memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry + k]), (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry + 1 + k]), sizeof(nvrec_btdevicerecord)); } memset((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[pBtDevInfo->pairedDevNum-1]), 0, sizeof(nvrec_btdevicerecord)); pBtDevInfo->pairedDevNum--; nv_record_update_runtime_userdata(); nv_record_post_write_operation(lock); return BT_STS_SUCCESS; } int nv_record_btdevicerecord_find(const bt_bdaddr_t *bd_ddr, nvrec_btdevicerecord **record) { if ((NULL == bd_ddr) || (NULL == record) || (NULL == nvrecord_extension_p)) { return -1; } int8_t indexOfEntry = -1; NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); indexOfEntry = nv_record_get_bt_pairing_info_index(bd_ddr->address); if (-1 == indexOfEntry) { return -1; } *record = (nvrec_btdevicerecord *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry]); return 0; } void nv_record_btdevicerecord_set_a2dp_vol(nvrec_btdevicerecord* pRecord, int8_t vol) { uint32_t lock = nv_record_pre_write_operation(); if (vol != pRecord->device_vol.a2dp_vol) { nv_record_update_runtime_userdata(); pRecord->device_vol.a2dp_vol = vol; } nv_record_post_write_operation(lock); } void nv_record_btdevicerecord_set_hfp_vol(nvrec_btdevicerecord* pRecord, int8_t vol) { uint32_t lock = nv_record_pre_write_operation(); if (vol != pRecord->device_vol.hfp_vol) { nv_record_update_runtime_userdata(); pRecord->device_vol.hfp_vol = vol; } nv_record_post_write_operation(lock); } void nv_record_btdevicevolume_set_a2dp_vol(btdevice_volume* device_vol, int8_t vol) { uint32_t lock = nv_record_pre_write_operation(); if (vol != device_vol->a2dp_vol) { nv_record_update_runtime_userdata(); device_vol->a2dp_vol = vol; } nv_record_post_write_operation(lock); } void nv_record_btdevicevolume_set_hfp_vol(btdevice_volume* device_vol, int8_t vol) { uint32_t lock = nv_record_pre_write_operation(); if (vol != device_vol->hfp_vol) { nv_record_update_runtime_userdata(); device_vol->hfp_vol = vol; } nv_record_post_write_operation(lock); } void nv_record_btdevicerecord_set_vend_id_and_source(nvrec_btdevicerecord* pRecord, int16_t vend_id, int16_t vend_id_source) { #ifdef BTIF_DIP_DEVICE TRACE(2, "%s vend id 0x%x", __func__, vend_id); uint32_t lock = nv_record_pre_write_operation(); if (vend_id != pRecord->vend_id) { nv_record_update_runtime_userdata(); pRecord->vend_id = vend_id; pRecord->vend_id_source = vend_id_source; } nv_record_post_write_operation(lock); #endif } #endif //#if defined(NEW_NV_RECORD_ENABLED)