|
| 1 | +#include "BluetoothWorker.hpp" |
| 2 | +#include "profiles/GAVD.hpp" |
| 3 | +#include "log/log.hpp" |
| 4 | + |
| 5 | +#include <cstdio> |
| 6 | +extern "C" { |
| 7 | +#include <HCITRANS.h> |
| 8 | +#include <BTPSKRNL.h> |
| 9 | +#include <BSCAPI.h> |
| 10 | +#include <HCIAPI.h> |
| 11 | +#include <GAPAPI.h> |
| 12 | +#include <L2CAPAPI.h> |
| 13 | +}; |
| 14 | + |
| 15 | +using namespace bsp; |
| 16 | + |
| 17 | +// WORK IN PROGRESS - in open() in A3DP example right now (Stack initialization...) |
| 18 | +struct HCI |
| 19 | +{ |
| 20 | + HCI_DriverInformation_t driver; |
| 21 | + HCI_HCILLConfiguration_t ll; |
| 22 | + HCI_Driver_Reconfigure_Data_t driver_reconfigure; |
| 23 | + HCI() { |
| 24 | + memset(&driver, 0, sizeof driver); |
| 25 | + memset(&ll, 0, sizeof ll); |
| 26 | + memset(&driver_reconfigure, 0, sizeof driver_reconfigure); |
| 27 | + } |
| 28 | +}; |
| 29 | + |
| 30 | +BluetoothWorker::BluetoothWorker() : active_features(0) |
| 31 | +{ |
| 32 | + LOG_INFO("Create bluetooth worker"); |
| 33 | + bt = Bluetopia::getInstance(); |
| 34 | + host = std::make_unique<BtDev>(BtDev()); |
| 35 | + hci = std::make_unique<HCI>(HCI()); |
| 36 | + bt->open(); |
| 37 | + bt->set_logging(BTdev::LogDebug); |
| 38 | + if (initialize_stack() != SuccessBt) { |
| 39 | + LOG_ERROR("initialize_stack error!"); |
| 40 | + return; |
| 41 | + } |
| 42 | + if (enable_a2dp() != SuccessBt) { |
| 43 | + LOG_ERROR("enable a2dp error!"); |
| 44 | + return; |
| 45 | + } |
| 46 | + if (get_local_addr() != SuccessBt) { |
| 47 | + LOG_ERROR("get local address error!"); |
| 48 | + } |
| 49 | + if (enable_l2ca() != SuccessBt) { |
| 50 | + LOG_ERROR("enable l2ca error"); |
| 51 | + } |
| 52 | + if (hci_write_link_policy() != SuccessBt) { |
| 53 | + LOG_ERROR("HCI write link policy error"); |
| 54 | + } |
| 55 | + if (check_a2dp() != SuccessBt) { |
| 56 | + LOG_ERROR("Check a2dp error"); |
| 57 | + } |
| 58 | + if (aud_init() != SuccessBt) { |
| 59 | + LOG_ERROR("AUD init error"); |
| 60 | + } |
| 61 | + if (hcill_setup() != SuccessBt) { |
| 62 | + LOG_ERROR("hcill_setup error"); |
| 63 | + } |
| 64 | +} |
| 65 | + |
| 66 | +BluetoothWorker::~BluetoothWorker() |
| 67 | +{ |
| 68 | +} |
| 69 | + |
| 70 | +int lib_log_callback(int len,char* msg) |
| 71 | +{ |
| 72 | + LOG_INFO("%.*s",len,msg); |
| 73 | + return 0; |
| 74 | +} |
| 75 | + |
| 76 | +BluetoothWorker::Error BluetoothWorker::initialize_stack() |
| 77 | +{ |
| 78 | + LOG_INFO("%s", __PRETTY_FUNCTION__); |
| 79 | + Error ret = SuccessBt; |
| 80 | + int result = 0; |
| 81 | + BTPS_Initialization_t BTPS_Initialization; |
| 82 | + |
| 83 | + HCI_DRIVER_SET_COMM_INFORMATION(&hci->driver, 1, bt->default_baudrate, cpHCILL_RTS_CTS); |
| 84 | + hci->driver.DriverInformation.COMMDriverInformation.InitializationDelay = 100; |
| 85 | + BTPS_Initialization.MessageOutputCallback = lib_log_callback; |
| 86 | + // initialize kernel |
| 87 | + BTPS_Init(&BTPS_Initialization); |
| 88 | + |
| 89 | + do { |
| 90 | + if ((result = BSC_Initialize(&hci->driver, 0)) <= 0) { |
| 91 | + LOG_ERROR("HCI Initialization failure"); |
| 92 | + ret = ErrorBtAPI; |
| 93 | + break; |
| 94 | + } else { |
| 95 | + stack.id = result; |
| 96 | + } |
| 97 | + |
| 98 | + HCI_Version_t v_hci; |
| 99 | + if (HCI_Version_Supported(stack.id, &v_hci) != 0) { |
| 100 | + LOG_ERROR("HCI supported stack err"); |
| 101 | + ret = ErrorBtAPI; |
| 102 | + } else { |
| 103 | + // print supported stack |
| 104 | + } |
| 105 | + } while (0); |
| 106 | + |
| 107 | + // HCI_Read_Local_Version_Information(BluetoothStackID, &FW_Version_Details.StatusResult, &FW_Version_Details.HCI_VersionResult, |
| 108 | + // &FW_Version_Details.HCI_RevisionResult, &FW_Version_Details.LMP_VersionResult, &FW_Version_Details.Manufacturer_NameResult, |
| 109 | + // &FW_Version_Details.LMP_SubversionResult); |
| 110 | + return ret; |
| 111 | +} |
| 112 | + |
| 113 | +BluetoothWorker::Error BluetoothWorker::enable_a2dp() |
| 114 | +{ |
| 115 | + LOG_INFO("%s", __PRETTY_FUNCTION__); |
| 116 | + Error ret = SuccessBt; |
| 117 | + if (BSC_EnableFeature(stack.id, BSC_FEATURE_A3DP_SOURCE) != 0) { |
| 118 | + LOG_ERROR("A2DP enable feature failure"); |
| 119 | + ret = ErrorBtAPI; |
| 120 | + } |
| 121 | + return ret; |
| 122 | +} |
| 123 | + |
| 124 | +BluetoothWorker::Error BluetoothWorker::get_local_addr() |
| 125 | +{ |
| 126 | + LOG_INFO("%s", __PRETTY_FUNCTION__); |
| 127 | + Error ret = SuccessBt; |
| 128 | + if (!GAP_Query_Local_BD_ADDR(stack.id, host->val)) { |
| 129 | + LOG_INFO("Local address: %s", host->tostr().c_str()); |
| 130 | + } else { |
| 131 | + ret = ErrorBtAPI; |
| 132 | + LOG_ERROR("Local address querry failure"); |
| 133 | + } |
| 134 | + return ret; |
| 135 | +} |
| 136 | + |
| 137 | +BluetoothWorker::Error BluetoothWorker::enable_l2ca() |
| 138 | +{ |
| 139 | + LOG_INFO("%s", __PRETTY_FUNCTION__); |
| 140 | + Error ret = SuccessBt; |
| 141 | + LOG_INFO("Enable l2ca"); |
| 142 | + L2CA_Link_Connect_Params_t L2CA_Link_Connect_Params; |
| 143 | + L2CA_Link_Connect_Params.L2CA_Link_Connect_Request_Config = cqAllowRoleSwitch; |
| 144 | + L2CA_Link_Connect_Params.L2CA_Link_Connect_Response_Config = csMaintainCurrentRole; |
| 145 | + L2CA_Set_Link_Connection_Configuration(stack.id, &L2CA_Link_Connect_Params); |
| 146 | + return ret; |
| 147 | +} |
| 148 | + |
| 149 | +BluetoothWorker::Error BluetoothWorker::hci_write_link_policy() |
| 150 | +{ |
| 151 | + LOG_INFO("%s", __PRETTY_FUNCTION__); |
| 152 | + Error ret = SuccessBt; |
| 153 | + unsigned char status; |
| 154 | + LOG_INFO("HCI write link policy"); |
| 155 | + if (HCI_Command_Supported(stack.id, HCI_SUPPORTED_COMMAND_WRITE_DEFAULT_LINK_POLICY_BIT_NUMBER) > 0) |
| 156 | + HCI_Write_Default_Link_Policy_Settings( |
| 157 | + stack.id, (HCI_LINK_POLICY_SETTINGS_ENABLE_MASTER_SLAVE_SWITCH | HCI_LINK_POLICY_SETTINGS_ENABLE_SNIFF_MODE), &status); |
| 158 | + return ret; |
| 159 | +} |
| 160 | + |
| 161 | +BluetoothWorker::Error BluetoothWorker::check_a2dp() |
| 162 | +{ |
| 163 | + LOG_INFO("%s", __PRETTY_FUNCTION__); |
| 164 | + Error err = SuccessBt; |
| 165 | + LOG_INFO("Check a2dp source enabled"); |
| 166 | + if (!((BSC_QueryActiveFeatures(stack.id, &active_features) == 0) && (active_features & BSC_FEATURE_A3DP_SOURCE))) { |
| 167 | + err = ErrorBtAPI; |
| 168 | + } |
| 169 | + return err; |
| 170 | +} |
| 171 | + |
| 172 | +BluetoothWorker::Error BluetoothWorker::aud_init() |
| 173 | +{ |
| 174 | + LOG_INFO("%s", __PRETTY_FUNCTION__); |
| 175 | + Error err = SuccessBt; |
| 176 | + LOG_INFO("Initialize AUD profile"); |
| 177 | + BtProfile *prof = new GAVD(); |
| 178 | + profiles.push_back(prof); |
| 179 | + if (prof->init(&stack) != BtProfile::SuccessBtProfile) { |
| 180 | + LOG_ERROR("AUD init failure!"); |
| 181 | + } else { |
| 182 | + // ASSIGN_CLASS_OF_DEVICE(ClassOfDevice, 0x28, 0x04, 0x10); |
| 183 | + } |
| 184 | + return err; |
| 185 | +} |
| 186 | + |
| 187 | +// SetConnect -> SetPair -> SetDisconnectable |
| 188 | + |
| 189 | +void sleep_cb(Boolean_t SleepAllowed, unsigned long CallbackParameter) |
| 190 | +{ |
| 191 | + LOG_ERROR("not implemented"); |
| 192 | +} |
| 193 | + |
| 194 | +BluetoothWorker::Error BluetoothWorker::hcill_setup() |
| 195 | +{ |
| 196 | + LOG_INFO("%s", __PRETTY_FUNCTION__); |
| 197 | + Error ret = SuccessBt; |
| 198 | + int result; |
| 199 | + if ((hci->driver.DriverInformation.COMMDriverInformation.Protocol == cpHCILL) || |
| 200 | + (hci->driver.DriverInformation.COMMDriverInformation.Protocol == cpHCILL_RTS_CTS)) { |
| 201 | + hci->ll.SleepCallbackFunction = sleep_cb; |
| 202 | + hci->ll.SleepCallbackParameter = 0; |
| 203 | + hci->driver_reconfigure.ReconfigureCommand = HCI_COMM_DRIVER_RECONFIGURE_DATA_COMMAND_CHANGE_HCILL_PARAMETERS; |
| 204 | + hci->driver_reconfigure.ReconfigureData = (void *)&hci->ll; |
| 205 | + |
| 206 | + // Register the sleep mode callback. Note that if this unction returns greater than 0 then sleep is currently enabled. |
| 207 | + result = HCI_Reconfigure_Driver((unsigned int)result, FALSE, &hci->driver_reconfigure); |
| 208 | + if (result > 0) { |
| 209 | + LOG_INFO("Sleep is allowed."); |
| 210 | + } |
| 211 | + } |
| 212 | + return ret; |
| 213 | +} |
0 commit comments