Vv-yichenxiMerge commit
9d0c825c创建于 4月27日历史提交
/*
 * This file is auto-generated by jsongensource.py, Do not modify it directly!
 */

/*
 * Copyright (C) 2023 Xiaomi Corporation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
#include "bluetooth.h"
#include "bt_a2dp_sink.h"
#include "bt_a2dp_source.h"
#include "bt_adapter.h"
#include "bt_hfp_ag.h"
#include "bt_hfp_hf.h"
#include "bt_hid_device.h"
#include "bt_pan.h"
#include "feature_bluetooth.h"
#include "system_bluetooth_bt.h"

#define file_tag "system_bluetooth_bt"

static bool bt_feature_allocator(void** data, uint32_t size)
{
    *data = malloc(size);
    if (!(*data))
        return false;

    return true;
}

static bt_status_t bluetooth_connect_profiles(FeatureInstanceHandle feature, bt_address_t* addr, feature_bluetooth_profile_t profile_id)
{
    bt_status_t status = BT_STATUS_SUCCESS;
    bt_instance_t* bt_ins = feature_bluetooth_get_bt_ins(feature);
    if (!bt_ins) {
        return BT_STATUS_FAIL;
    }

    switch (profile_id) {
    case A2DP_SINK:
#ifdef CONFIG_BLUETOOTH_A2DP_SINK
        status = bt_a2dp_sink_connect(bt_ins, addr);
#endif
        break;
    case A2DP_SOURCE:
#ifdef CONFIG_BLUETOOTH_A2DP_SOURCE
        status = bt_a2dp_source_connect(bt_ins, addr);
#endif
        break;
    case HFP_AG:
#ifdef CONFIG_BLUETOOTH_HFP_AG
        status = bt_hfp_ag_connect(bt_ins, addr);
#endif
        break;
    case HFP_HF:
#ifdef CONFIG_BLUETOOTH_HFP_HF
        status = bt_hfp_hf_connect(bt_ins, addr);
#endif
        break;
    case HID_DEVICE:
#ifdef CONFIG_BLUETOOTH_HID_DEVICE
        status = bt_hid_device_connect(bt_ins, addr);
#endif
        break;
    case PAN_USE:
#ifdef CONFIG_BLUETOOTH_PAN
        status = bt_pan_connect(bt_ins, addr);
#endif
        break;
    default:
        status = BT_STATUS_NOT_SUPPORTED;
        break;
    }
    return status;
}

static bt_status_t bluetooth_disconnect_profiles(FeatureInstanceHandle feature, bt_address_t* addr, feature_bluetooth_profile_t profile_id)
{
    bt_status_t status = BT_STATUS_SUCCESS;
    bt_instance_t* bt_ins = feature_bluetooth_get_bt_ins(feature);
    if (!bt_ins) {
        return BT_STATUS_FAIL;
    }

    switch (profile_id) {
    case A2DP_SINK:
#ifdef CONFIG_BLUETOOTH_A2DP_SINK
        status = bt_a2dp_sink_disconnect(bt_ins, addr);
#endif
        break;
    case A2DP_SOURCE:
#ifdef CONFIG_BLUETOOTH_A2DP_SOURCE
        status = bt_a2dp_source_disconnect(bt_ins, addr);
#endif
        break;
    case HFP_AG:
#ifdef CONFIG_BLUETOOTH_HFP_AG
        status = bt_hfp_ag_disconnect(bt_ins, addr);
#endif
        break;
    case HFP_HF:
#ifdef CONFIG_BLUETOOTH_HFP_HF
        status = bt_hfp_hf_disconnect(bt_ins, addr);
#endif
        break;
    case HID_DEVICE:
#ifdef CONFIG_BLUETOOTH_HID_DEVICE
        status = bt_hid_device_disconnect(bt_ins, addr);
#endif
        break;
    case PAN_USE:
#ifdef CONFIG_BLUETOOTH_PAN
        status = bt_pan_disconnect(bt_ins, addr);
#endif
        break;
    default:
        status = BT_STATUS_NOT_SUPPORTED;
        break;
    }
    return status;
}

void system_bluetooth_bt_onRegister(const char* feature_name)
{
    FEATURE_LOG_DEBUG("%s::%s()", file_tag, __FUNCTION__);
}

void system_bluetooth_bt_onCreate(FeatureRuntimeContext ctx, FeatureProtoHandle handle)
{
    feature_bluetooth_init_bt_ins(FEATURE_BLUETOOTH_BT, handle);
    FEATURE_LOG_DEBUG("%s::%s()", file_tag, __FUNCTION__);
}

void system_bluetooth_bt_onRequired(FeatureRuntimeContext ctx, FeatureInstanceHandle handle)
{
    feature_bluetooth_add_feature_callback(handle, FEATURE_BLUETOOTH_BT);
    FEATURE_LOG_DEBUG("%s::%s()", file_tag, __FUNCTION__);
}

void system_bluetooth_bt_onDetached(FeatureRuntimeContext ctx, FeatureInstanceHandle handle)
{
    feature_bluetooth_free_feature_callback(handle, FEATURE_BLUETOOTH_BT);
    FEATURE_LOG_DEBUG("%s::%s()", file_tag, __FUNCTION__);
}

void system_bluetooth_bt_onDestroy(FeatureRuntimeContext ctx, FeatureProtoHandle handle)
{
    feature_bluetooth_uninit_bt_ins(FEATURE_BLUETOOTH_BT, handle);
    FEATURE_LOG_DEBUG("%s::%s()", file_tag, __FUNCTION__);
}

void system_bluetooth_bt_onUnregister(const char* feature_name)
{
    FEATURE_LOG_DEBUG("%s::%s()", file_tag, __FUNCTION__);
}

void system_bluetooth_bt_wrap_startDiscovery(FeatureInstanceHandle feature, AppendData append_data, system_bluetooth_bt_StartDiscoveryParams* params)
{
    int timeout = 8;
    bt_status_t status = bt_adapter_start_discovery(feature_bluetooth_get_bt_ins(feature), timeout);
    if (status == BT_STATUS_SUCCESS) {
        if (!FeatureInvokeCallback(feature, params->success)) {
            FEATURE_LOG_ERROR("invoke start discovery success  failed!");
        }
    } else {
        if (!FeatureInvokeCallback(feature, params->fail, "start discovery failed!", status)) {
            FEATURE_LOG_ERROR("invoke start discovery fail callback failed!");
        }
    }
    if (!FeatureInvokeCallback(feature, params->complete)) {
        FEATURE_LOG_ERROR("invoke start discovery complete callback failed!");
    }

    FeatureRemoveCallback(feature, params->success);
    FeatureRemoveCallback(feature, params->fail);
    FeatureRemoveCallback(feature, params->complete);
}
void system_bluetooth_bt_wrap_stopDiscovery(FeatureInstanceHandle feature, AppendData append_data, system_bluetooth_bt_StopDiscoveryParams* params)
{
    bt_status_t status = bt_adapter_cancel_discovery(feature_bluetooth_get_bt_ins(feature));
    if (status == BT_STATUS_SUCCESS) {
        if (!FeatureInvokeCallback(feature, params->success)) {
            FEATURE_LOG_ERROR("invoke stop discovery success callback failed!");
        }
    } else {
        if (!FeatureInvokeCallback(feature, params->fail, "stop discovery failed!", status)) {
            FEATURE_LOG_ERROR("invoke stop discovery fail callback failed!");
        }
    }
    if (!FeatureInvokeCallback(feature, params->complete)) {
        FEATURE_LOG_ERROR("invoke stop discovery complete callback failed!");
    }

    FeatureRemoveCallback(feature, params->success);
    FeatureRemoveCallback(feature, params->fail);
    FeatureRemoveCallback(feature, params->complete);
}

void system_bluetooth_bt_wrap_connectProfiles(FeatureInstanceHandle feature, AppendData append_data, system_bluetooth_bt_ConnectProfilesParams* params)
{
    int profiles_num = params->profiles->_size;
    int* profiles = (int*)(params->profiles->_element);
    bt_address_t addr;
    int status = BT_STATUS_SUCCESS;
    if (bt_addr_str2ba(params->deviceId, &addr) < 0) {
        if (!FeatureInvokeCallback(feature, params->fail, "invalid addr!", BT_STATUS_PARM_INVALID)) {
            FEATURE_LOG_ERROR("invoke connect profiles fail callback failed!");
        }
        goto COMPLETE_CALLBACK;
    }

    for (int i = 0; i < profiles_num; ++i) {
        status |= bluetooth_connect_profiles(feature, &addr, (feature_bluetooth_profile_t)(profiles[i]));
    }

    if (status != BT_STATUS_SUCCESS) {
        if (!FeatureInvokeCallback(feature, params->fail, "connect all passing profiles failed!", status)) {
            FEATURE_LOG_ERROR("invoke connect profiles fail callback failed!");
        }
    } else {
        if (!FeatureInvokeCallback(feature, params->success)) {
            FEATURE_LOG_ERROR("invoke connect profiles success callback failed!");
        }
    }
COMPLETE_CALLBACK:
    if (!FeatureInvokeCallback(feature, params->complete)) {
        FEATURE_LOG_ERROR("invoke connect profiles complete callback failed!");
    }

    FeatureRemoveCallback(feature, params->success);
    FeatureRemoveCallback(feature, params->fail);
    FeatureRemoveCallback(feature, params->complete);
}

void system_bluetooth_bt_wrap_disconnectProfiles(FeatureInstanceHandle feature, AppendData append_data, system_bluetooth_bt_DisconnectProfilesParams* params)
{
    int profiles_num = params->profiles->_size;
    int* profiles = (int*)params->profiles->_element;
    bt_address_t addr;
    int status = BT_STATUS_SUCCESS;
    if (bt_addr_str2ba(params->deviceId, &addr) < 0) {
        if (!FeatureInvokeCallback(feature, params->fail, "invalid addr!", BT_STATUS_PARM_INVALID)) {
            FEATURE_LOG_ERROR("invoke disconnect profiles fail callback failed!");
        }
        goto COMPLETE_CALLBACK;
    }
    for (int i = 0; i < profiles_num; ++i) {
        status |= bluetooth_disconnect_profiles(feature, &addr, (feature_bluetooth_profile_t)profiles[i]);
    }
    if (status != BT_STATUS_SUCCESS) {
        if (!FeatureInvokeCallback(feature, params->fail, "disconnect all passing profiles failed!", status)) {
            FEATURE_LOG_ERROR("invoke disconnect profiles fail callback failed!");
        }
    } else {
        if (!FeatureInvokeCallback(feature, params->success)) {
            FEATURE_LOG_ERROR("invoke disconnect profiles success callback failed!");
        }
    }
COMPLETE_CALLBACK:
    if (!FeatureInvokeCallback(feature, params->complete)) {
        FEATURE_LOG_ERROR("invoke disconnect profiles complete callback failed!");
    }

    FeatureRemoveCallback(feature, params->success);
    FeatureRemoveCallback(feature, params->fail);
    FeatureRemoveCallback(feature, params->complete);
}

void system_bluetooth_bt_wrap_disconnect(FeatureInstanceHandle feature, AppendData append_data, system_bluetooth_bt_DisconnectParams* params)
{
    bt_address_t addr;
    bt_status_t status = BT_STATUS_SUCCESS;
    if (bt_addr_str2ba(params->deviceId, &addr) < 0) {
        if (!FeatureInvokeCallback(feature, params->fail, "invalid addr!", BT_STATUS_PARM_INVALID)) {
            FEATURE_LOG_ERROR("invoke disconnect fail callback failed!");
        }
        goto COMPLETE_CALLBACK;
    }

    status = bt_device_disconnect(feature_bluetooth_get_bt_ins(feature), &addr);

    if (status != BT_STATUS_SUCCESS) {
        if (!FeatureInvokeCallback(feature, params->fail, "disconnect failed!", status)) {
            FEATURE_LOG_ERROR("invoke disconnect fail callback failed!");
        }
    } else {
        if (!FeatureInvokeCallback(feature, params->success)) {
            FEATURE_LOG_ERROR("invoke disconnect success callback failed!");
        }
    }
COMPLETE_CALLBACK:
    if (!FeatureInvokeCallback(feature, params->complete)) {
        FEATURE_LOG_ERROR("invoke disconnect complete callback failed!");
    }

    FeatureRemoveCallback(feature, params->success);
    FeatureRemoveCallback(feature, params->fail);
    FeatureRemoveCallback(feature, params->complete);
}

FtBool system_bluetooth_bt_wrap_getConnectState(FeatureInstanceHandle feature, AppendData append_data, FtString deviceId)
{
    FtBool connected = false;
    bt_address_t addr;
    if (bt_addr_str2ba(deviceId, &addr) < 0) {
        return false;
    }
#ifdef CONFIG_BLUETOOTH_A2DP_SINK
    connected |= bt_a2dp_sink_get_connection_state(feature_bluetooth_get_bt_ins(feature), &addr);
#endif
    return connected;
}

FtArray* system_bluetooth_bt_wrap_getConnectedDevices(FeatureInstanceHandle feature, AppendData append_data)
{
    bt_address_t* addrs = NULL;
    int num = 0;
    bt_adapter_get_connected_devices(feature_bluetooth_get_bt_ins(feature), BT_TRANSPORT_BREDR, &addrs, &num, bt_feature_allocator);
    FtArray* devices = system_bluetooth_bt_malloc_string_array();
    devices->_size = num;
    devices->_element = malloc(devices->_size * sizeof(char*));
    for (int i = 0; i < devices->_size; ++i) {
        char addr_str[BT_ADDR_STR_LENGTH] = { 0 };
        bt_addr_ba2str(addrs + i, addr_str);
        ((char**)devices->_element)[i] = StringToFtString(addr_str);
    }
    free(addrs);
    return devices;
}

FtArray* system_bluetooth_bt_wrap_getBondedDevices(FeatureInstanceHandle feature, AppendData append_data)
{
    bt_address_t* addrs = NULL;
    int num = 0;
    bt_adapter_get_bonded_devices(feature_bluetooth_get_bt_ins(feature), BT_TRANSPORT_BREDR, &addrs, &num, bt_feature_allocator);
    FtArray* devices = system_bluetooth_bt_malloc_string_array();
    devices->_size = num;
    devices->_element = malloc(devices->_size * sizeof(char*));
    for (int i = 0; i < devices->_size; ++i) {
        char addr_str[BT_ADDR_STR_LENGTH] = { 0 };
        bt_addr_ba2str(addrs + i, addr_str);
        ((char**)devices->_element)[i] = StringToFtString(addr_str);
    }
    free(addrs);
    return devices;
}

void system_bluetooth_bt_wrap_removeBondedDevice(FeatureInstanceHandle feature, AppendData append_data, system_bluetooth_bt_RemoveBondedParams* params)
{
    bt_address_t addr;
    bt_status_t status;
    if (bt_addr_str2ba(params->deviceId, &addr) < 0) {
        if (!FeatureInvokeCallback(feature, params->fail, "invalid addr!", BT_STATUS_PARM_INVALID)) {
            FEATURE_LOG_ERROR("invoke remove bonded fail callback failed!");
        }
        goto COMPLETE_CALLBACK;
    }

    if (!bt_device_is_bonded(feature_bluetooth_get_bt_ins(feature), &addr, BT_TRANSPORT_BREDR)) {
        if (!FeatureInvokeCallback(feature, params->success)) {
            FEATURE_LOG_ERROR("invoke remove bonded success callback failed!");
        }
        goto COMPLETE_CALLBACK;
    }

    status = bt_device_remove_bond(feature_bluetooth_get_bt_ins(feature), &addr, BT_TRANSPORT_BREDR);
    if (status != BT_STATUS_SUCCESS) {
        if (!FeatureInvokeCallback(feature, params->fail, "remove bonded failed!", status)) {
            FEATURE_LOG_ERROR("invoke remove bonded fail callback failed!");
        }
    } else {
        if (!FeatureInvokeCallback(feature, params->success)) {
            FEATURE_LOG_ERROR("invoke remove bonded success callback failed!");
        }
    }
COMPLETE_CALLBACK:
    if (!FeatureInvokeCallback(feature, params->complete)) {
        FEATURE_LOG_ERROR("invoke remove bonded complete callback failed!");
    }

    FeatureRemoveCallback(feature, params->success);
    FeatureRemoveCallback(feature, params->fail);
    FeatureRemoveCallback(feature, params->complete);
}

FtBool system_bluetooth_bt_wrap_setScanMode(FeatureInstanceHandle feature, AppendData append_data, FtInt scanMode)
{
    FEATURE_LOG_DEBUG("set scanmode: %d!", scanMode);
    if (scanMode < 0 || scanMode > 2) {
        return false;
    }
    if (bt_adapter_set_scan_mode(feature_bluetooth_get_bt_ins(feature), (bt_scan_mode_t)scanMode, 1) == BT_STATUS_SUCCESS) {
        return true;
    } else {
        return false;
    }
}

FtInt system_bluetooth_bt_wrap_getScanMode(FeatureInstanceHandle feature, AppendData append_data)
{
    return bt_adapter_get_scan_mode(feature_bluetooth_get_bt_ins(feature));
}

FtString system_bluetooth_bt_wrap_getDeviceName(FeatureInstanceHandle feature, AppendData append_data, FtString deviceId)
{
    bt_address_t addr;
    char name[64] = { 0 };
    if (bt_addr_str2ba(deviceId, &addr) < 0) {
        return StringToFtString("");
    }
    bt_device_get_name(feature_bluetooth_get_bt_ins(feature), &addr, name, 64);
    return StringToFtString(name);
}

unsigned int system_bluetooth_bt_wrap_getDeviceClass(FeatureInstanceHandle feature, AppendData append_data, FtString deviceId)
{
    bt_address_t addr;
    if (bt_addr_str2ba(deviceId, &addr) < 0) {
        return 0;
    }

    return bt_device_get_device_class(feature_bluetooth_get_bt_ins(feature), &addr);
}

FtCallbackId system_bluetooth_bt_get_ondiscoveryresult(void* feature, AppendData append_data)
{
    return feature_bluetooth_get_feature_callback(feature, ON_DISCOVERY_RESULT);
}

void system_bluetooth_bt_set_ondiscoveryresult(void* feature, AppendData append_data, FtCallbackId ondiscoveryresult)
{
    FEATURE_LOG_DEBUG("set ondiscoveryresult feature: %p, callbackId: %d", feature, ondiscoveryresult);
    feature_bluetooth_set_feature_callback(feature, ondiscoveryresult, ON_DISCOVERY_RESULT);
}

FtCallbackId system_bluetooth_bt_get_onbondstatechange(void* feature, AppendData append_data)
{
    return feature_bluetooth_get_feature_callback(feature, ON_BOND_STATE_CHANGE);
}

void system_bluetooth_bt_set_onbondstatechange(void* feature, AppendData append_data, FtCallbackId onbondstatechange)
{
    FEATURE_LOG_DEBUG("set onbondstatechange feature: %p, callbackId: %d", feature, onbondstatechange);
    feature_bluetooth_set_feature_callback(feature, onbondstatechange, ON_BOND_STATE_CHANGE);
}