/* Copyright Statement: * * * * This software/firmware and related documentation ("MediaTek Software") are * * protected under relevant copyright laws. The information contained herein * * is confidential and proprietary to MediaTek Inc. and/or its licensors. * * Without the prior written permission of MediaTek inc. and/or its licensors, * * any reproduction, modification, use or disclosure of MediaTek Software, * * and information contained herein, in whole or in part, shall be strictly * * prohibited. * * * * MediaTek Inc. (C) 2016. All rights reserved. * * * * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES * * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") * * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER * * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL * * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED * * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * * NONINFRINGEMENT. * * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE * * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR * * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO * * SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER * * EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN * * FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK SOFTWARE. * * MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES * * MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR * * OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND * * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED * * HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK * * SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE * * PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. * * * * The following software/firmware and/or related documentation ("MediaTek Software") * * have been modified by MediaTek Inc. All revisions are subject to any receiver's * * applicable license agreements with MediaTek Inc. * */ #if defined(MTK_BT_PROPRIETARY_HANDLING) && (MTK_BT_PROPRIETARY_HANDLING == TRUE) #define LOG_TAG "mtk_btif_ble_scanner" #include #include #include #include #include #include #include #include #include "device/include/controller.h" #include "btif_common.h" #include "btif_util.h" #include #include "advertise_data_parser.h" #include "bta_api.h" #include "bta_gatt_api.h" #include "btif_config.h" #include "btif_dm.h" #include "btif_gatt.h" #include "btif_gatt_util.h" #include "btif_storage.h" #include "osi/include/log.h" #include "main/shim/dumpsys.h" #include "../include/mtk_btif_ble_scanner.h" #if defined(MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE) /******************************************************************************* ** ** Function btif_av_change_pkt_len_callback ** ** Description Callback function for vendor specific event that to change packet length of a2dp ** ** Returns void ** *******************************************************************************/ void mtk_bta_batch_scan_reports_cb(int client_id, tBTM_STATUS status, uint8_t report_format, uint8_t num_records, std::vector data){ // read all, check all recorsd inside data uint8_t* pdata = data.data(); int32_t remain = 0; RawAddress remote_addr; uint8_t remote_addr_type; int device_type; uint8_t addr_type; if ( 0x01 == report_format ){ // Truncated Mode: Address[0]: 6 octets, Address_Type[0]: 1 octet, Tx_Pwr[0]: 1 octet, RSSI[0] : 1 octet, Timestamp[0]: 2 octets for(pdata = data.data(); pdata < (data.data()+data.size()); ){ remain = (int32_t)(data.size() - ( pdata - data.data() )); LOG_DEBUG("batch remain:%d size:%lu diff:%ld", remain, (unsigned long)data.size(), (signed long)(pdata - data.data()) ); if( remain >= 10 && remain > 0 ){ STREAM_TO_BDADDR(remote_addr, pdata); LOG_DEBUG("batch addr: remote_addr %s", remote_addr.ToString().c_str()); STREAM_TO_UINT8(remote_addr_type, pdata); pdata += 1; // tx_pwr pdata += 1; // rssi pdata += 2; // timestamp LOG_DEBUG("%s: truncated_report add peer %s remote_addr_type=0x%x ", __func__, remote_addr.ToString().c_str(), remote_addr_type); if (!btif_get_device_type(remote_addr, &device_type) && !btif_get_address_type(remote_addr, &addr_type) ) { // add device_type and address_type if not exist device_type = BT_DEVICE_TYPE_BLE; addr_type = remote_addr_type; BTA_DmAddBleDevice(remote_addr, addr_type, device_type); LOG_INFO("%s: truncated_report add peer %s remote_addr_type=0x%x ", __func__, remote_addr.ToString().c_str(), remote_addr_type); }else{ LOG_INFO("%s: device_type %d addr_type %d", __func__, device_type, addr_type); } }else{ LOG_INFO("%s: truncated_report no more size remain %d", __func__, remain); break; } } }else if( 0x02 == report_format){ // Full Mode: Address[0]: 6 octets, Address_Type[0]: 1 octet, Tx_Pwr[0]: 1 octet, RSSI[0]: 1 octet // Timestamp[0]: 2 octets, Adv packet_len[0]: 1 octet, Adv_packet[0]: Adv_packet_len octets, // Scan_data_resp_len[0]: 1 octet, Scan_data_resp[0]: Scan_data_resp octets uint8_t packet_len = 0; uint8_t data_resp_len = 0; for(pdata = data.data(); pdata < (data.data()+data.size()); ){ remain = (int32_t)(data.size() - ( pdata - data.data() )); LOG_DEBUG("batch remain:%d size:%lu diff:%ld", remain, (unsigned long)data.size(), (signed long)(pdata - data.data()) ); if( remain >= 12 && remain > 0 ){ STREAM_TO_BDADDR(remote_addr, pdata); LOG_INFO("batch addr: remote_addr %s", remote_addr.ToString().c_str()); STREAM_TO_UINT8(remote_addr_type, pdata); pdata += 1; // tx_pwr pdata += 1; // rssi pdata += 2; // timestamp STREAM_TO_UINT8(packet_len, pdata); pdata += packet_len; STREAM_TO_UINT8(data_resp_len, pdata); pdata += data_resp_len; LOG_DEBUG("%s: full_report peer %s remote_addr_type=0x%x ", __func__, remote_addr.ToString().c_str(), remote_addr_type); if (!btif_get_device_type(remote_addr, &device_type) && !btif_get_address_type(remote_addr, (tBLE_ADDR_TYPE*)&addr_type) ) { // unknown device_type but want to connect LE transport. Add it as a BLE device first device_type = BT_DEVICE_TYPE_BLE; addr_type = remote_addr_type; BTA_DmAddBleDevice(remote_addr, addr_type, device_type); LOG_DEBUG("%s: full_report add peer %s remote_addr_type=0x%x packet_len %d data_resp_len %d", __func__, remote_addr.ToString().c_str(), remote_addr_type, packet_len, data_resp_len); }else{ LOG_DEBUG("%s: device_type %d addr_type %d", __func__, device_type, addr_type); } }else{ LOG_INFO("%s: full_report no more size remain %d", __func__, remain); break; } } }else{ LOG_INFO("%s: unknown report_format", __func__); } // report to upper layer LOG_INFO("%s: num_records %d data.size() d", __func__, num_records ); //, (unsigned long)data.size()); } void btif_ble_scanner_update_COD(tBTA_DM_SEARCH* p_data) { bt_property_t properties[1]; RawAddress bdaddr; bt_status_t status; uint32_t cod = 0; uint32_t old_cod = 0; uint8_t num_properties = 0; memset(properties, 0, sizeof(properties)); if (p_data) { bdaddr = p_data->inq_res.bd_addr; cod = devclass2uint(p_data->inq_res.dev_class); BTIF_TRACE_DEBUG("%s %s cod is 0x%06x", __func__, PRIVATE_ADDRESS(bdaddr), cod); BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties], BT_PROPERTY_CLASS_OF_DEVICE, sizeof(uint32_t), &old_cod); status = btif_storage_get_remote_device_property(&bdaddr, &properties[num_properties]); BTIF_TRACE_DEBUG("%s cod in config 0x%06x, status=%d", __func__, old_cod, status); /* some device adv appearance is reserved, and it will be set as * 0x1F00, and when it report to upper layer. the EIR cod may be overwritten * by this cod. And when upper layer want to connect the profile, the cod * is useless, then upper layer will drop the connection. */ if ((cod == 0) || (cod == 0x1f00)) { /* Try to retrieve cod from storage */ BTIF_TRACE_DEBUG("%s invalid cod 0x%x, use cod 0x%x in config", __func__, cod, old_cod); cod = old_cod; if (cod == 0) { BTIF_TRACE_DEBUG("%s cod is again 0, set as unclassified", __func__); cod = 0x1f00; } } /* some device is dual mode, and it will send ble adv and it will cause * device update the cod and flush the config file. * so if there is no any change, don't update. * if not cod in config, save it too. */ if ((cod != old_cod) || (status != BT_STATUS_SUCCESS)) { BTIF_TRACE_DEBUG("%s cod change 0x%x=>0x%x, update config", __func__, old_cod, cod); BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties], BT_PROPERTY_CLASS_OF_DEVICE, sizeof(uint32_t), &cod); status = btif_storage_set_remote_device_property(&bdaddr, &properties[num_properties]); ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote device class", status); num_properties++; } } } #endif #endif