[EGD-3637] restoration of Bluetooth stack [EGD-3637] Bluetooth hangup fix
57 files changed, 7547 insertions(+), 1 deletions(-) M .gitmodules M CMakeLists.txt M module-apps/application-settings/ApplicationSettings.cpp M module-apps/application-settings/CMakeLists.txt A module-bluetooth/Bluetooth/BluetoothWorker.cpp A module-bluetooth/Bluetooth/BluetoothWorker.hpp A module-bluetooth/Bluetooth/BtCommand.hpp A module-bluetooth/Bluetooth/Device.hpp A module-bluetooth/Bluetooth/Error.hpp A module-bluetooth/Bluetooth/Stack.hpp A module-bluetooth/Bluetooth/glucode/HCITRANS.cpp A module-bluetooth/Bluetooth/glucode/bluetooth_init_cc2564C_1.0.c A module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.cpp A module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.h A module-bluetooth/Bluetooth/glucode/hal_time_ms.c A module-bluetooth/Bluetooth/interface/bluekitchen/GAP.cpp A module-bluetooth/Bluetooth/interface/bluekitchen/PAN.cpp A module-bluetooth/Bluetooth/interface/bluekitchen/Worker.cpp A module-bluetooth/Bluetooth/interface/bluekitchen/btstack_config.h A module-bluetooth/CMakeLists.txt A module-bluetooth/README.md A module-bluetooth/lib/btstack A module-bluetooth/lib/btstack.cmake A module-bluetooth/targets/Target_Linux.cmake A module-bluetooth/tests/CMakeLists.txt M module-bsp/CMakeLists.txt A module-bsp/board/linux/bluetooth/Bluetooth.cpp A module-bsp/board/linux/bluetooth/test/bsp_bt.cpp A module-bsp/board/linux/bluetooth/test/bsp_bt.hpp A module-bsp/board/rt1051/bluetooth/BlueKitchen.cpp A module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp A module-bsp/board/rt1051/bluetooth/Bluetopia.cpp M module-bsp/board/rt1051/common/board.h A module-bsp/bsp/bluetooth/Bluetooth.cpp A module-bsp/bsp/bluetooth/Bluetooth.hpp M module-bsp/targets/Target_Linux.cmake M module-bsp/targets/Target_RT1051.cmake A module-lwip/CMakeLists.txt A module-lwip/README.md A module-lwip/includes/arch/cc.h A module-lwip/includes/lwipopts.h A module-lwip/lib/dhcp-server/LICENSE A module-lwip/lib/dhcp-server/README A module-lwip/lib/dhcp-server/dhserver.c A module-lwip/lib/dhcp-server/dhserver.h A module-lwip/lib/lwip A module-lwip/lwip-includes.cmake A module-lwip/tests/CMakeLists.txt M module-services/CMakeLists.txt A module-services/service-bluetooth/CMakeLists.txt A module-services/service-bluetooth/ServiceBluetooth.cpp A module-services/service-bluetooth/ServiceBluetooth.hpp A module-services/service-bluetooth/messages/BluetoothMessage.hpp A module-services/service-lwip/CMakeLists.txt A module-services/service-lwip/ServiceLwIP.cpp A module-services/service-lwip/ServiceLwIP.hpp M source/main.cpp
M .gitmodules => .gitmodules +7 -0
@@ 1,3 1,7 @@ [submodule "module-lwip/lib/lwip"] path = module-lwip/lib/lwip url = ../lwip.git shallow = true [submodule "module-utils/microtar"] path = module-utils/microtar url = ../microtar.git @@ 40,3 44,6 @@ path = module-audio/Audio/decoder/taglib url = ../taglib.git branch = rt1051 [submodule "module-bluetooth/lib/btstack"] path = module-bluetooth/lib/btstack url = git@github.com:mudita/btstack.git
M CMakeLists.txt => CMakeLists.txt +10 -0
@@ 11,6 11,7 @@ include(Colours) include(CCacheConfig) include(ProjectConfig) include(ModuleConfig) include(module-lwip/lwip-includes.cmake) include(SerialPort) include(CopyGdbInit) @@ 161,6 162,12 @@ add_subdirectory(module-services) message("${PROJECT_NAME}: add_subdirectory module-apps") add_subdirectory(module-apps) message("${PROJECT_NAME}: add_subdirectory module-bluetooth") add_subdirectory(module-bluetooth) message("${PROJECT_NAME}: add_subdirectory module-lwip") add_subdirectory(module-lwip) add_subdirectory(image) set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES SUFFIX ".elf") @@ 184,6 191,9 @@ target_link_libraries(${PROJECT_NAME} module-gui module-services module-apps module-bluetooth ${LWIP_LIBRARIES} module-lwip ${TARGET_LIBRARIES} )
M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +4 -0
@@ 11,6 11,7 @@ #include "MessageType.hpp" #include "windows/SettingsMainWindow.hpp" #include "windows/LanguageWindow.hpp" #include "windows/BtWindow.hpp" #include "windows/DateTimeWindow.hpp" #include "windows/FotaWindow.hpp" #include "windows/Info.hpp" @@ 95,6 96,9 @@ namespace app window = new gui::LanguageWindow(this); windows.insert(std::pair<std::string, gui::AppWindow *>(window->getName(), window)); window = new gui::BtWindow(this); windows.insert(std::pair<std::string, gui::AppWindow *>(window->getName(), window)); window = new gui::UiTestWindow(this); windows.insert(std::pair<std::string, gui::AppWindow *>(window->getName(), window));
M module-apps/application-settings/CMakeLists.txt => module-apps/application-settings/CMakeLists.txt +1 -0
@@ 17,6 17,7 @@ target_sources( ${PROJECT_NAME} ApplicationSettings.cpp windows/SettingsMainWindow.cpp windows/LanguageWindow.cpp windows/BtWindow.cpp windows/UITestWindow.cpp windows/Info.cpp
A module-bluetooth/Bluetooth/BluetoothWorker.cpp => module-bluetooth/Bluetooth/BluetoothWorker.cpp +171 -0
@@ 0,0 1,171 @@ #include "BluetoothWorker.hpp" #include "log/log.hpp" #include "BtCommand.hpp" using namespace bsp; const char *c_str(Bt::Error::Code code) { switch (code) { case Bt::Error::Code::Succes: return "Succes"; case Bt::Error::Code::NotReady: return "NotReady"; case Bt::Error::Code::SystemError: return "SystemError"; case Bt::Error::Code::LibraryError: return "LibraryError"; } return ""; } BluetoothWorker::BluetoothWorker(sys::Service *service) : Worker(service) { init({ {"qBtIO", sizeof(Bt::Message), 10}, {"qBtWork", sizeof(Bt::EvtWorker), 10}, }); }; BluetoothWorker::~BluetoothWorker() { if (this->bt_worker_task != nullptr) {} LOG_INFO("Worker removed"); } bool BluetoothWorker::run() { LOG_INFO("-> BluetoothWorker run request"); if (is_running) { return true; } if (Worker::run()) { is_running = true; auto el = queues[queueIO_handle]; BlueKitchen::getInstance()->qHandle = el; Bt::initialize_stack(); Bt::register_hw_error_callback(); Bt::GAP::register_scan(); std::string name = "PurePhone"; Bt::set_name(name); // set local namne // set discoverable (on) // Bt::GAP:: Bt::run_stack(&this->bt_worker_task); return true; } else { return false; } } bool BluetoothWorker::scan() { std::vector<Device> empty; auto ret = Bt::GAP::scan(); if (ret.err != Bt::Error::Succes) { LOG_ERROR("Cant start scan!: %s %" PRIu32 "", c_str(ret.err), ret.lib_code); return false; } else { LOG_INFO("Scan started!"); return true; } } bool BluetoothWorker::set_visible() { LOG_ERROR("TODO"); return false; } bool BluetoothWorker::start_pan() { Bt::PAN::bnep_setup(); auto err = Bt::PAN::bnep_start(); if (err.err != Bt::Error::Succes) { LOG_ERROR("PAN setup error: %s %" PRIu32, c_str(err.err), err.lib_code); } return false; } BluetoothWorker::Error BluetoothWorker::aud_init() { LOG_INFO("%s", __PRETTY_FUNCTION__); Error err = SuccessBt; LOG_INFO("AUDIO - TODO"); // start GAVD // && ASSIGN_CLASS_OF_DEVICE(ClassOfDevice, 0x28, 0x04, 0x10); return err; } #include <sstream> bool BluetoothWorker::handleMessage(uint32_t queueID) { QueueHandle_t queue = queues[queueID]; if (queueID == queueService) { LOG_DEBUG("not interested"); return true; } if (queueID != queueIO_handle) { LOG_ERROR("Wrong queue! %" PRIu32, queueID); return false; } Bt::Message notification = Bt::Message::EvtErrorRec; if (xQueueReceive(queue, ¬ification, 0) != pdTRUE) { LOG_ERROR("Receive failure!"); return false; } auto bt = BlueKitchen::getInstance(); switch (notification) { case Bt::Message::EvtSent: #ifdef DO_DEBUG_HCI_COMS LOG_INFO("[evt] sent"); #endif if (bt->write_done_cb) { bt->write_done_cb(); } break; case Bt::Message::EvtReceived: { if (bt->to_read_req > bt->in.len) { // LOG_ERROR("%d vs %d", bt->to_read_req, bt->in.len); break; } for (int i = 0; i < bt->to_read_req; ++i) { // error in pop should never happen if (int ret = bt->in.pop((char *)bt->read_buff + i)) { LOG_ERROR("This shall never happen: %d", ret); } } // LOG_DEBUG(">> %d",bt->in.len); #ifdef DO_DEBUG_HCI_COMS std::stringstream ss; for (int i = 0; i < bt->to_read_req; ++i) { ss << " 0x" << std::hex << (int)*(bt->read_buff + i); } LOG_DEBUG("[evt] recieved <-- [%d]>%s<", bt->to_read_req, ss.str().c_str()); #endif bt->to_read_req = 0; if (bt->read_ready_cb) { bt->read_ready_cb(); } } break; case Bt::Message::EvtSentError: case Bt::Message::EvtRecError: case Bt::Message::EvtUartError: case Bt::Message::EvtRecUnwanted: { LOG_ERROR("Uart error [%d]: %s", notification, Bt::MessageCstr(notification)); break; } break; default: LOG_ERROR("ERROR"); } return true; }
A module-bluetooth/Bluetooth/BluetoothWorker.hpp => module-bluetooth/Bluetooth/BluetoothWorker.hpp +98 -0
@@ 0,0 1,98 @@ #pragma once #include <FreeRTOS.h> #include <task.h> #include <bsp/bluetooth/Bluetooth.hpp> #include <memory> #include <vector> #include "Device.hpp" #include "Service/Worker.hpp" struct HCI; /// debug option for HCI (uart) commands debugging // #define DO_DEBUG_HCI_COMS namespace Bt { enum Message : uint8_t { /// asynchronous messages to use on event from irq EvtSent, /// trigger Bt stack wrote, enable writting in HCI in BluetoothWorker task EvtRecUnwanted, /// not requested recieve - probably receive came to fast from sent... EvtRecError, /// bsp error on receive EvtSentError, /// bsp error on send EvtUartError, /// generic uart error EvtReceived, /// trigger Bt stack received, start processing HCI in BluetoothWorker task EvtErrorRec, /// there was error o queue receive }; inline const char *MessageCstr(Message what) { switch (what) { case EvtReceived: return "EvtReceived"; case EvtSent: return "EvtSent"; case EvtRecUnwanted: return "EvtRecUnwanted"; case EvtRecError: return "EvtRecError"; case EvtSentError: return "EvtSentError"; case EvtUartError: return "EvtUartError"; case EvtErrorRec: return "EvtErrorRec"; default: return ""; } } struct EvtWorker { enum Evt : uint8_t { }; }; }; // namespace Bt class BluetoothWorker : private sys::Worker { enum WorkerEventQueues { queueService = 0, queueIO_handle, /// bsp support queue queue_profiles, /// queue for communication between profile workers, /// main bt_worker_task should dispatch these in events }; TaskHandle_t bt_worker_task = nullptr; int is_running = false; public: enum Error { SuccessBt, ErrorBtGeneric, ErrorBtAPI, }; BluetoothWorker(sys::Service *service); virtual ~BluetoothWorker(); virtual bool handleMessage(uint32_t queueID); bool run(); bool scan(); bool set_visible(); bool start_pan(); Error aud_init(); /// bluetooth stack id in use unsigned long active_features; };
A module-bluetooth/Bluetooth/BtCommand.hpp => module-bluetooth/Bluetooth/BtCommand.hpp +26 -0
@@ 0,0 1,26 @@ #pragma once #include <FreeRTOS.h> #include <task.h> #include "BluetoothWorker.hpp" #include "Error.hpp" #include <functional> namespace Bt { Error initialize_stack(); Error register_hw_error_callback(std::function<void(uint8_t)> new_callback = nullptr); Error set_name(std::string &name); Error run_stack(TaskHandle_t *handle); namespace GAP { /// THIS have to be called prior to Bt system start! Error register_scan(); Error scan(); }; // namespace GAP namespace PAN { Error bnep_start(); Error bnep_setup(); } // namespace PAN }; // namespace Bt
A module-bluetooth/Bluetooth/Device.hpp => module-bluetooth/Bluetooth/Device.hpp +11 -0
@@ 0,0 1,11 @@ #pragma once #include <string> struct Device { public: Device(std::string name = "") : name(name) {} virtual ~Device(){}; std::string name; };
A module-bluetooth/Bluetooth/Error.hpp => module-bluetooth/Bluetooth/Error.hpp +25 -0
@@ 0,0 1,25 @@ #pragma once #include <cstdint> #include <variant> #include <optional> namespace Bt { struct Error { enum Code { Succes, NotReady, SystemError, LibraryError, } err = Succes; uint32_t lib_code = 0; Error(enum Code err = Succes, int lib_code = Succes) : err(err), lib_code(0) {} }; } // namespace Bt const char *c_str(Bt::Error::Code code);
A module-bluetooth/Bluetooth/Stack.hpp => module-bluetooth/Bluetooth/Stack.hpp +8 -0
A module-bluetooth/Bluetooth/glucode/HCITRANS.cpp => module-bluetooth/Bluetooth/glucode/HCITRANS.cpp +123 -0
@@ 0,0 1,123 @@ #include <bsp/bluetooth/Bluetooth.hpp> #include "log/log.hpp" using namespace bsp; extern "C" { #include "HCITRANS.h" #define TRANSPORT_ID 1 typedef void(BTPSAPI *HCITR_COMDataCallback_t)(unsigned int HCITransportID, unsigned int DataLength, unsigned char *DataBuffer, unsigned long CallbackParameter); void RxThread(void *Param); int BTPSAPI HCITR_COMOpen(HCI_COMMDriverInformation_t *COMMDriverInformation, HCITR_COMDataCallback_t COMDataCallback, unsigned long CallbackParameter) { int ret = TRANSPORT_ID; LOG_INFO("COM OPEN!"); Bluetopia *bt = Bluetopia::getInstance(); bt->set_reset(true); bt->open(); bt->com_cb = COMDataCallback; bt->com_cb_param = CallbackParameter; bt->rx_thread = xTaskCreate(RxThread, "RxThread", 4096, NULL, 3, &bt->thandle); if (bt->rx_thread != pdPASS) { ret = ErrorBtGeneric; LOG_ERROR("COM OPEN failure: %d", bt->rx_thread); } LOG_INFO("COM OPEN! done"); return ret; } void BTPSAPI HCITR_COMClose(unsigned int HCITransportID) { LOG_ERROR("COM CLOSE"); Bluetopia *dev = Bluetopia::getInstance(); if (dev->thandle != NULL) { // vTaskDelete(bt->thandle); } dev->close(); dev->set_reset(false); if (dev->com_cb) { dev->com_cb(TRANSPORT_ID, 0, NULL, dev->com_cb_param); } LOG_ERROR("COM CLOSED"); } void BTPSAPI HCITR_COMReconfigure(unsigned int HCITransportID, HCI_Driver_Reconfigure_Data_t *DriverReconfigureData) { HCI_COMMReconfigureInformation_t *ReconfigureInformation; Bluetopia *dev = Bluetopia::getInstance(); if ((HCITransportID == TRANSPORT_ID) && dev->is_open && (DriverReconfigureData)) { if ((DriverReconfigureData->ReconfigureCommand == HCI_COMM_DRIVER_RECONFIGURE_DATA_COMMAND_CHANGE_COMM_PARAMETERS) && (DriverReconfigureData->ReconfigureData)) { ReconfigureInformation = (HCI_COMMReconfigureInformation_t *)(DriverReconfigureData->ReconfigureData); if (ReconfigureInformation->ReconfigureFlags & HCI_COMM_RECONFIGURE_INFORMATION_RECONFIGURE_FLAGS_CHANGE_BAUDRATE) { LOG_INFO("Set baudrate to: %d", ReconfigureInformation->BaudRate); dev->set_irq(false); dev->set_baudrate(ReconfigureInformation->BaudRate); dev->set_irq(true); } } } } int BTPSAPI HCITR_COMWrite(unsigned int HCITransportID, unsigned int Length, unsigned char *Buffer) { int ret = 0; // LOG_INFO("DATA -> [%d]", Length); if (HCITransportID) { ret = Bluetopia::getInstance()->write_blocking(reinterpret_cast<char *>(Buffer), Length); } else { ret = -1; } return ret; } int BTPSAPI HCITR_COMSuspend(unsigned int HCITransportID) { LOG_ERROR("Not implemented!"); int ret = -1; if (HCITransportID) {} else { ret = -1; } return ret; } int BTPSAPI HCITR_EnableDebugLogging(Boolean_t Enable) { return 0; } void RxThread(void *Param) { LOG_INFO("BT RxThread created"); Bluetopia *dev = Bluetopia::getInstance(); while (dev->is_open) { dev->wait_data(); dev->set_irq(false); // LOG_INFO("DATA [%d]<--", dev->in.len); // for(int i=0; i<dev->in.len; ++i) { // LOG_PRINTF("0x%X ", dev->in.buff[i]); // } // LOG_PRINTF("\n"); if (dev->com_cb) { dev->com_cb(TRANSPORT_ID, dev->in.len, (unsigned char *)dev->in.buff, dev->com_cb_param); } dev->in.flush(); dev->set_irq(true); dev->set_rts(true); } } };
A module-bluetooth/Bluetooth/glucode/bluetooth_init_cc2564C_1.0.c => module-bluetooth/Bluetooth/glucode/bluetooth_init_cc2564C_1.0.c +3939 -0
@@ 0,0 1,3939 @@ // init script created from // - initscripts-TIInit_6.12.26_v1.0.bts // - AKA TIInit_6.12.26.bts // - initscripts-TIInit_6.12.26_ble_add-on_v1.0.bts #include <stdint.h> #include "btstack_chipset_cc256x.h" const uint16_t cc256x_init_script_lmp_subversion = 0x9a1a; uint16_t btstack_chipset_cc256x_lmp_subversion(void) { return cc256x_init_script_lmp_subversion; } #if defined(__GNUC__) && defined(__MSP430X__) && (__MSP430X__ > 0) __attribute__((section(".fartext"))) #endif #ifdef __AVR__ __attribute__((__progmem__)) #endif const uint8_t cc256x_init_script[] = { // #-------------------------------------------------------------------------------- // # Description : Orca C ROM Initialization Script // # // # Compatibility: Orca, 12.0.26 ROM // # // # Last Updated: 29-Sep-2016 14:08:47.69 // # // # Version : 12_26.12 // # // # // # // # // # Notes : Use this script on Orca C, 12.0.26 ROM device only (FW v12.0.26) // #-------------------------------------------------------------------------------- // // ################################################################# // ## START of CC256x Add-On // ################################################################# // // ## Change UART baudrate // // ################################################################# // ## END of CC256x Add-On // ################################################################# // 0x01, 0x37, 0xfe, 0x02, 0x0c, 0x1a, // // 0x01, 0x05, 0xff, 0xff, 0xd0, 0x65, 0x08, 0x00, 0xfa, 0x0c, 0x1a, 0x09, 0x0c, 0x01, 0x6a, 0xc8, 0x7b, 0x00, 0x02, 0x89, 0x7b, 0x01, 0x43, 0x09, 0x48, 0x51, 0x30, 0x02, 0x88, 0x06, 0x48, 0x91, 0x42, 0x03, 0xd1, 0x04, 0x49, 0x09, 0x78, 0x01, 0x29, 0x01, 0xd0, 0x5d, 0x30, 0xf7, 0x46, 0xff, 0x30, 0xd8, 0x30, 0xf7, 0x46, 0x76, 0x24, 0x08, 0x00, 0xbd, 0x28, 0x02, 0x00, 0x69, 0x53, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x69, 0xff, 0x21, 0x02, 0x31, 0x09, 0x5c, 0x09, 0x29, 0x05, 0xd1, 0x01, 0x21, 0x00, 0x22, 0x8e, 0x46, 0xcb, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0xbd, 0xca, 0x4a, 0x11, 0x88, 0x01, 0x20, 0x40, 0x03, 0x08, 0x43, 0x10, 0x80, 0xf7, 0x46, 0x30, 0xb5, 0x00, 0x69, 0xf4, 0x21, 0x08, 0x5c, 0x01, 0x28, 0x16, 0xd1, 0xc5, 0x48, 0x00, 0x78, 0x03, 0x28, 0x12, 0xd0, 0x00, 0x25, 0x28, 0x1c, 0xc3, 0x49, 0x01, 0x24, 0xa6, 0x46, 0xc2, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0x08, 0xd0, 0xc1, 0x49, 0xc1, 0x4a, 0xbb, 0x32, 0x20, 0x20, 0x2b, 0x1c, 0xa6, 0x46, 0xc0, 0x4c, 0xfe, 0x44, 0x20, 0x47, 0x30, 0xbd, 0x70, 0xb5, 0x85, 0x69, 0x00, 0x7d, 0x80, 0x1f, 0x11, 0xd0, 0x47, 0x38, 0x2e, 0xd1, 0xa9, 0x79, 0x28, 0x20, 0x48, 0x43, 0xba, 0x4a, 0x10, 0x18, 0x23, 0x22, 0x12, 0x5c, 0x01, 0x2a, 0x25, 0xd1, 0x80, 0x7b, 0x00, 0x28, 0x22, 0xd0, 0xb6, 0x4a, 0x00, 0x20, 0x50, 0x54, 0x70, 0xbd, 0x01, 0x24, 0xa6, 0x46, 0xef, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x01, 0x05, 0xff, 0xff, 0xca, 0x66, 0x08, 0x00, 0xfa, 0x01, 0x28, 0x05, 0xd0, 0xa6, 0x46, 0xec, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x04, 0x28, 0x11, 0xd1, 0xe8, 0x78, 0x00, 0x28, 0x0e, 0xd1, 0x0e, 0x26, 0x31, 0x1c, 0xe9, 0x4d, 0x28, 0x1c, 0x14, 0x38, 0xa6, 0x46, 0xe6, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x28, 0x1c, 0x31, 0x1c, 0xa6, 0x46, 0xe3, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x70, 0xbd, 0x70, 0xb5, 0x01, 0x1c, 0x88, 0x69, 0x89, 0x8a, 0xe1, 0x4a, 0x89, 0x1a, 0x1c, 0xd0, 0x1c, 0x39, 0x20, 0xd1, 0xc5, 0x7a, 0x01, 0x21, 0x0c, 0x1c, 0x8e, 0x46, 0xde, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x06, 0x1c, 0x10, 0x20, 0xa6, 0x46, 0xdc, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x00, 0x2d, 0x11, 0xd0, 0x02, 0x2e, 0x0f, 0xd0, 0xd9, 0x49, 0xda, 0x4a, 0xd9, 0x32, 0x20, 0x20, 0x00, 0x23, 0xa6, 0x46, 0x92, 0x4c, 0xfe, 0x44, 0x20, 0x47, 0x70, 0xbd, 0xc0, 0x7a, 0x00, 0x28, 0x02, 0xd1, 0x00, 0x20, 0xd4, 0x49, 0x08, 0x70, 0x70, 0xbd, 0x00, 0xb5, 0x00, 0x69, 0xff, 0x21, 0x04, 0x31, 0x09, 0x5c, 0x06, 0x29, 0x06, 0xd1, 0xff, 0x21, 0x05, 0x31, 0x0a, 0x5c, 0x2c, 0x2a, 0x01, 0xd1, 0x2d, 0x22, 0x0a, 0x54, 0xff, 0x21, 0x05, 0x31, 0x09, 0x5c, 0x34, 0x29, 0x11, 0xd1, 0xff, 0x21, 0x0b, 0x31, 0x09, 0x5c, 0x91, 0x29, 0x0c, 0xd1, 0xf1, 0x21, 0x09, 0x5c, 0x60, 0x22, 0x4a, 0x43, 0xc6, 0x4b, 0x00, 0x21, 0x99, 0x54, 0x06, 0x21, 0x01, 0x22, 0x96, 0x46, 0xc4, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0xbd, 0xf0, 0xb5, 0x06, 0x1c, 0xf7, 0x69, 0x08, 0x20, 0xc0, 0x19, 0x01, 0x24, 0xa6, 0x46, 0xbf, 0x49, 0xfe, 0x44, 0x08, 0x47, 0xc1, 0x7b, 0x09, 0x02, 0x80, 0x7b, 0x08, 0x43, 0x05, 0x04, 0x2d, 0x0c, 0x02, 0x2d, 0x01, 0x05, 0xff, 0xff, 0xc4, 0x67, 0x08, 0x00, 0xfa, 0x12, 0xd0, 0xbb, 0x48, 0x00, 0x88, 0xa8, 0x42, 0x0e, 0xd1, 0xba, 0x48, 0x00, 0x78, 0x01, 0x28, 0x0a, 0xd1, 0xb9, 0x48, 0x82, 0x8f, 0x81, 0x6b, 0x08, 0x1c, 0x10, 0x43, 0x04, 0xd0, 0x38, 0x1c, 0xa6, 0x46, 0xb6, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x35, 0x60, 0xb5, 0x48, 0x24, 0x30, 0x30, 0x62, 0xf0, 0xbd, 0xf0, 0xb5, 0x85, 0xb0, 0x04, 0x90, 0x87, 0x69, 0x81, 0x8a, 0xb1, 0x48, 0x08, 0x1a, 0x74, 0xd0, 0xb1, 0x49, 0x40, 0x1a, 0x28, 0xd0, 0xb0, 0x49, 0x40, 0x1a, 0x1d, 0xd1, 0xb0, 0x48, 0x05, 0x1c, 0x84, 0x3d, 0x00, 0x78, 0x02, 0x28, 0x17, 0xd1, 0x01, 0x24, 0xa6, 0x46, 0xad, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x00, 0x28, 0x10, 0xd1, 0xa6, 0x46, 0xab, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x00, 0x28, 0x0a, 0xd1, 0xa6, 0x46, 0xa9, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x00, 0x28, 0x04, 0xd1, 0x28, 0x78, 0x00, 0x28, 0x01, 0xd1, 0xa8, 0x78, 0x00, 0x28, 0x00, 0xd0, 0x8b, 0xe0, 0xa6, 0x20, 0xa6, 0x46, 0xa3, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x85, 0xe0, 0x95, 0x48, 0x51, 0x38, 0x00, 0x78, 0x2a, 0x28, 0x7c, 0xd1, 0x0e, 0x20, 0xc6, 0x19, 0x44, 0x20, 0x0c, 0x21, 0x1a, 0x22, 0x01, 0x24, 0xa6, 0x46, 0x9c, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x9b, 0x48, 0x81, 0x78, 0xc2, 0x78, 0x9b, 0x48, 0xa6, 0x46, 0x9b, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x06, 0x20, 0xb8, 0x80, 0x08, 0x25, 0x35, 0x70, 0x01, 0x36, 0x30, 0x1c, 0x00, 0x21, 0xa6, 0x46, 0x96, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x06, 0x1c, 0x35, 0x70, 0x01, 0x36, 0x30, 0x1c, 0x0d, 0x21, 0xa6, 0x46, 0x92, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x06, 0x1c, 0xa6, 0x46, 0x91, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x01, 0x05, 0xff, 0xff, 0xbe, 0x68, 0x08, 0x00, 0xfa, 0x81, 0x02, 0x8a, 0x48, 0xc0, 0x78, 0x40, 0x06, 0x40, 0x0e, 0x08, 0x43, 0x8c, 0x49, 0x01, 0x43, 0x09, 0x04, 0x09, 0x0c, 0x30, 0x1c, 0xa6, 0x46, 0x88, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x7d, 0x80, 0x38, 0x1c, 0xff, 0x21, 0x02, 0x31, 0x00, 0x22, 0xa6, 0x46, 0x86, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x38, 0xe0, 0x38, 0x1c, 0x00, 0x21, 0x6a, 0x46, 0x01, 0x24, 0xa6, 0x46, 0x84, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x02, 0xa8, 0x00, 0x21, 0x06, 0x22, 0xa6, 0x46, 0x81, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x25, 0x02, 0xe0, 0x68, 0x1c, 0x05, 0x04, 0x2d, 0x0c, 0x66, 0x48, 0x4f, 0x38, 0x00, 0x78, 0x85, 0x42, 0x23, 0xda, 0x11, 0x20, 0x40, 0x01, 0x68, 0x43, 0x7a, 0x49, 0x0e, 0x18, 0x10, 0x20, 0x80, 0x19, 0x69, 0x46, 0xa6, 0x46, 0x78, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0xe9, 0xd1, 0x68, 0x46, 0x02, 0xa9, 0xa6, 0x46, 0x74, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0xe1, 0xd0, 0xb0, 0x78, 0x01, 0x28, 0xde, 0xd0, 0x38, 0x1c, 0x5c, 0x49, 0x3a, 0x22, 0xa6, 0x46, 0x6f, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x69, 0x49, 0xe2, 0x31, 0x04, 0x98, 0x01, 0x62, 0x05, 0xb0, 0xf0, 0xbd, 0xc0, 0x46, 0xdd, 0x9d, 0x00, 0x00, 0x3e, 0xa6, 0x1b, 0x00, 0x18, 0x32, 0x08, 0x00, 0xce, 0x04, 0x00, 0x00, 0x23, 0xb9, 0x02, 0x00, 0xf1, 0x6b, 0x08, 0x00, 0xfd, 0x79, 0x00, 0x00, 0x35, 0x6b, 0x08, 0x00, 0xd4, 0x1d, 0x08, 0x00, 0x94, 0x54, 0x08, 0x00, 0xfe, 0xb5, 0x00, 0x90, 0x81, 0x69, 0x01, 0x91, 0x4c, 0x78, 0xc6, 0x69, 0x25, 0x20, 0x20, 0x1a, 0x5d, 0x49, 0x32, 0xd0, 0x01, 0x38, 0x68, 0xd1, 0x05, 0x23, 0x03, 0x20, 0x1a, 0x1c, 0x01, 0x25, 0x01, 0x05, 0xff, 0xff, 0xb8, 0x69, 0x08, 0x00, 0xfa, 0xae, 0x46, 0x5a, 0x4f, 0xfe, 0x44, 0x38, 0x47, 0x04, 0x20, 0xb0, 0x80, 0x0c, 0x20, 0x87, 0x19, 0x61, 0x00, 0x01, 0x98, 0x00, 0x78, 0x08, 0x43, 0x38, 0x70, 0x08, 0x20, 0x78, 0x70, 0x02, 0x37, 0x38, 0x1c, 0x0d, 0x21, 0xae, 0x46, 0x46, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x07, 0x1c, 0xae, 0x46, 0x45, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x82, 0x02, 0x4d, 0x48, 0x00, 0x78, 0x40, 0x06, 0x41, 0x0e, 0x11, 0x43, 0x40, 0x48, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xae, 0x46, 0x3c, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x03, 0x20, 0x02, 0x90, 0x2e, 0xe0, 0x03, 0x20, 0x02, 0x90, 0x04, 0x22, 0x13, 0x1c, 0x01, 0x25, 0xae, 0x46, 0x41, 0x4f, 0xfe, 0x44, 0x38, 0x47, 0x04, 0x20, 0xb0, 0x80, 0x0c, 0x20, 0x87, 0x19, 0x61, 0x00, 0x01, 0x98, 0x00, 0x78, 0x08, 0x43, 0x38, 0x70, 0x08, 0x20, 0x78, 0x70, 0x02, 0x37, 0x38, 0x1c, 0x0d, 0x21, 0xae, 0x46, 0x2d, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x07, 0x1c, 0xae, 0x46, 0x2c, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x82, 0x02, 0x34, 0x48, 0x00, 0x78, 0x40, 0x06, 0x41, 0x0e, 0x11, 0x43, 0x27, 0x48, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xae, 0x46, 0x23, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x06, 0x20, 0x70, 0x80, 0x02, 0x98, 0x30, 0x80, 0x2d, 0x48, 0x2c, 0x49, 0x09, 0x18, 0x00, 0x98, 0x01, 0x62, 0xfe, 0xbd, 0x8f, 0x8d, 0x01, 0x00, 0xfd, 0x06, 0x05, 0x00, 0x14, 0x05, 0x1a, 0x00, 0xa2, 0xfd, 0x00, 0x00, 0x65, 0x2d, 0x00, 0x00, 0x7d, 0xca, 0x03, 0x00, 0x31, 0x6c, 0x08, 0x00, 0x79, 0x47, 0x00, 0x00, 0x78, 0x24, 0x08, 0x00, 0x76, 0xa0, 0x1b, 0x00, 0xc5, 0x8e, 0x00, 0x00, 0x5b, 0x19, 0x01, 0x05, 0xff, 0xff, 0xb2, 0x6a, 0x08, 0x00, 0xfa, 0x04, 0x00, 0xba, 0x53, 0x08, 0x00, 0x90, 0xa1, 0x1b, 0x00, 0xa8, 0x59, 0x08, 0x00, 0x25, 0x6f, 0x04, 0x00, 0x79, 0x6c, 0x04, 0x00, 0x05, 0x04, 0x00, 0x00, 0xfc, 0x0b, 0x00, 0x00, 0x1d, 0x10, 0x00, 0x00, 0x45, 0x10, 0x08, 0x00, 0xc1, 0x72, 0x03, 0x00, 0x1b, 0x5f, 0x03, 0x00, 0x53, 0x38, 0x02, 0x00, 0x21, 0xf0, 0x04, 0x00, 0xdb, 0x8e, 0x04, 0x00, 0xfc, 0x53, 0x08, 0x00, 0xc6, 0x02, 0x00, 0x00, 0x8d, 0x8f, 0x04, 0x00, 0xf9, 0x2d, 0x00, 0x00, 0x00, 0x82, 0xff, 0xff, 0xa9, 0x57, 0x05, 0x00, 0xed, 0x49, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x99, 0x2d, 0x00, 0x00, 0xe9, 0x63, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x49, 0x8f, 0x03, 0x00, 0x85, 0x48, 0x02, 0x00, 0xc5, 0x05, 0x00, 0x00, 0x31, 0x90, 0x04, 0x00, 0xff, 0x53, 0x08, 0x00, 0x4e, 0x05, 0x00, 0x00, 0xb5, 0xcc, 0x00, 0x00, 0x40, 0x1e, 0x80, 0x00, 0x8c, 0x4b, 0x19, 0x50, 0x8a, 0x49, 0x0a, 0x50, 0xf7, 0x46, 0xf0, 0xb5, 0x01, 0x1c, 0x88, 0x69, 0x82, 0x88, 0x53, 0x04, 0x5b, 0x0c, 0x88, 0x4e, 0x88, 0x4f, 0x89, 0x4d, 0x03, 0xd0, 0x60, 0x2b, 0x01, 0xdc, 0xb2, 0x42, 0x14, 0xd0, 0x82, 0x88, 0x01, 0x23, 0x1b, 0x03, 0x54, 0x04, 0x64, 0x0f, 0x24, 0x03, 0x9c, 0x42, 0x08, 0xdb, 0x3b, 0x1c, 0x01, 0x33, 0x54, 0x04, 0x24, 0x0d, 0xe4, 0x00, 0x9c, 0x42, 0x01, 0xda, 0xba, 0x42, 0x03, 0xd0, 0xff, 0x20, 0x88, 0x60, 0xe8, 0x1d, 0xf0, 0xbd, 0x01, 0x24, 0xa6, 0x46, 0x7b, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x38, 0x1c, 0xa6, 0x46, 0x7a, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x30, 0x1c, 0xa6, 0x46, 0x77, 0x49, 0xfe, 0x44, 0x08, 0x47, 0xa6, 0x46, 0x76, 0x48, 0xfe, 0x44, 0x01, 0x05, 0xff, 0xff, 0xac, 0x6b, 0x08, 0x00, 0xfa, 0x00, 0x47, 0x38, 0x1c, 0xa6, 0x46, 0x73, 0x49, 0xfe, 0x44, 0x08, 0x47, 0xe8, 0x48, 0x01, 0x68, 0x30, 0x1c, 0xa6, 0x46, 0x71, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x71, 0x48, 0x40, 0x19, 0xf0, 0xbd, 0x01, 0x1c, 0x0a, 0x7d, 0x6f, 0x48, 0x00, 0x2a, 0x02, 0xd0, 0xc9, 0x68, 0x01, 0x29, 0x01, 0xd0, 0x4f, 0x30, 0xf7, 0x46, 0x31, 0x30, 0xf7, 0x46, 0x41, 0x68, 0x02, 0x39, 0x41, 0x60, 0xe9, 0x48, 0x3f, 0x30, 0xf7, 0x46, 0x1c, 0xb5, 0x41, 0x68, 0xe7, 0x4c, 0x00, 0x29, 0x17, 0xd0, 0x41, 0x69, 0xb0, 0x20, 0x40, 0x18, 0xb8, 0x31, 0x6a, 0x46, 0x01, 0x23, 0x9e, 0x46, 0xe9, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x99, 0xe8, 0x48, 0xe4, 0x38, 0x41, 0x43, 0x68, 0x46, 0x80, 0x88, 0x41, 0x18, 0xff, 0x20, 0xae, 0x30, 0x81, 0x42, 0x02, 0xd9, 0x20, 0x1c, 0xbf, 0x30, 0x1c, 0xbd, 0x20, 0x1c, 0xdf, 0x30, 0x1c, 0xbd, 0x10, 0xb5, 0x04, 0x1c, 0xc8, 0x68, 0x0a, 0x21, 0x01, 0x22, 0x96, 0x46, 0xde, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0x00, 0xd1, 0x8c, 0x20, 0xa0, 0x60, 0xdc, 0x48, 0xdb, 0x30, 0x10, 0xbd, 0xdc, 0x49, 0x04, 0x39, 0x09, 0x78, 0x00, 0x29, 0x01, 0xd1, 0x00, 0x21, 0x41, 0x60, 0x41, 0x68, 0x42, 0x69, 0x51, 0x1a, 0x41, 0x60, 0xd6, 0x48, 0x55, 0x30, 0xf7, 0x46, 0xd6, 0x49, 0x09, 0x78, 0x00, 0x29, 0x04, 0xd1, 0x01, 0x7d, 0xd3, 0x48, 0x02, 0x30, 0xff, 0x22, 0x42, 0x54, 0xd3, 0x48, 0x4f, 0x30, 0xf7, 0x46, 0x01, 0x1c, 0x8a, 0x69, 0x4b, 0x68, 0xd1, 0x48, 0x9a, 0x42, 0x01, 0xd9, 0x3b, 0x30, 0xf7, 0x46, 0xca, 0x60, 0x79, 0x30, 0xf7, 0x46, 0xcf, 0x48, 0xcd, 0x49, 0x08, 0x80, 0xce, 0x48, 0xff, 0x30, 0xde, 0x30, 0x01, 0x05, 0xff, 0xff, 0xa6, 0x6c, 0x08, 0x00, 0xfa, 0xf7, 0x46, 0xc2, 0x69, 0xff, 0x21, 0x11, 0x31, 0x8b, 0x5c, 0xcb, 0x49, 0x5b, 0x08, 0x08, 0xd3, 0xff, 0x23, 0x02, 0x33, 0x9a, 0x5c, 0x02, 0x2a, 0x03, 0xd0, 0x01, 0x2a, 0x01, 0xd0, 0x03, 0x2a, 0x02, 0xd1, 0x08, 0x1c, 0x5b, 0x30, 0xf7, 0x46, 0xff, 0x22, 0x42, 0x60, 0x08, 0x1c, 0x39, 0x30, 0xf7, 0x46, 0x00, 0xb5, 0x40, 0x68, 0x01, 0x21, 0x8e, 0x46, 0xc0, 0x49, 0xfe, 0x44, 0x08, 0x47, 0xc0, 0x48, 0x57, 0x30, 0x00, 0xbd, 0x02, 0x8a, 0x01, 0x79, 0x0a, 0x29, 0x00, 0xdb, 0x0a, 0x21, 0xbd, 0x48, 0x8a, 0x42, 0x01, 0xdd, 0x5f, 0x30, 0xf7, 0x46, 0x5b, 0x30, 0xf7, 0x46, 0xf0, 0xb5, 0x01, 0x24, 0xa6, 0x46, 0xb9, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x01, 0x28, 0x05, 0xd0, 0xa6, 0x46, 0xb6, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x04, 0x28, 0x19, 0xd1, 0x02, 0x26, 0xb4, 0x4d, 0x28, 0x79, 0x00, 0x28, 0x11, 0xd0, 0xe8, 0x7a, 0x06, 0x28, 0x0e, 0xd1, 0x0e, 0x20, 0x01, 0x1c, 0xb1, 0x4f, 0x38, 0x1c, 0x14, 0x38, 0xa6, 0x46, 0xae, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x38, 0x1c, 0x0e, 0x21, 0xa6, 0x46, 0xab, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x70, 0x35, 0x01, 0x3e, 0xe7, 0xd1, 0xa6, 0x46, 0xaa, 0x48, 0xfe, 0x44, 0x00, 0x47, 0xa9, 0x49, 0x0b, 0x48, 0x54, 0x30, 0x40, 0x18, 0xf0, 0xbd, 0xc0, 0x46, 0x04, 0xf3, 0x1a, 0x00, 0x80, 0x7b, 0x08, 0x00, 0x03, 0x80, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0xc9, 0xfb, 0x04, 0x00, 0xbb, 0x15, 0x04, 0x00, 0x7d, 0xca, 0x03, 0x00, 0x05, 0x43, 0x02, 0x00, 0x0b, 0xc9, 0x03, 0x00, 0xab, 0x02, 0x00, 0x00, 0xb1, 0x33, 0x02, 0x00, 0xf0, 0xb5, 0x8d, 0xb0, 0x01, 0x90, 0x81, 0x69, 0x02, 0x91, 0x01, 0x7d, 0x01, 0x05, 0xff, 0xff, 0xa0, 0x6d, 0x08, 0x00, 0xfa, 0x03, 0x91, 0x42, 0x68, 0x00, 0x92, 0x80, 0x8b, 0x40, 0x00, 0x04, 0x90, 0x6b, 0x48, 0x83, 0x30, 0x00, 0x78, 0x40, 0x00, 0x05, 0x90, 0x00, 0x29, 0x01, 0xd1, 0x00, 0x20, 0xe1, 0xe0, 0x04, 0x98, 0x02, 0x04, 0x12, 0x0c, 0x06, 0x92, 0x02, 0x98, 0x03, 0x99, 0x6b, 0x46, 0x01, 0x24, 0xa6, 0x46, 0x8e, 0x4d, 0xfe, 0x44, 0x28, 0x47, 0x07, 0x90, 0x00, 0x9e, 0x00, 0x20, 0x08, 0x90, 0x7e, 0x48, 0x09, 0x90, 0x0a, 0x90, 0x7f, 0xe0, 0x09, 0x98, 0x00, 0x28, 0x2b, 0xd0, 0x0b, 0x98, 0x09, 0x90, 0x28, 0xe0, 0x05, 0x98, 0x87, 0x42, 0x25, 0xdb, 0x90, 0x79, 0x03, 0x28, 0x01, 0xd0, 0x01, 0x28, 0x20, 0xd1, 0x79, 0x19, 0x05, 0x98, 0x08, 0x1a, 0x07, 0x99, 0xa6, 0x46, 0x80, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x07, 0x1c, 0x28, 0x1c, 0x07, 0x99, 0xa6, 0x46, 0x7d, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x01, 0x04, 0x09, 0x0c, 0x3a, 0x04, 0x12, 0x0c, 0x00, 0x20, 0xa6, 0x46, 0x79, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x28, 0x04, 0xd1, 0x0a, 0x98, 0x00, 0x28, 0x03, 0xd0, 0x0a, 0x97, 0x01, 0xe0, 0x00, 0x20, 0x0a, 0x90, 0xb6, 0x68, 0x00, 0x2e, 0x03, 0xd0, 0x30, 0x88, 0x07, 0x99, 0x88, 0x42, 0x49, 0xdb, 0x08, 0x98, 0x00, 0x28, 0x46, 0xd1, 0x5f, 0x49, 0x09, 0x98, 0x88, 0x42, 0x42, 0xd1, 0x0a, 0x98, 0x88, 0x42, 0x3f, 0xd1, 0x03, 0x98, 0x00, 0x28, 0x2c, 0xd0, 0x02, 0x9d, 0x03, 0x98, 0x0c, 0x90, 0x00, 0x27, 0x28, 0x88, 0x0b, 0x90, 0x04, 0x99, 0xa6, 0x46, 0x64, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0x07, 0xd0, 0x0b, 0x99, 0x04, 0x98, 0xa6, 0x46, 0x60, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0x11, 0xd1, 0x08, 0x98, 0xb8, 0x42, 0x01, 0x05, 0xff, 0xff, 0x9a, 0x6e, 0x08, 0x00, 0xfa, 0x09, 0xd0, 0x08, 0x98, 0xc1, 0x00, 0x02, 0x98, 0x40, 0x18, 0x29, 0x1c, 0x08, 0x22, 0xa6, 0x46, 0x5b, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x08, 0x98, 0x40, 0x1c, 0x00, 0x06, 0x00, 0x0e, 0x08, 0x90, 0x08, 0x35, 0x01, 0x37, 0x0c, 0x98, 0x01, 0x38, 0x0c, 0x90, 0xd6, 0xd1, 0x08, 0x98, 0x00, 0x28, 0x0c, 0xd0, 0x02, 0x98, 0x08, 0x99, 0x06, 0x9a, 0x6b, 0x46, 0xa6, 0x46, 0x4d, 0x4d, 0xfe, 0x44, 0x28, 0x47, 0x07, 0x90, 0x00, 0x9e, 0x3d, 0x48, 0x09, 0x90, 0x0a, 0x90, 0x00, 0x2e, 0x3a, 0xd0, 0x35, 0x88, 0x07, 0x98, 0x85, 0x42, 0x36, 0xda, 0xb0, 0x68, 0x00, 0x28, 0x05, 0xd0, 0x00, 0x88, 0x07, 0x99, 0x88, 0x42, 0x01, 0xdc, 0x47, 0x1b, 0x04, 0xe0, 0x07, 0x98, 0x40, 0x1b, 0x00, 0x99, 0x09, 0x88, 0x0f, 0x18, 0x72, 0x68, 0x91, 0x88, 0x05, 0x98, 0x40, 0x18, 0x87, 0x42, 0x00, 0xda, 0x6a, 0xe7, 0x48, 0x19, 0x07, 0x99, 0xa6, 0x46, 0x3b, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x0b, 0x90, 0x79, 0x19, 0x05, 0x98, 0x08, 0x1a, 0x07, 0x99, 0xa6, 0x46, 0x36, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x0b, 0x98, 0x01, 0x04, 0x09, 0x0c, 0x00, 0x20, 0xa6, 0x46, 0x32, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x28, 0x00, 0xd1, 0x48, 0xe7, 0x00, 0x20, 0x09, 0x90, 0x06, 0xe0, 0xc0, 0x46, 0xe0, 0x31, 0x08, 0x00, 0x1d, 0x48, 0x09, 0x99, 0x81, 0x42, 0x02, 0xd0, 0x09, 0x98, 0x0a, 0x90, 0x02, 0xe0, 0x0a, 0x99, 0x81, 0x42, 0x01, 0xd0, 0x0a, 0x98, 0x04, 0xe0, 0x06, 0x98, 0xa6, 0x46, 0x27, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x01, 0x99, 0x48, 0x60, 0x20, 0x48, 0xff, 0x30, 0x10, 0x30, 0x0d, 0xb0, 0xf0, 0xbd, 0xb7, 0x4b, 0x04, 0x00, 0x01, 0x05, 0xff, 0xf3, 0x94, 0x6f, 0x08, 0x00, 0xee, 0xfd, 0x79, 0x00, 0x00, 0x22, 0x49, 0x09, 0x78, 0x2a, 0x29, 0x01, 0xd1, 0x08, 0x21, 0x00, 0xe0, 0x06, 0x21, 0x41, 0x60, 0x1d, 0x48, 0x43, 0x30, 0xf7, 0x46, 0xc0, 0x46, 0x4f, 0x81, 0x03, 0x00, 0xc6, 0x05, 0x00, 0x00, 0x65, 0x2d, 0x00, 0x00, 0x79, 0x47, 0x00, 0x00, 0x0d, 0x13, 0x02, 0x00, 0x76, 0x24, 0x08, 0x00, 0xe0, 0xa0, 0x1b, 0x00, 0x89, 0x28, 0x05, 0x00, 0x3d, 0x39, 0x02, 0x00, 0x60, 0x5b, 0x08, 0x00, 0xff, 0xff, 0x00, 0x00, 0xd9, 0xaa, 0x00, 0x00, 0xd5, 0x75, 0x00, 0x00, 0x23, 0x01, 0x05, 0x00, 0xb3, 0x09, 0x02, 0x00, 0xf9, 0x97, 0x00, 0x00, 0x8f, 0x8d, 0x01, 0x00, 0xa4, 0x13, 0x08, 0x00, 0xe5, 0x06, 0x05, 0x00, 0x14, 0x05, 0x1a, 0x00, 0x77, 0xc5, 0x01, 0x00, 0xb9, 0xc5, 0x01, 0x00, 0x6d, 0x95, 0x00, 0x00, 0xa1, 0x95, 0x01, 0x00, 0x95, 0x49, 0x05, 0x00, 0x21, 0x96, 0x01, 0x00, 0x5d, 0x5f, 0x05, 0x00, 0x4d, 0x96, 0x01, 0x00, 0x7b, 0x5e, 0x02, 0x00, 0x69, 0x53, 0x08, 0x00, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0xb9, 0xfb, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0xde, 0xfb, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0xaa, 0xfc, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0x84, 0xfb, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0xf8, 0xfa, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0xe5, 0xfa, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0xf5, 0xfa, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0x45, 0xfb, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0x09, 0xfb, 0xff, 0xbd, 0x01, 0x05, 0xff, 0x8d, 0x78, 0x7b, 0x08, 0x00, 0x88, 0x00, 0xb5, 0xf8, 0xf0, 0xa7, 0xfa, 0x00, 0xbd, 0x43, 0x6b, 0x08, 0x00, 0xcd, 0x6b, 0x08, 0x00, 0xd5, 0x65, 0x08, 0x00, 0xe5, 0x6b, 0x08, 0x00, 0x51, 0x6c, 0x08, 0x00, 0x6d, 0x6c, 0x08, 0x00, 0x85, 0x6c, 0x08, 0x00, 0x9b, 0x6c, 0x08, 0x00, 0xa9, 0x6c, 0x08, 0x00, 0xd9, 0x6c, 0x08, 0x00, 0xed, 0x6c, 0x08, 0x00, 0x05, 0x6d, 0x08, 0x00, 0x95, 0x6d, 0x08, 0x00, 0x99, 0x6f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x6c, 0x08, 0x00, 0x01, 0x05, 0xff, 0x85, 0x04, 0xf3, 0x1a, 0x00, 0x80, 0xce, 0xfb, 0x04, 0x00, 0xde, 0x33, 0x02, 0x00, 0x14, 0x29, 0x02, 0x00, 0xf4, 0x4b, 0x04, 0x00, 0x60, 0x13, 0x02, 0x00, 0xd6, 0x28, 0x05, 0x00, 0x74, 0x39, 0x02, 0x00, 0x88, 0xac, 0x00, 0x00, 0x0c, 0x76, 0x00, 0x00, 0x06, 0x0a, 0x02, 0x00, 0x50, 0x98, 0x00, 0x00, 0xb4, 0xc6, 0x01, 0x00, 0x7a, 0x95, 0x00, 0x00, 0xb8, 0x5e, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x52, 0x48, 0x00, 0x00, 0x01, 0x05, 0xff, 0xff, 0x00, 0x00, 0x18, 0x00, 0xfa, 0x70, 0xb5, 0x25, 0x4d, 0xae, 0x7f, 0x01, 0x24, 0xa6, 0x46, 0x21, 0x48, 0xfe, 0x44, 0x00, 0x47, 0xb0, 0x42, 0xf8, 0xd1, 0x03, 0x20, 0x17, 0x21, 0x89, 0x01, 0xa6, 0x46, 0x1d, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0xad, 0x7f, 0xa6, 0x46, 0x1a, 0x48, 0xfe, 0x44, 0x00, 0x47, 0xa8, 0x42, 0xf9, 0xd1, 0xfe, 0xe7, 0x10, 0xb5, 0x19, 0x49, 0x08, 0x1f, 0x19, 0x4a, 0x10, 0x60, 0x1c, 0x48, 0x02, 0x1c, 0x71, 0x3a, 0x93, 0x24, 0x01, 0x23, 0xa3, 0x54, 0x16, 0x4b, 0x0b, 0x60, 0x02, 0x23, 0x13, 0x71, 0x15, 0x4b, 0x4b, 0x60, 0x03, 0x23, 0x53, 0x71, 0x14, 0x4b, 0x8b, 0x60, 0x04, 0x23, 0x03, 0x70, 0x14, 0x4b, 0xcb, 0x60, 0x05, 0x23, 0x83, 0x73, 0x13, 0x4b, 0x0b, 0x61, 0x06, 0x23, 0x03, 0x73, 0x12, 0x4b, 0x4b, 0x61, 0x07, 0x23, 0x43, 0x71, 0x11, 0x4b, 0x8b, 0x61, 0x08, 0x23, 0x33, 0x38, 0x03, 0x70, 0x10, 0x48, 0xc8, 0x61, 0x09, 0x20, 0xd0, 0x74, 0x0f, 0x48, 0x08, 0x62, 0x10, 0xbd, 0x25, 0x86, 0x04, 0x00, 0x1b, 0x90, 0x04, 0x00, 0x6c, 0x52, 0x08, 0x00, 0x08, 0x66, 0x08, 0x00, 0x20, 0x55, 0x08, 0x00, 0x5b, 0x70, 0x08, 0x00, 0x6f, 0x70, 0x08, 0x00, 0x79, 0x70, 0x08, 0x00, 0x95, 0x55, 0x08, 0x00, 0x47, 0x70, 0x08, 0x00, 0x51, 0x70, 0x08, 0x00, 0x65, 0x70, 0x08, 0x00, 0x29, 0x70, 0x08, 0x00, 0x33, 0x70, 0x08, 0x00, 0x3d, 0x70, 0x08, 0x00, 0xf0, 0xb5, 0x0c, 0x22, 0x22, 0x4e, 0x32, 0x70, 0x1a, 0x23, 0x73, 0x70, 0x09, 0x20, 0xb0, 0x70, 0xf2, 0x70, 0x03, 0x20, 0x20, 0x4d, 0x29, 0x1c, 0x01, 0x39, 0x01, 0x24, 0xa6, 0x46, 0x1d, 0x4f, 0xfe, 0x44, 0x38, 0x47, 0xb2, 0x78, 0xf3, 0x78, 0x03, 0x20, 0x29, 0x1c, 0xa6, 0x46, 0x01, 0x05, 0xff, 0x8b, 0xfa, 0x00, 0x18, 0x00, 0x86, 0x19, 0x4e, 0xfe, 0x44, 0x30, 0x47, 0x03, 0x20, 0x29, 0x1c, 0x01, 0x31, 0xa6, 0x46, 0x17, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0xa6, 0x46, 0x16, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x16, 0x4b, 0x00, 0x21, 0x08, 0x1c, 0x1a, 0x68, 0x00, 0x2a, 0x04, 0xd0, 0x02, 0x07, 0x15, 0x0f, 0x22, 0x1c, 0xaa, 0x40, 0x11, 0x43, 0x02, 0x07, 0x12, 0x0f, 0x0f, 0x2a, 0x05, 0xd1, 0xc5, 0x08, 0x06, 0x22, 0x2a, 0x40, 0x0e, 0x4d, 0xa9, 0x52, 0x00, 0x21, 0x04, 0x33, 0x01, 0x30, 0x20, 0x28, 0xe9, 0xd3, 0x0c, 0x48, 0x01, 0x1c, 0x50, 0x31, 0x0c, 0x70, 0x0a, 0x21, 0x09, 0x4a, 0x11, 0x70, 0x2a, 0x21, 0x01, 0x70, 0xf0, 0xbd, 0xfc, 0x53, 0x08, 0x00, 0x31, 0x90, 0x04, 0x00, 0xc6, 0x05, 0x00, 0x00, 0x1b, 0x90, 0x04, 0x00, 0x33, 0x00, 0x18, 0x00, 0x80, 0x7b, 0x08, 0x00, 0x84, 0xf3, 0x1a, 0x00, 0x6d, 0x22, 0x08, 0x00, 0x69, 0x53, 0x08, 0x00, 0x01, 0x83, 0xff, 0x14, 0x79, 0x7b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // // 0x01, 0x0c, 0xfd, 0x09, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x64, 0x00, 0x01, 0x09, 0xfd, 0x08, 0x58, 0x60, 0x1a, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x09, 0xfd, 0x08, 0x10, 0x60, 0x1a, 0x00, 0x10, 0x00, 0x10, 0x00, 0x01, 0x1c, 0xfd, 0x14, 0xff, 0x88, 0x13, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfa, 0x00, 0xff, 0xff, 0x00, // // // ##-------------------------------------------------------------------------------- // ## Description: ORCA_C Commercial PHY FW Initialization Script // ##-------------------------------------------------------------------------------- 0x01, 0x76, 0xfd, 0x31, 0x01, 0x21, 0x54, 0x00, 0x00, 0x61, 0x57, 0x00, 0x00, 0x14, 0x05, 0x0a, 0x05, 0x00, 0x07, 0x06, 0x0a, 0x04, 0x05, 0x08, 0x09, 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, // BTstack: added HCI_VS_SET_POWER_VECTOR(GFSK) 0xFD82 template 0x01, 0x82, 0xfd, 0x14, 0x00, 0x9c, 0x18, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xdc, 0xe6, 0xf0, 0xfa, 0x04, 0x0e, 0x18, 0xff, 0x00, 0x00, // BTstack: added HCI_VS_SET_POWER_VECTOR(EDR2) 0xFD82 template 0x01, 0x82, 0xfd, 0x14, 0x01, 0x9c, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xd8, 0xe2, 0xec, 0xf6, 0x00, 0x0a, 0x14, 0xff, 0x00, 0x00, // BTstack: added HCI_VS_SET_POWER_VECTOR(EDR3) 0xFD82 for EDR3 template 0x01, 0x82, 0xfd, 0x14, 0x02, 0x9c, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xd8, 0xe2, 0xec, 0xf6, 0x00, 0x0a, 0x14, 0xff, 0x00, 0x00, // BTstack: added HCI_VS_SET_CLASS2_SINGLE_POWER 0xFD87 template 0x01, 0x87, 0xfd, 0x03, 0x0d, 0x0d, 0x0d, 0x01, 0x80, 0xfd, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x80, 0xfd, 0x06, 0x3c, 0xf0, 0x5f, 0x00, 0x00, 0x00, // // // 0x01, 0x38, 0xfe, 0x00, // // ################################################################# // ## START of CC2564 Adds-On // ################################################################# // // ## Enable fast clock XTAL support 0x01, 0x1c, 0xfd, 0x14, 0x01, 0x88, 0x13, 0x00, 0x00, 0xd0, 0x07, 0x00, 0x00, 0xff, 0xff, 0x04, 0xff, 0xff, 0xff, 0xfa, 0x00, 0x00, 0x00, 0x00, // // ## Enable eHCILL 0x01, 0x2b, 0xfd, 0x05, 0x10, 0x00, 0x50, 0x00, 0x96, // 0x01, 0x0c, 0xfd, 0x09, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0x64, 0x00, // // ################################################################# // ## END of CC2564 Adds-On // ################################################################# 0x01, 0x5b, 0xfd, 0x02, 0x01, 0x01, // 0x01, 0xdd, 0xfd, 0x01, 0x01, }; const uint32_t cc256x_init_script_size = 3825;
A module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.cpp => module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.cpp +107 -0
@@ 0,0 1,107 @@ #include <bsp/bluetooth/Bluetooth.hpp> #include <log/log.hpp> using namespace bsp; extern "C" { #include "btstack_uart_block_rt1051.h" #include <hci_transport.h> #include <btstack_run_loop.h> #include <btstack_uart_block.h> #include <stddef.h> // for null #include <btstack_run_loop_freertos.h> // #define DEBUG_UART // and it's hci_transport_config_uart_t which is a bit different... static int uart_rt1051_init(const btstack_uart_config_t *config) { LOG_INFO("Create BlueKitchen interface"); BlueKitchen::getInstance(); return 0; } static int uart_rt1051_open() { LOG_INFO("BlueKitchen uart open"); BlueKitchen::getInstance()->open(); return 0; } static int uart_rt1051_close() { LOG_INFO("BlueKitchen uart close"); BlueKitchen::getInstance()->close(); return 0; } static void uart_rt1051_set_block_received(void (*handler)(void)) { BlueKitchen::getInstance()->read_ready_cb = handler; } static void uart_rt1051_set_block_sent(void (*handler)(void)) { BlueKitchen::getInstance()->write_done_cb = handler; } static int uart_rt1051_set_baudrate(uint32_t baudrate) { BlueKitchen::getInstance()->set_baudrate(baudrate); return 0; } static int uart_rt1051_set_parity(int pairity) { // Not implemented LOG_INFO("BlueKitchen set pairity: %d", pairity); return 0; } static int uart_rt1051_set_flowcontrol(int flowcontrol) { LOG_INFO("BlueKitchen set flowcontrol: %d", flowcontrol); // BlueKitchen::getInstance()->set_rts(); ?? return 0; } static void uart_rt1051_receive_block(uint8_t *buffer, uint16_t len) { #ifdef DEBUG_UART LOG_INFO("<-- read: %d", len); #endif BlueKitchen::getInstance()->read(buffer, len); } static void uart_rt1051_send_block(const uint8_t *buffer, uint16_t length) { #ifdef DEBUG_UART LOG_INFO("--> write: %d", length); #endif BlueKitchen::getInstance()->write_blocking((char *)buffer, length); } static const btstack_uart_block_t btstack_uart_posix = { /* int (*init)(hci_transport_config_uart_t * config); */ uart_rt1051_init, /* int (*open)(void); */ uart_rt1051_open, /* int (*close)(void); */ uart_rt1051_close, /* void (*set_block_received)(void (*handler)(void)); */ uart_rt1051_set_block_received, /* void (*set_block_sent)(void (*handler)(void)); */ uart_rt1051_set_block_sent, /* int (*set_baudrate)(uint32_t baudrate); */ uart_rt1051_set_baudrate, /* int (*set_parity)(int parity); */ uart_rt1051_set_parity, /* int (*set_flowcontrol)(int flowcontrol); */ NULL, // uart_rt1051_set_flowcontrol, /* void (*receive_block)(uint8_t *buffer, uint16_t len); */ uart_rt1051_receive_block, /* void (*send_block)(const uint8_t *buffer, uint16_t length); */ uart_rt1051_send_block, /* int (*get_supported_sleep_modes); */ NULL, /* void (*set_sleep)(btstack_uart_sleep_mode_t sleep_mode); */ NULL, /* void (*set_wakeup_handler)(void (*handler)(void)); */ NULL, }; const btstack_uart_block_t *btstack_uart_block_rt1051_instance() { LOG_INFO("btstack_uart_block_rt1051_instance"); return &btstack_uart_posix; } };
A module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.h => module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.h +13 -0
@@ 0,0 1,13 @@ #pragma once #ifdef __cplusplus extern "C" { #endif #include <btstack_uart_block.h> const btstack_uart_block_t *btstack_uart_block_rt1051_instance(); #ifdef __cplusplus }; // __cplusplus #endif
A module-bluetooth/Bluetooth/glucode/hal_time_ms.c => module-bluetooth/Bluetooth/glucode/hal_time_ms.c +8 -0
@@ 0,0 1,8 @@ #include <FreeRTOS.h> #include <task.h> #include <stdint.h> uint32_t hal_time_ms(void) { return xTaskGetTickCount(); }
A module-bluetooth/Bluetooth/interface/bluekitchen/GAP.cpp => module-bluetooth/Bluetooth/interface/bluekitchen/GAP.cpp +244 -0
@@ 0,0 1,244 @@ #include <Bluetooth/Device.hpp> #include <log/log.hpp> #include <vector> #include <Bluetooth/Error.hpp> extern "C" { #include "btstack.h" }; btstack_packet_callback_registration_t cb_handler; enum DEVICE_STATE { REMOTE_NAME_REQUEST, REMOTE_NAME_INQUIRED, REMOTE_NAME_FETCHED }; struct Devicei : public Device { public: bd_addr_t address; uint8_t pageScanRepetitionMode; uint16_t clockOffset; enum DEVICE_STATE state; Devicei(std::string name = "") : name(name) {} virtual ~Devicei() {} void address_set(bd_addr_t *addr) { memcpy(&address, addr, sizeof address); } std::string name; }; std::vector<Devicei> devices; static int getDeviceIndexForAddress(std::vector<Devicei> &devs, bd_addr_t addr) { int j; for (j = 0; j < devs.size(); j++) { if (bd_addr_cmp(addr, devs[j].address) == 0) { return j; } } return -1; } enum STATE { INIT, ACTIVE, DONE }; enum STATE state = INIT; #define INQUIRY_INTERVAL 5 static int start_scan(void) { LOG_INFO("Starting inquiry scan.."); return gap_inquiry_start(INQUIRY_INTERVAL); } static int has_more_remote_name_requests(void) { int i; for (i = 0; i < devices.size(); i++) { if (devices[i].state == REMOTE_NAME_REQUEST) return 1; } return 0; } static void do_next_remote_name_request(void) { int i; for (i = 0; i < devices.size(); i++) { // remote name request if (devices[i].state == REMOTE_NAME_REQUEST) { devices[i].state = REMOTE_NAME_INQUIRED; LOG_INFO("Get remote name of %s...", bd_addr_to_str(devices[i].address)); gap_remote_name_request( devices[i].address, devices[i].pageScanRepetitionMode, devices[i].clockOffset | 0x8000); return; } } } static void continue_remote_names(void) { if (has_more_remote_name_requests()) { do_next_remote_name_request(); return; } start_scan(); } static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { UNUSED(channel); UNUSED(size); bd_addr_t addr; int i; int index; if (packet_type != HCI_EVENT_PACKET) return; uint8_t event = hci_event_packet_get_type(packet); switch (state) { /* @text In INIT, an inquiry scan is started, and the application transits to * ACTIVE state. */ case INIT: switch (event) { case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING) { state = ACTIVE; } break; default: break; } break; /* @text In ACTIVE, the following events are processed: * - GAP Inquiry result event: BTstack provides a unified inquiry result that contain * Class of Device (CoD), page scan mode, clock offset. RSSI and name (from EIR) are optional. * - Inquiry complete event: the remote name is requested for devices without a fetched * name. The state of a remote name can be one of the following: * REMOTE_NAME_REQUEST, REMOTE_NAME_INQUIRED, or REMOTE_NAME_FETCHED. * - Remote name request complete event: the remote name is stored in the table and the * state is updated to REMOTE_NAME_FETCHED. The query of remote names is continued. */ case ACTIVE: switch (event) { case GAP_EVENT_INQUIRY_RESULT: { gap_event_inquiry_result_get_bd_addr(packet, addr); index = getDeviceIndexForAddress(devices, addr); if (index >= 0) break; // already in our list Devicei dev; dev.address_set(&addr); dev.pageScanRepetitionMode = gap_event_inquiry_result_get_page_scan_repetition_mode(packet); dev.clockOffset = gap_event_inquiry_result_get_clock_offset(packet); // print info LOG_INFO("Device found: %s ", bd_addr_to_str(addr)); LOG_INFO("with COD: 0x%06x, ", (unsigned int)gap_event_inquiry_result_get_class_of_device(packet)); LOG_INFO("pageScan %d, ", dev.pageScanRepetitionMode); LOG_INFO("clock offset 0x%04x", dev.clockOffset); if (gap_event_inquiry_result_get_rssi_available(packet)) { LOG_INFO(", rssi %d dBm", (int8_t)gap_event_inquiry_result_get_rssi(packet)); } if (gap_event_inquiry_result_get_name_available(packet)) { char name_buffer[240]; int name_len = gap_event_inquiry_result_get_name_len(packet); memcpy(name_buffer, gap_event_inquiry_result_get_name(packet), name_len); name_buffer[name_len] = 0; LOG_INFO(", name '%s'", name_buffer); dev.state = REMOTE_NAME_FETCHED; ; } else { dev.state = REMOTE_NAME_REQUEST; } devices.push_back(dev); } break; case GAP_EVENT_INQUIRY_COMPLETE: for (i = 0; i < devices.size(); i++) { // retry remote name request if (devices[i].state == REMOTE_NAME_INQUIRED) devices[i].state = REMOTE_NAME_REQUEST; } continue_remote_names(); break; case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: { reverse_bd_addr(&packet[3], addr); index = getDeviceIndexForAddress(devices, addr); if (index >= 0) { if (packet[2] == 0) { LOG_INFO("Name: '%s'", &packet[9]); devices[index].state = REMOTE_NAME_FETCHED; devices[index].name = reinterpret_cast<char *>(&packet[9]); } else { LOG_INFO("Failed to get name: page timeout"); } } if (index + 1 == devices.size()) { LOG_INFO("Scanned all"); state = DONE; } continue_remote_names(); } break; default: break; } break; default: break; } } namespace Bt { namespace GAP { Error register_scan() { LOG_INFO("GAP register scan!"); /// -> this have to be called prior to power on! hci_set_inquiry_mode(INQUIRY_MODE_RSSI_AND_EIR); cb_handler.callback = &packet_handler; hci_add_event_handler(&cb_handler); return Error(); } Error scan() { LOG_INFO("Start scan if active: %d: %d", hci_get_state(), state); if (hci_get_state() == HCI_STATE_WORKING) { if (int ret = start_scan() != 0) { LOG_ERROR("Start scan error!: 0x%X", ret); return Error(Error::LibraryError, ret); } } else { return Error(Error::NotReady); } return Error(); } } // namespace GAP } // namespace Bt
A module-bluetooth/Bluetooth/interface/bluekitchen/PAN.cpp => module-bluetooth/Bluetooth/interface/bluekitchen/PAN.cpp +174 -0
@@ 0,0 1,174 @@ #include <log/log.hpp> extern "C" { #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include "btstack_config.h" #include <btstack_event.h> // #include <btstack_link_key_db_fs.h> #include <btstack_memory.h> #include <btstack_run_loop.h> #include <btstack_run_loop_freertos.h> #include <bluetooth_company_id.h> #include <hci.h> #include <hci_dump.h> #include <btstack_stdin.h> // #include <btstack_tlv_posix.h> #include <btstack_chipset_cc256x.h> #include <pan.h> #include <sdp_util.h> #include <bnep_lwip.h> #include <bluetooth_sdp.h> }; #include <BtCommand.hpp> #include <Error.hpp> #ifdef TARGET_RT1051 #include <Bluetooth/glucode/btstack_uart_block_rt1051.h> #endif static btstack_packet_callback_registration_t hci_event_callback_registration; #define NETWORK_TYPE_IPv4 0x0800 #define NETWORK_TYPE_ARP 0x0806 #define NETWORK_TYPE_IPv6 0x86DD static uint8_t pan_sdp_record[220]; static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { /* LISTING_PAUSE */ UNUSED(channel); UNUSED(size); bd_addr_t event_addr; switch (packet_type) { case HCI_EVENT_PACKET: switch (hci_event_packet_get_type(packet)) { case HCI_EVENT_PIN_CODE_REQUEST: // inform about pin code request LOG_INFO("Pin code request - using '0000'"); hci_event_pin_code_request_get_bd_addr(packet, event_addr); gap_pin_code_response(event_addr, "0000"); break; case HCI_EVENT_USER_CONFIRMATION_REQUEST: // inform about user confirmation request LOG_INFO("SSP User Confirmation Auto accept"); hci_event_user_confirmation_request_get_bd_addr(packet, event_addr); break; /* @text BNEP_EVENT_CHANNEL_OPENED is received after a BNEP connection was established or * or when the connection fails. The status field returns the error code. */ case BNEP_EVENT_CHANNEL_OPENED: if (bnep_event_channel_opened_get_status(packet)) { LOG_INFO("BNEP channel open failed, status %02x", bnep_event_channel_opened_get_status(packet)); } else { uint16_t uuid_source = bnep_event_channel_opened_get_source_uuid(packet); uint16_t uuid_dest = bnep_event_channel_opened_get_destination_uuid(packet); uint16_t mtu = bnep_event_channel_opened_get_mtu(packet); bnep_event_channel_opened_get_remote_address(packet, event_addr); LOG_INFO("BNEP connection open succeeded to %s source UUID 0x%04x dest UUID: 0x%04x, max frame size %u", bd_addr_to_str(event_addr), uuid_source, uuid_dest, mtu); LOG_INFO("Please open 'http://192.168.7.1' in your web browser: "); } break; /* @text BNEP_EVENT_CHANNEL_CLOSED is received when the connection gets closed. */ case BNEP_EVENT_CHANNEL_CLOSED: LOG_INFO("BNEP channel closed"); break; default: break; } break; default: break; } } namespace Bt { // Set local name with a template Bluetooth address, that will be automatically // replaced with a actual address once it is available, i.e. when BTstack boots Error set_name(std::string &name) { // name has to have storage constexpr uint32_t size = 64; static char lname[size] = {0}; snprintf(lname, size, "%s %s", name.c_str(), "00:00:00:00:00:00"); LOG_INFO("Setting local name: %s", lname); gap_set_local_name(lname); return Error(); } namespace PAN { Error bnep_setup() { // Discoverable // up and starts talking to a Bluetooth module. gap_discoverable_control(1); // register for HCI events hci_event_callback_registration.callback = &packet_handler; hci_add_event_handler(&hci_event_callback_registration); // Initialize L2CAP l2cap_init(); // Initialize BNEP bnep_init(); // Init SDP sdp_init(); memset(pan_sdp_record, 0, sizeof(pan_sdp_record)); uint16_t network_packet_types[] = {NETWORK_TYPE_IPv4, NETWORK_TYPE_ARP, 0}; // 0 as end of list // NAP Network Access Type: Other, 1 MB/s pan_create_nap_sdp_record(pan_sdp_record, sdp_create_service_record_handle(), network_packet_types, NULL, NULL, BNEP_SECURITY_NONE, PAN_NET_ACCESS_TYPE_OTHER, 1000000, NULL, NULL); sdp_register_service(pan_sdp_record); LOG_INFO("SDP service record size: %u", de_get_len((uint8_t *)pan_sdp_record)); return Error(); } Error bnep_start() { bnep_lwip_init(); // Setup NAP Service via BENP lwIP adapter bnep_lwip_register_service(BLUETOOTH_SERVICE_CLASS_NAP, 1691); // register callback - to print state bnep_lwip_register_packet_handler(packet_handler); return Error(); } } // namespace PAN } // namespace Bt
A module-bluetooth/Bluetooth/interface/bluekitchen/Worker.cpp => module-bluetooth/Bluetooth/interface/bluekitchen/Worker.cpp +231 -0
@@ 0,0 1,231 @@ #include <log/log.hpp> // #define __BTSTACK_FILE__ ".c" extern "C" { #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include "btstack_config.h" #include <btstack_event.h> // #include <btstack_link_key_db_fs.h> #include <btstack_memory.h> #include <btstack_run_loop.h> #include <bluetooth_company_id.h> #include <hci.h> #include <hci_dump.h> #include <btstack_stdin.h> #include <btstack_chipset_cc256x.h> #include <btstack_link_key_db_memory.h> }; #ifdef TARGET_RT1051 #include <Bluetooth/glucode/btstack_uart_block_rt1051.h> #include <btstack_run_loop_freertos.h> #else extern "C" { #include <btstack_run_loop_posix.h> #include <btstack_tlv_posix.h> } #endif #include <Error.hpp> #include <functional> // #define TLV_DB_PATH_PREFIX "/tmp/btstack_" // #define TLV_DB_PATH_POSTFIX ".tlv" // static char tlv_db_path[100]; // static const btstack_tlv_t * tlv_impl; // static btstack_tlv_posix_t tlv_context; static void local_version_information_handler(uint8_t *packet); static hci_transport_config_uart_t config = { .type = HCI_TRANSPORT_CONFIG_UART, .baudrate_init = 115200, .baudrate_main = 0, // main baudrate .flowcontrol = 1, // flow control .device_name = NULL, }; static btstack_packet_callback_registration_t hci_event_callback_registration; static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { bd_addr_t addr; if (packet_type != HCI_EVENT_PACKET) return; switch (hci_event_packet_get_type(packet)) { case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break; gap_local_bd_addr(addr); LOG_INFO("BTstack up and running at %s", bd_addr_to_str(addr)); // setup TLV // strcpy(tlv_db_path, TLV_DB_PATH_PREFIX); // strcat(tlv_db_path, bd_addr_to_str(addr)); // strcat(tlv_db_path, TLV_DB_PATH_POSTFIX); // tlv_impl = btstack_tlv_posix_init_instance(&tlv_context, tlv_db_path); // btstack_tlv_set_instance(tlv_impl, &tlv_context); break; case HCI_EVENT_COMMAND_COMPLETE: if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)) { if (hci_event_command_complete_get_return_parameters(packet)[0]) break; // terminate, name 248 chars packet[6 + 248] = 0; LOG_INFO("Local name: %s", &packet[6]); } if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)) { local_version_information_handler(packet); } break; default: break; } } static void sigint_handler(int param) { UNUSED(param); LOG_INFO("CTRL-C - SIGINT received, shutting down.."); // reset anyway btstack_stdin_reset(); // power down hci_power_control(HCI_POWER_OFF); hci_close(); exit(0); } static int led_state = 0; void hal_led_toggle(void) { led_state = 1 - led_state; LOG_INFO("LED State %u", led_state); } static void use_fast_uart(void) { #if defined(HAVE_POSIX_B240000_MAPPED_TO_3000000) || defined(HAVE_POSIX_B600_MAPPED_TO_3000000) LOG_INFO("Using 3000000 baud."); config.baudrate_main = 3000000; #elif defined(HAVE_POSIX_B1200_MAPPED_TO_2000000) || defined(HAVE_POSIX_B300_MAPPED_TO_2000000) LOG_INFO("Using 2000000 baud."); config.baudrate_main = 2000000; #else LOG_INFO("Using 921600 baud"); config.baudrate_main = 921600; #endif } static void local_version_information_handler(uint8_t *packet) { LOG_INFO("Local version information:"); uint16_t hci_version = packet[6]; uint16_t hci_revision = little_endian_read_16(packet, 7); uint16_t lmp_version = packet[9]; uint16_t manufacturer = little_endian_read_16(packet, 10); uint16_t lmp_subversion = little_endian_read_16(packet, 12); LOG_INFO("- HCI Version 0x%04x", hci_version); LOG_INFO("- HCI Revision 0x%04x", hci_revision); LOG_INFO("- LMP Version 0x%04x", lmp_version); LOG_INFO("- LMP Subversion 0x%04x", lmp_subversion); LOG_INFO("- Manufacturer 0x%04x", manufacturer); switch (manufacturer) { case BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC: LOG_INFO("Texas Instruments - CC256x compatible chipset."); if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion()) { LOG_INFO("Error: LMP Subversion does not match initscript! "); LOG_INFO("Your initscripts is for %s chipset", btstack_chipset_cc256x_lmp_subversion() < lmp_subversion ? "an older" : "a newer"); LOG_INFO("Please update Makefile to include the appropriate bluetooth_init_cc256???.c file"); exit(10); } use_fast_uart(); hci_set_chipset(btstack_chipset_cc256x_instance()); #ifdef ENABLE_EHCILL LOG_INFO("eHCILL enabled."); #else LOG_INFO("eHCILL disable."); #endif break; case BLUETOOTH_COMPANY_ID_NORDIC_SEMICONDUCTOR_ASA: LOG_INFO("Nordic Semiconductor nRF5 chipset."); break; default: LOG_INFO("Unknown manufacturer / manufacturer not supported yet.\n"); break; } } extern "C" { #include <FreeRTOS.h> #include <task.h> }; namespace Bt { void run_btstack(void *) { LOG_INFO("- run BtStack loop\n"); btstack_run_loop_execute(); } Error initialize_stack() { btstack_memory_init(); #ifdef TARGET_RT1051 btstack_run_loop_init(btstack_run_loop_freertos_get_instance()); const btstack_uart_block_t *uart_driver = btstack_uart_block_rt1051_instance(); #else btstack_run_loop_init(btstack_run_loop_posix_get_instance()); config.device_name = "/dev/telit"; LOG_INFO("H4 device: %s", config.device_name); const btstack_uart_block_t *uart_driver = btstack_uart_block_posix_instance(); #endif const hci_transport_t *transport = hci_transport_h4_instance(uart_driver); const btstack_link_key_db_t *link_key_db = btstack_link_key_db_memory_instance(); hci_init(transport, (void *)&config); hci_set_link_key_db(link_key_db); hci_event_callback_registration.callback = &hci_packet_handler; hci_add_event_handler(&hci_event_callback_registration); LOG_DEBUG("BT worker run success"); return Error(); } Error register_hw_error_callback(std::function<void(uint8_t)> new_callback) { static std::function<void(uint8_t)> callback = nullptr; callback = new_callback; hci_set_hardware_error_callback([](uint8_t val) -> void { LOG_ERROR("Bluetooth HW ERROR! %d", val); if (callback) { callback(val); } }); return Error(); } Error run_stack(TaskHandle_t *handle) { BaseType_t taskerr = 0; LOG_INFO("Past last moment for Bt registration prior to RUN state"); hci_power_control(HCI_POWER_ON); if ((taskerr = xTaskCreate(run_btstack, "BtStack", 1024, NULL, tskIDLE_PRIORITY, handle)) != pdPASS) { LOG_ERROR("BT Service failure! %lu", taskerr); return Error(Error::SystemError, taskerr); } return Error(); } } // namespace Bt
A module-bluetooth/Bluetooth/interface/bluekitchen/btstack_config.h => module-bluetooth/Bluetooth/interface/bluekitchen/btstack_config.h +51 -0
@@ 0,0 1,51 @@ // // btstack_config.h for generic POSIX H4 port // #ifndef __BTSTACK_CONFIG #define __BTSTACK_CONFIG // Port related features #define HAVE_MALLOC #ifndef TARGET_RT1051 #define HAVE_POSIX_FILE_IO #endif #define HAVE_BTSTACK_STDIN // #define HAVE_POSIX_TIME #define HAVE_EM9304_PATCH_CONTAINER // BTstack features that can be enabled // #define ENABLE_BLE #define ENABLE_CLASSIC #define ENABLE_HFP_WIDE_BAND_SPEECH #define ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE // #define ENABLE_LE_CENTRAL // #define ENABLE_LE_PERIPHERAL // #define ENABLE_LE_SECURE_CONNECTIONS // #define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS // #define ENABLE_LE_DATA_CHANNELS // #define ENABLE_LE_DATA_LENGTH_EXTENSION #define ENABLE_ATT_DELAYED_RESPONSE #define ENABLE_USER_LOG #define ENABLE_LOG_ERROR #define ENABLE_LOG_INFO #define ENABLE_LOG_WARNING // #define ENABLE_LOG_DEBUG #define ENABLE_SCO_OVER_HCI #define ENABLE_SDP_DES_DUMP // #define ENABLE_EHCILL // BTstack configuration. buffers, sizes, ... #define HCI_INCOMING_PRE_BUFFER_SIZE 14 // sizeof benep heade, avoid memcpy #define HCI_ACL_PAYLOAD_SIZE (1691 + 4) // As an option - much slower (according to docs) // HCI Controller to Host Flow Control // #define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL // // // Interal ring buffer: 21 kB // #define HCI_HOST_ACL_PACKET_NUM 20 // #define HCI_HOST_ACL_PACKET_LEN 1024 // #define HCI_HOST_SCO_PACKET_NUM 10 // #define HCI_HOST_SCO_PACKET_LEN 60 #endif
A module-bluetooth/CMakeLists.txt => module-bluetooth/CMakeLists.txt +56 -0
@@ 0,0 1,56 @@ project(module-bluetooth VERSION 1.0 DESCRIPTION "Bluetooth module library") include(${CMAKE_SOURCE_DIR}/config/ModuleConfig.cmake) set(CMAKE_CXX_STANDARD 17) set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/BluetoothWorker.cpp ) message("Build with BlueKitchen") include(lib/btstack.cmake) message("Sources: " ${SOURCES}) add_library(${PROJECT_NAME} STATIC ${SOURCES} ${BOARD_DIR_SOURCES}) # # Board specific compilation definitions,options,include directories and features target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_CONFIG_DEFINITIONS} ${PROJECT_TARGET} ${TARGET_COMPILE_DEFINITIONS} ${BOARD_DIR_DEFINITIONS} ) target_compile_features(${PROJECT_NAME} PUBLIC ${TARGET_COMPILE_FEATURES}) target_compile_options(${PROJECT_NAME} PUBLIC ${TARGET_COMPILE_OPTIONS} PRIVATE -Wno-sign-compare -Wno-missing-field-initializers -Wno-unused-function -Wno-implicit-fallthrough # C only flags "$<$<COMPILE_LANGUAGE:C>:-Wno-old-style-declaration>" ) target_link_options(${PROJECT_NAME} PUBLIC ${TARGET_LINK_OPTIONS}) target_include_directories( ${PROJECT_NAME} PUBLIC ${BOARD_DIR_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR} ${TARGET_LIBRARIES_INCLUDES} ) target_link_libraries( ${PROJECT_NAME} module-bsp module-utils module-vfs module-sys ${BOARD_DIR_LIBRARIES} )
A module-bluetooth/README.md => module-bluetooth/README.md +15 -0
@@ 0,0 1,15 @@ Bluetooth interface layer ========================= Right now it properly uses API from bsp/bsp-bluetooth and BlueKitchen stack. It's meant to provide interface layer for service-bluetooth like that: >>> os calls <=> service-bluetooth <=> module-bluetooth <=> bluetooth library >>> <=> bsp/bluetooth ## Layout * Bluetooth * `interface` code - for other modules to use * `glucode` code needed for libraries to work * `profiles` bluetooth library function wrappers * lib Libraries used with as little modifications as possible
A module-bluetooth/lib/btstack => module-bluetooth/lib/btstack +1 -0
A module-bluetooth/lib/btstack.cmake => module-bluetooth/lib/btstack.cmake +168 -0
@@ 0,0 1,168 @@ set(BT_GLU "${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/glucode/") set(BT_INT "${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/interface/bluekitchen/") set(BT_STACK_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/lib/btstack") set(BT_CORE ${BT_STACK_ROOT}/src/btstack_memory.c ${BT_STACK_ROOT}/src/btstack_linked_list.c ${BT_STACK_ROOT}/src/btstack_memory_pool.c ${BT_STACK_ROOT}/src/btstack_run_loop.c ${BT_STACK_ROOT}/src/btstack_util.c ) set(BT_COMMON ${BT_STACK_ROOT}/src/ad_parser.c ${BT_STACK_ROOT}/src/hci.c ${BT_STACK_ROOT}/src/hci_cmd.c ${BT_STACK_ROOT}/src/hci_dump.c ${BT_STACK_ROOT}/src/l2cap.c ${BT_STACK_ROOT}/src/l2cap_signaling.c ${BT_STACK_ROOT}/src/btstack_audio.c ${BT_STACK_ROOT}/src/btstack_tlv.c ${BT_STACK_ROOT}/src/btstack_crypto.c #${BT_STACK_ROOT}/src/3rd-party/micro-ecc/uECC.c #${BT_STACK_ROOT}/src/sm.c ) set(BT_CLASSIC ${BT_STACK_ROOT}/src/classic/btstack_link_key_db_memory.c ${BT_STACK_ROOT}/src/classic/sdp_util.c ${BT_STACK_ROOT}/src/classic/gatt_sdp.c ${BT_STACK_ROOT}/src/classic/spp_server.c ${BT_STACK_ROOT}/src/classic/rfcomm.c ${BT_STACK_ROOT}/src/classic/bnep.c ${BT_STACK_ROOT}/src/classic/btstack_link_key_db_memory.c ${BT_STACK_ROOT}/src/classic/pan.c ${BT_STACK_ROOT}/src/classic/sdp_server.c ${BT_STACK_ROOT}/src/classic/device_id_server.c ) set(BNEP_LWIP ${BT_STACK_ROOT}/platform/lwip/bnep_lwip.c ) # ATT # ${BT_STACK_ROOT}/att_dispatch.c # # GATT_SERVER # ${BT_STACK_ROOT}/att_db.c # ${BT_STACK_ROOT}/att_server.c # # GATT_CLIENT # ${BT_STACK_ROOT}/gatt_client.c # PAN # ${BT_STACK_ROOT}/pan.c # MBEDTLS = \ # ${BT_STACK_ROOT}/bignum.c \ # ${BT_STACK_ROOT}/ecp.c \ # ${BT_STACK_ROOT}/ecp_curves.c \ # ${BT_STACK_ROOT}/sm_mbedtls_allocator.c \ # ${BT_STACK_ROOT}/memory_buffer_alloc.c \ # ${BT_STACK_ROOT}/platform.c \ # # LWIP_CORE_SRC = init.c mem.c memp.c netif.c udp.c ip.c pbuf.c inet_chksum.c def.c tcp.c tcp_in.c tcp_out.c timeouts.c sys_arch.c # LWIP_IPV4_SRC = acd.c dhcp.c etharp.c icmp.c ip4.c ip4_frag.c ip4_addr.c # LWIP_NETIF_SRC = ethernet.c # LWIP_HTTPD = altcp_proxyconnect.c fs.c httpd.c # LWIP_SRC = ${LWIP_CORE_SRC} ${LWIP_IPV4_SRC} ${LWIP_NETIF_SRC} ${LWIP_HTTPD} dhserver.c # # List of files for Bluedroid SBC codec # include ${BTSTACK_ROOT}/3rd-party/bluedroid/decoder/Makefile.inc # include ${BTSTACK_ROOT}/3rd-party/bluedroid/encoder/Makefile.inc # SBC_DECODER += \ # btstack_sbc_plc.c \ # btstack_sbc_decoder_bluedroid.c \ # # SBC_ENCODER += \ # btstack_sbc_encoder_bluedroid.c \ # hfp_msbc.c \ # # CVSD_PLC = \ # btstack_cvsd_plc.c \ # # AVDTP += \ # avdtp_util.c \ # avdtp.c \ # avdtp_initiator.c \ # avdtp_acceptor.c \ # avdtp_source.c \ # avdtp_sink.c \ # a2dp_source.c \ # a2dp_sink.c \ # btstack_ring_buffer.c \ set(TARGET_LIBRARIES_INCLUDES "${BT_INT}" ${BT_STACK_ROOT}/platform/freertos/ ${BT_STACK_ROOT}/platform/embedded/ ${BT_STACK_ROOT}/chipset/cc256x ${BT_STACK_ROOT}/src/ble ${BT_STACK_ROOT}/src/classic ${BT_STACK_ROOT}/src ${BT_STACK_ROOT}/3rd-party/bluedroid/decoder/include ${BT_STACK_ROOT}/3rd-party/bluedroid/encoder/include ${BT_STACK_ROOT}/3rd-party/hxcmod-player # ${BT_STACK_ROOT}/3rd-party/lwip/core/src/include/ ${BT_STACK_ROOT}/3rd-party/lwip/dhcp-server ${BT_STACK_ROOT}/3rd-party/md5 ${BT_STACK_ROOT}/3rd-party/micro-ecc ${BT_STACK_ROOT}/3rd-party/yxml # ${BT_STACK_ROOT}/platform/lwip ) # pseudocode #if(PLATFORM LINUX) { #btstack_stdin_posix.c #&& include from posix too #} if(${PROJECT_TARGET} STREQUAL "TARGET_Linux") message("Linux specyfic includes") message("-----------------------") list(APPEND TARGET_LIBRARIES_INCLUDES ${BT_STACK_ROOT}/platform/posix/ ) else () endif() include(${CMAKE_SOURCE_DIR}/module-lwip/lwip-includes.cmake) list(APPEND TARGET_LIBRARIES_INCLUDES ${LWIP_INCLUDE_DIRS}) list(APPEND TARGET_LIBRARIES_INCLUDES ${BT_STACK_ROOT}/platform/lwip ) set(BOARD_DIR_SOURCES ${BT_INT}/Worker.cpp ${BT_INT}/GAP.cpp ${BT_INT}/PAN.cpp ${BT_GLU}/bluetooth_init_cc2564C_1.0.c ${BT_GLU}/btstack_uart_block_rt1051.cpp ${BT_GLU}/btstack_uart_block_rt1051.h ${BT_GLU}/hal_time_ms.c ${BT_STACK_ROOT}/chipset/cc256x/btstack_chipset_cc256x.c ${BT_STACK_ROOT}/platform/freertos/btstack_run_loop_freertos.c ${BT_STACK_ROOT}/src/hci_transport_h4.c ${BT_CORE} ${BT_COMMON} ${BT_CLASSIC} ${BNEP_LWIP} ) if(${PROJECT_TARGET} STREQUAL "TARGET_Linux") message("Linux specyfic sources") message("----------------------") # include(${CMAKE_CURRENT_SOURCE_DIR}/targets/Target_Linux.cmake) list(APPEND BOARD_DIR_SOURCES # ${BOARD_SOURCES} ${BT_STACK_ROOT}/platform/posix/btstack_stdin_posix.c ${BT_STACK_ROOT}/platform/posix/btstack_uart_block_posix.c ${BT_STACK_ROOT}/platform/posix/btstack_run_loop_posix.c ${BT_STACK_ROOT}/platform/posix/btstack_tlv_posix.c ) else() endif()
A module-bluetooth/targets/Target_Linux.cmake => module-bluetooth/targets/Target_Linux.cmake +2 -0
@@ 0,0 1,2 @@ set(BOARD_SOURCES CACHE INTERNAL "") set(BOARD_DIR_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/board/linux CACHE INTERNAL "")
A module-bluetooth/tests/CMakeLists.txt => module-bluetooth/tests/CMakeLists.txt +0 -0
M module-bsp/CMakeLists.txt => module-bsp/CMakeLists.txt +1 -0
@@ 15,6 15,7 @@ set(SOURCES #"${CMAKE_CURRENT_SOURCE_DIR}/drivers/sai/DriverSAI.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/drivers/gpio/DriverGPIO.cpp" board/linux/lpm/LinuxLPM.cpp board/linux/lpm/LinuxLPM.h "${CMAKE_CURRENT_SOURCE_DIR}/bsp/bluetooth/Bluetooth.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/bsp/common.cpp" )
A module-bsp/board/linux/bluetooth/Bluetooth.cpp => module-bsp/board/linux/bluetooth/Bluetooth.cpp +117 -0
@@ 0,0 1,117 @@ #include "bsp/bluetooth/Bluetooth.hpp" #include "BluetoothWorker.hpp" #include "log/log.hpp" /// stubs using namespace bsp; void BTdev::_circ::sem_take() {} void BTdev::_circ::sem_give() {} BTdev::_circ::_circ(unsigned int size, int threshold) : head(0), tail(0), threshold(threshold), size(size), len(0) { buff = new char[size]; } BTdev::_circ::~_circ() { delete[] buff; } BlueKitchen::BlueKitchen(unsigned int in_size, unsigned int out_size) : BluetoothCommon(in_size, out_size) {} BlueKitchen *BlueKitchen::getInstance() { static BlueKitchen *k = NULL; if (k == NULL) { k = new BlueKitchen(); } return k; } ssize_t BlueKitchen::write_blocking(char *buf, ssize_t len) { return 0; } BluetoothCommon::BluetoothCommon(unsigned int in_size, unsigned int out_size, int threshold) : BTdev(in_size, out_size, threshold) {} BlueKitchen::~BlueKitchen() {} BluetoothCommon::~BluetoothCommon() {} void BluetoothCommon::open() {} void BluetoothCommon::close() {} void BluetoothCommon::sleep_ms(ssize_t ms) { ulTaskNotifyTake(pdTRUE, ms); } BTdev::Error BluetoothCommon::flush() { return Success; } ssize_t BluetoothCommon::write(char *buf, size_t nbytes) { return 0; } ssize_t BluetoothCommon::write_blocking(char *buf, ssize_t len) { return 0; } BTdev::Error BluetoothCommon::set_baudrate(uint32_t bd) { return Success; } // set flow on -> true, set flow off -> false BTdev::Error BluetoothCommon::set_rts(bool on) { return Success; } BTdev::Error BluetoothCommon::set_reset(bool on) { return Success; } int BluetoothCommon::read_cts() { return 0; } void BluetoothCommon::configure_uart_io() {} void BluetoothCommon::configure_lpuart() {} void BluetoothCommon::configure_cts_irq() {} void BluetoothCommon::set_irq(bool enable) {} ssize_t BlueKitchen::read(void *buf, size_t nbytes) { return 0; } ssize_t Bluetopia::read(void *buf, size_t nbytes) { return 0; }
A module-bsp/board/linux/bluetooth/test/bsp_bt.cpp => module-bsp/board/linux/bluetooth/test/bsp_bt.cpp +138 -0
@@ 0,0 1,138 @@ #include "bsp_bt.hpp" namespace bsp { BluetopiaHW::BluetopiaHW(LogLvl lvl) : Bluetopia(64, 64, 0) { log(LogDebug, "Init done!\n"); } BluetopiaHW::~BluetopiaHW() {} Bluetopia *BluetopiaHW::getInstance() { static BluetopiaHW *inst = NULL; if (inst == NULL) { inst = new BluetopiaHW(); } return inst; } void Bluetopia::wait_data() {} void Bluetopia::set_data() {} void BluetopiaHW::open() { log(LogDebug, "open!\n"); set_irq(true); } void BluetopiaHW::close() { log(LogDebug, "close!\n"); set_irq(false); } void BluetopiaHW::sleep_ms(ssize_t ms) { log(LogDebug, "sleep %d [ms]!\n", ms); ulTaskNotifyTake(pdTRUE, ms); } void mocup_write_blocking(unsigned char *buf, size_t len) { printf("WRITE: [%d][%.*s]\n", int(len), int(len), buf); } BTdev::Error BluetopiaHW::flush() { log(LogDebug, "flush [%d] %s\n", out.len, out.tail < out.head ? "reverse" : "normal"); Error err = Success; unsigned int i = 0; for (i = 0; i < default_timeout_ms; ++i) { if (read_cts() == 0) { break; } else { sleep_ms(1); } } if (i == default_timeout_ms) { printf("BT CTS error!\n"); err = ErrorTimeout; } char *from = &out.buff[out.head]; if (out.tail >= out.head) { mocup_write_blocking(reinterpret_cast<uint8_t *>(from), out.len); } else { mocup_write_blocking(reinterpret_cast<uint8_t *>(from), out.len - out.tail); from = out.buff; mocup_write_blocking(reinterpret_cast<uint8_t *>(from), out.tail); } out.flush(); return err; } ssize_t BluetopiaHW::write(char *buf, size_t nbytes) { log(LogDebug, "write %d -> [%.*s]\n", nbytes, nbytes, buf); size_t i = 0; // if CTS set -> ignore return 0, can use threshold_guard here too for (i = 0; i < nbytes; ++i) { if (out.push(*(buf + i)) != 0) { break; } } return i; } ssize_t BluetopiaHW::write_blocking(char *buf, ssize_t len) { int llen = 0; while (llen != len) { llen += write(buf, len - llen); flush(); } return llen; } BTdev::Error BluetopiaHW::set_baudrate(uint32_t bd) { log(LogDebug, "Set baudrate: %d", bd); Error ret = Success; return ret; } // set flow on -> true, set flow off -> false BTdev::Error BluetopiaHW::set_rts(bool on) { log(LogDebug, "RTS %s", on ? "on" : "off"); return Success; } BTdev::Error BluetopiaHW::set_reset(bool on) { log(LogDebug, "reset %s", on ? "on" : "off"); return Success; } void BluetopiaHW::set_irq(bool enable) {} ssize_t BluetopiaHW::read(void *, unsigned long) { return 0; } int BluetopiaHW::read_cts() { return 0; } }; // namespace bsp
A module-bsp/board/linux/bluetooth/test/bsp_bt.hpp => module-bsp/board/linux/bluetooth/test/bsp_bt.hpp +38 -0
@@ 0,0 1,38 @@ #pragma once #include "bsp/bluetooth/Bluetooth.hpp" #include "FreeRTOS.h" #include "stream_buffer.h" #include "timers.h" #include <memory> namespace bsp { class BluetopiaHW : public Bluetopia { public: BluetopiaHW(LogLvl lvl = LogError); virtual ~BluetopiaHW(); static Bluetopia *getInstance(); static const ssize_t baudrate = 115200; static const ssize_t off_threshold = 16; static const ssize_t on_threshold = 32; // without them it doesnt see inherited functs o_o virtual void open() override; virtual void close() override; virtual void sleep_ms(ssize_t ms); virtual ssize_t read(void *buf, size_t nbytes) override; virtual ssize_t write(char *buf, size_t nbytes); virtual Error flush(); virtual Error set_baudrate(uint32_t bd); virtual Error set_rts(bool on); virtual Error set_reset(bool on); virtual int read_cts(); ssize_t write_blocking(char *buf, ssize_t len); virtual void set_irq(bool enable); virtual void wait_data(); virtual void set_data(); }; }; // namespace bsp
A module-bsp/board/rt1051/bluetooth/BlueKitchen.cpp => module-bsp/board/rt1051/bluetooth/BlueKitchen.cpp +120 -0
@@ 0,0 1,120 @@ #include "bsp/bluetooth/Bluetooth.hpp" #include "BluetoothWorker.hpp" #include "log/log.hpp" #include "FreeRTOS.h" #include "fsl_lpuart.h" #include "board.h" using namespace bsp; BlueKitchen::BlueKitchen(unsigned int in_size, unsigned int out_size) : BluetoothCommon(in_size, out_size) { to_read = 0; read_buff = NULL; read_ready_cb = NULL; write_done_cb = NULL; in.threshold = 128; } BlueKitchen::~BlueKitchen() {} BlueKitchen *BlueKitchen::getInstance() { static BlueKitchen *k = NULL; if (k == NULL) { /// outcomming & incomming heap allocated buffers sizes /// packet on IP network cna have MTU 1500, so big enough buffers were added to not throttle comms k = new BlueKitchen(2048, 8000); } return k; } // request... from circ buffer ssize_t BlueKitchen::read(void *buf, size_t nbytes) { set_rts(false); to_read = nbytes; to_read_req = nbytes; read_buff = reinterpret_cast<char *>(buf); // set bt ptr to 0, len to 0, to read to nbytes // bt->to_read BaseType_t taskwoken = 0; uint8_t val = Bt::Message::EvtReceived; if ((to_read != 0) && (in.len >= to_read)) { to_read = 0; if (qHandle) { xQueueSendFromISR(qHandle, &val, &taskwoken); portEND_SWITCHING_ISR(taskwoken); } } set_rts(true); return 0; } void BlueKitchen::set_flowcontrol(int on) { // TODO } #include <sstream> ssize_t BlueKitchen::write_blocking(char *buf, ssize_t size) { ssize_t i = 0; BaseType_t taskwoken = 0; uint8_t val = Bt::Message::EvtSent; #ifdef DO_DEBUG_HCI_COMS std::stringstream ss; for (int i = 0; i < size; ++i) { ss << " 0x" << std::hex << (int)buf[i]; } LOG_DEBUG("--> [%d]>%s<", size, ss.str().c_str()); #endif if (BluetoothCommon::write_blocking(buf, size) == size) { xQueueSendFromISR(qHandle, &val, &taskwoken); portEND_SWITCHING_ISR(taskwoken); } else { val = Bt::Message::EvtSentError; xQueueSendFromISR(qHandle, &val, &taskwoken); } return i; } extern "C" { void LPUART2_IRQHandler(void) { uint32_t isrReg = LPUART_GetStatusFlags(BSP_BLUETOOTH_UART_BASE); static char characterReceived = 0; BaseType_t taskwoken = 0; uint8_t val = Bt::Message::EvtReceived; bsp::BlueKitchen *bt = bsp::BlueKitchen::getInstance(); if (isrReg & kLPUART_RxDataRegFullFlag) { characterReceived = LPUART_ReadByte(BSP_BLUETOOTH_UART_BASE); if (bt->in.push(characterReceived)) { val = Bt::Message::EvtRecUnwanted; xQueueSendFromISR(bt->qHandle, &val, &taskwoken); } if (bt->to_read != 0 && (bt->in.len >= bt->to_read)) { bt->to_read = 0; assert(bt->qHandle); val = Bt::Message::EvtReceived; xQueueSendFromISR(bt->qHandle, &val, &taskwoken); portEND_SWITCHING_ISR(taskwoken); } if (bt->in.threshold_guard()) { bt->set_rts(false); } } if (isrReg & kLPUART_RxOverrunFlag) { val = Bt::Message::EvtUartError; xQueueSendFromISR(bt->qHandle, &val, &taskwoken); } LPUART_ClearStatusFlags(BSP_BLUETOOTH_UART_BASE, isrReg); } };
A module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp => module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp +273 -0
@@ 0,0 1,273 @@ #include "bsp/bluetooth/Bluetooth.hpp" #include "log/log.hpp" #include "FreeRTOS.h" #include "fsl_lpuart.h" #include "board.h" using namespace bsp; // TODO it's plain copy same as in cellular - this is kind of wrong uint32_t UartGetPeripheralClock(); void BTdev::_circ::sem_take() { if (!(SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)) { xSemaphoreTake(sem, 0); } else { BaseType_t px; xSemaphoreTakeFromISR(sem, &px); } } void BTdev::_circ::sem_give() { if (!(SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)) { xSemaphoreGive(sem); } else { BaseType_t px; xSemaphoreGiveFromISR(sem, &px); } } BTdev::_circ::_circ(unsigned int size, int threshold) : head(0), tail(0), threshold(threshold), size(size), len(0) { buff = new char[size]; sem = xSemaphoreCreateBinary(); } BTdev::_circ::~_circ() { vSemaphoreDelete(sem); delete[] buff; } BluetoothCommon::BluetoothCommon(unsigned int in_size, unsigned int out_size, int threshold) : BTdev(in_size, out_size, threshold) { configure_uart_io(); configure_lpuart(); configure_cts_irq(); LOG_INFO("Bluetooth HW init done!"); } BluetoothCommon::~BluetoothCommon() {} void BluetoothCommon::open() { LOG_INFO("Bluetooth HW open!"); set_reset(true); set_irq(true); is_open = true; set_rts(true); } void BluetoothCommon::close() { LOG_INFO("close!"); // TODO destroy semaphore set_rts(false); set_irq(false); is_open = false; set_reset(false); } void BluetoothCommon::sleep_ms(ssize_t ms) { ulTaskNotifyTake(pdTRUE, ms); } BTdev::Error BluetoothCommon::flush() { // LOG_INFO("flush [%d] %s", out.len, out.tail<out.head?"reverse":"normal"); Error err = Success; int len = out.len; char *from = new char[out.len]; for (int i = 0; i < len; ++i) { out.pop(from + i); } int to_write = len; char *fromp = from; while (to_write) { while (1) { if (read_cts() == 0) { break; } else { sleep_ms(1); } } LPUART_WriteBlocking(BSP_BLUETOOTH_UART_BASE, reinterpret_cast<uint8_t *>(fromp), 1); --to_write; ++fromp; } delete[] from; return err; } ssize_t BluetoothCommon::write(char *buf, size_t nbytes) { // LOG_INFO( "write -> [%.*s]",nbytes, buf); ssize_t i = 0; // if CTS set -> ignore return 0, can use threshold_guard here too for (i = 0; i < nbytes; ++i) { if (out.push(*(buf + i)) != 0) { LOG_ERROR("Cant push!"); break; } } return i; } ssize_t BluetoothCommon::write_blocking(char *buf, ssize_t len) { int yet_to_write = len; if (len > out.size) { LOG_WARN("WRITE: %d vs %d", len, out.size); } while (yet_to_write != 0) { yet_to_write -= write(buf + len - yet_to_write, yet_to_write < out.size ? yet_to_write : (out.size - 1)); flush(); } return len; } BTdev::Error BluetoothCommon::set_baudrate(uint32_t bd) { LOG_INFO("Set baudrate: %" PRIu32, bd); Error ret = Success; int err = 0; if ((err = LPUART_SetBaudRate(BSP_BLUETOOTH_UART_BASE, bd, UartGetPeripheralClock())) != 0) { LOG_ERROR("BT error: baudrate [%lu] set err: %d", bd, err); ret = ErrorBSP; } return ret; } // set flow on -> true, set flow off -> false BTdev::Error BluetoothCommon::set_rts(bool on) { GPIO_PinWrite(BSP_BLUETOOTH_UART_RTS_PORT, BSP_BLUETOOTH_UART_RTS_PIN, on ? 0U : 1U); return Success; } BTdev::Error BluetoothCommon::set_reset(bool on) { LOG_INFO("reset %s", on ? "on" : "off"); GPIO_PinWrite(BSP_BLUETOOTH_SHUTDOWN_PORT, BSP_BLUETOOTH_SHUTDOWN_PIN, on ? 1U : 0U); return Success; } int BluetoothCommon::read_cts() { return GPIO_PinRead(BSP_BLUETOOTH_UART_CTS_PORT, BSP_BLUETOOTH_UART_CTS_PIN); } uint32_t UartGetPeripheralClock() { const int UART_PERIPHERAL_PLL_DIVIDER = 6; uint32_t freq = 0; /* To make it simple, we assume default PLL and divider settings, and the only variable from application is use PLL3 source or OSC source */ if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */ { freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / UART_PERIPHERAL_PLL_DIVIDER) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); } else { freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); } return freq; } void BluetoothCommon::configure_uart_io() { gpio_pin_config_t gpio_init_structure; gpio_init_structure.direction = kGPIO_DigitalOutput; gpio_init_structure.interruptMode = kGPIO_IntRisingOrFallingEdge; gpio_init_structure.outputLogic = 1; GPIO_PinInit(BSP_BLUETOOTH_UART_RTS_PORT, BSP_BLUETOOTH_UART_RTS_PIN, &gpio_init_structure); gpio_init_structure.direction = kGPIO_DigitalInput; gpio_init_structure.interruptMode = kGPIO_IntRisingOrFallingEdge; gpio_init_structure.outputLogic = 0; GPIO_PinInit(BSP_BLUETOOTH_UART_CTS_PORT, BSP_BLUETOOTH_UART_CTS_PIN, &gpio_init_structure); gpio_init_structure.direction = kGPIO_DigitalOutput; gpio_init_structure.interruptMode = kGPIO_NoIntmode; GPIO_PinInit(BSP_BLUETOOTH_OSC_EN_PORT, BSP_BLUETOOTH_OSC_EN_PIN, &gpio_init_structure); GPIO_PinWrite(BSP_BLUETOOTH_OSC_EN_PORT, BSP_BLUETOOTH_OSC_EN_PIN, 1U); gpio_init_structure.direction = kGPIO_DigitalOutput; GPIO_PinInit(BSP_BLUETOOTH_SHUTDOWN_PORT, BSP_BLUETOOTH_SHUTDOWN_PIN, &gpio_init_structure); } void BluetoothCommon::configure_lpuart() { lpuart_config_t bt_c; LPUART_GetDefaultConfig(&bt_c); bt_c.baudRate_Bps = baudrate; bt_c.dataBitsCount = kLPUART_EightDataBits; bt_c.parityMode = kLPUART_ParityDisabled; bt_c.isMsb = false; bt_c.rxIdleType = kLPUART_IdleTypeStartBit; bt_c.rxIdleConfig = kLPUART_IdleCharacter1; bt_c.enableTx = false; bt_c.enableRx = false; if (LPUART_Init(BSP_BLUETOOTH_UART_BASE, &bt_c, UartGetPeripheralClock()) != kStatus_Success) { LOG_ERROR("BT: UART config error Could not initialize the uart!"); return; } LPUART_ClearStatusFlags(BSP_BLUETOOTH_UART_BASE, 0xFFFFFFFF); NVIC_ClearPendingIRQ(LPUART2_IRQn); NVIC_SetPriority(LPUART2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_EnableIRQ(LPUART2_IRQn); } void BluetoothCommon::configure_cts_irq() { DisableIRQ(GPIO1_Combined_16_31_IRQn); GPIO_PortClearInterruptFlags(GPIO1, 0xFFFFFFFF); GPIO_PortEnableInterrupts(GPIO1, (1 << BSP_BLUETOOTH_UART_CTS_PIN)); EnableIRQ(GPIO1_Combined_16_31_IRQn); NVIC_SetPriority(GPIO1_Combined_16_31_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY); } void BluetoothCommon::set_irq(bool enable) { // printf("%s\n", __FUNCTION__); LPUART_EnableRx(BSP_BLUETOOTH_UART_BASE, false); LPUART_EnableTx(BSP_BLUETOOTH_UART_BASE, false); LPUART_ClearStatusFlags(BSP_BLUETOOTH_UART_BASE, 0xFFFFFFFF); if (enable) { LPUART_EnableInterrupts(BSP_BLUETOOTH_UART_BASE, kLPUART_RxDataRegFullInterruptEnable); } else { LPUART_DisableInterrupts(BSP_BLUETOOTH_UART_BASE, kLPUART_RxDataRegFullInterruptEnable); } // LPUART_EnableInterrupts(BSP_BLUETOOTH_UART_BASE, // kLPUART_RxDataRegFullInterruptEnable|kLPUART_TxDataRegEmptyInterruptEnable|kLPUART_TransmissionCompleteInterruptEnable|kLPUART_RxOverrunInterruptEnable // ); LPUART_EnableRx(BSP_BLUETOOTH_UART_BASE, true); LPUART_EnableTx(BSP_BLUETOOTH_UART_BASE, true); } extern "C" { void GPIO1_Combined_16_31_IRQHandler(void) { BaseType_t xHigherPriorityTaskWoken = 0; uint32_t irq_mask = GPIO_GetPinsInterruptFlags(GPIO1); if (irq_mask & (1 << BSP_BLUETOOTH_UART_CTS_PIN)) { LOG_DEBUG("CTS IRQ!\n"); } // Clear all IRQs GPIO_PortClearInterruptFlags(GPIO1, irq_mask); // Switch context if necessary portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } };
A module-bsp/board/rt1051/bluetooth/Bluetopia.cpp => module-bsp/board/rt1051/bluetooth/Bluetopia.cpp +57 -0
@@ 0,0 1,57 @@ #include "bluetooth/Bluetooth.hpp" #include "log/log.hpp" #include "fsl_lpuart.h" #include "board.h" namespace bsp { Bluetopia::Bluetopia(unsigned int in_size, unsigned int out_size, int threshold) : BluetoothCommon(default_buff_size, default_buff_size, 32) {} Bluetopia::~Bluetopia() {} Bluetopia *Bluetopia::getInstance() { static Bluetopia *inst = NULL; if (inst == NULL) { inst = new Bluetopia(); } return inst; } ssize_t Bluetopia::read(void *, size_t nbytes) { LOG_INFO("not implemented"); return 0; } extern "C" { void LPUART2_IRQHandler(void) { uint32_t isrReg = LPUART_GetStatusFlags(BSP_BLUETOOTH_UART_BASE); static char characterReceived = 0; if (isrReg & kLPUART_RxDataRegFullFlag) { characterReceived = LPUART_ReadByte(BSP_BLUETOOTH_UART_BASE); bsp::Bluetopia *bt = bsp::Bluetopia::getInstance(); if (bt->in.push(characterReceived) != 0) { // LOG_ERROR("BT: error no RX space!"); } else { bt->set_data(); } if (bt->in.threshold_guard()) { bt->set_rts(false); } } // TODO ths should be handled - othervise uart might be `nicelly` blocked if (isrReg & kLPUART_RxOverrunFlag) { printf("Overrun\n"); } LPUART_ClearStatusFlags(BSP_BLUETOOTH_UART_BASE, isrReg); } };
M module-bsp/board/rt1051/common/board.h => module-bsp/board/rt1051/common/board.h +1 -1
@@ 227,7 227,7 @@ * Definitions for BSP_BLUETOOTH pins configuration */ #define BSP_BLUETOOTH_UART_BASE LPUART2 ///< This macro indicate port to which GSM module is connected #define BSP_BLUETOOTH_UART_BASE LPUART2 ///< This macro indicate port to which BT module is connected #define BSP_BLUETOOTH_UART_CLKSRC kCLOCK_PllUsb1 ///< This macro indicate LPUART clock source #define BSP_BLUETOOTH_UART_RTS_PORT GPIO1
A module-bsp/bsp/bluetooth/Bluetooth.cpp => module-bsp/bsp/bluetooth/Bluetooth.cpp +37 -0
@@ 0,0 1,37 @@ #include "Bluetooth.hpp" #include <cstdarg> namespace bsp { BTdev::BTdev(unsigned int in_size, unsigned int out_size, int threshold) : flog(nullptr), in(in_size, threshold), out(out_size, threshold) { is_open = false; } BTdev::~BTdev() { } void BTdev::log(LogLvl lvl,const char* val, ...) { if(loglvl>=lvl && flog) { va_list args; va_start(args, val); flog(val,args); va_end(args); } } Bluetopia::Bluetopia(unsigned int in_size, unsigned int out_size, int threshold) : BluetoothCommon(in_size,out_size, threshold),rx_thread(0), thandle(NULL) { } Bluetopia::~Bluetopia() { } Bluetopia *Bluetopia::getInstance() { return Bluetopia::getInstance(); } };
A module-bsp/bsp/bluetooth/Bluetooth.hpp => module-bsp/bsp/bluetooth/Bluetooth.hpp +170 -0
@@ 0,0 1,170 @@ #pragma once #include <cstdint> // uint32 #include <sys/types.h> // ssize_t #include <cstdarg> #include <FreeRTOS.h> #include <thread.hpp> #include <board.h> /// c++ low level driver overlay namespace bsp { class BTdev { public: enum Error { Success, ErrorUndefined, ErrorTimeout, ErrorBSP, }; enum LogLvl { LogNone, LogError, LogWarning, LogDebug, }; typedef int(*LogFoo)(const char*,va_list args); private: LogFoo flog; public: LogLvl loglvl; bool is_open; static const unsigned int default_timeout_ms = 1000; static const unsigned int default_buff_size = 1024; static const unsigned int default_baudrate = 115200; struct _circ { SemaphoreHandle_t sem = 0; void sem_take(); void sem_give(); char* buff; volatile unsigned int head, tail, threshold; const unsigned int size; volatile unsigned int len; _circ(unsigned int size, int threshold=0); ~_circ(); inline int push(char val) { sem_take(); int ret=0; if(len<size) { buff[tail]=val; ++tail; ++len; if(tail==size) tail=0; } else { ret=-1; } sem_give(); return ret; } inline int pop(char* val) { sem_take(); int ret=0; if(val!=nullptr) { if(len) { *val = buff[head]; --len; ++head; if(head == size) head=0; } else { ret =-1; } } else { ret=-2; } sem_give(); return ret; } // reached => 1, safe => 0 inline bool threshold_guard() { return len+threshold > size; } inline void flush() { sem_take(); len=0; head=0; tail=0; sem_give(); } } in, out; BTdev(unsigned int in_size=default_buff_size, unsigned int out_size=default_buff_size, int threshold=0); virtual ~BTdev(); // generall virtual void open() = 0; // enable device -> irq enable virtual void close() = 0; // disable device -> irq disable virtual ssize_t read(void *buf, size_t nbytes) = 0; // read from internal in buffor void log(LogLvl lvl,const char* val, ...); // uart specyfic }; // Common stuff for Bluetopia and bluekitchen +clean listing for overrrides class BluetoothCommon : public BTdev { public: static const ssize_t baudrate =115200; static const ssize_t off_threshold =16; static const ssize_t on_threshold =32; public: BluetoothCommon(unsigned int in_size=default_buff_size, unsigned int out_size=default_buff_size, int threshold=0); virtual ~BluetoothCommon(); // uart specyfic Common part virtual void open() override; virtual void close() override; virtual ssize_t write(char *buf, size_t nbytes); virtual ssize_t write_blocking(char *buf, ssize_t len); Error flush(); Error set_baudrate(uint32_t bd); Error set_rts(bool on); Error set_reset(bool on); int read_cts(); void sleep_ms(ssize_t ms); void set_irq(bool enable); // Part to override virtual ssize_t read(void *buf, size_t nbytes) override = 0; private: void configure_uart_io(); void configure_lpuart(); void configure_cts_irq(); }; /// definitions needed by BT stack class Bluetopia : public BluetoothCommon { public: Bluetopia(unsigned int in_size=default_buff_size, unsigned int out_size=default_buff_size, int threshold=0); virtual ~Bluetopia(); static Bluetopia *getInstance(); virtual ssize_t read(void *buf, size_t nbytes) override; void wait_data(); void set_data(); void (*com_cb)(unsigned int transport_id, unsigned int datalen, unsigned char *buff, unsigned long param); unsigned long com_cb_param; long rx_thread; TaskHandle_t thandle; }; class BlueKitchen : public BluetoothCommon { public: BlueKitchen(unsigned int in_size=default_buff_size, unsigned int out_size=default_buff_size); virtual ~BlueKitchen(); static BlueKitchen *getInstance(); virtual ssize_t read(void *buf, size_t nbytes) override; virtual ssize_t write_blocking(char *buf, ssize_t len) override; volatile uint32_t to_read_req = 0; volatile uint32_t to_read =0; volatile char* read_buff; void set_flowcontrol(int on); void (*read_ready_cb)(void); void (*write_done_cb)(void); /// to be able to trigger events on thread xQueueHandle qHandle = nullptr; }; };
M module-bsp/targets/Target_Linux.cmake => module-bsp/targets/Target_Linux.cmake +4 -0
@@ 11,12 11,15 @@ set(BOARD_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/cellular/linux_cellular.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/harness/harness.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/rtc/rtc.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/bluetooth/test/bsp_bt.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/lpm/LinuxLPM.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/audio/linux_audiocodec.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/audio/LinuxCellularAudio.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/bluetooth/Bluetooth.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/usb_cdc/usb_cdc.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/linux/vibrator/vibrator.cpp" @@ 36,6 39,7 @@ set(BOARD_DIR_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/board/linux/audio ${CMAKE_CURRENT_SOURCE_DIR}/bsp/headset ${CMAKE_SOURCE_DIR}/module-bluetooth/Bluetooth ${CMAKE_SOURCE_DIR}/module-sys/ CACHE INTERNAL "")
M module-bsp/targets/Target_RT1051.cmake => module-bsp/targets/Target_RT1051.cmake +3 -0
@@ 92,6 92,9 @@ set(BOARD_SOURCES ${BOARD_SOURCES} "${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/lpm/RT1051LPM.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bluetooth/BluetoothCommon.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bluetooth/BlueKitchen.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/rtc/rtc.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/battery-charger/battery_charger.cpp"
A module-lwip/CMakeLists.txt => module-lwip/CMakeLists.txt +57 -0
@@ 0,0 1,57 @@ project(module-lwip VERSION 1.0 DESCRIPTION "LwIP port layer") # remove -Werror for lwip string(REPLACE "-Wno-error=format" "" LWIP_COMPILER_FLAGS "${TARGET_COMPILE_OPTIONS}") # module-lwip/lib/lwip/src/include/lwip/err.h include(${CMAKE_CURRENT_SOURCE_DIR}/lwip-includes.cmake) set (SOURCES "${LWIP_DIR}/contrib/ports/freertos/sys_arch.c" "${CMAKE_CURRENT_SOURCE_DIR}/lib/dhcp-server/dhserver.c" ) if (CMAKE_BUILD_TYPE STREQUAL "Debug") set (LWIP_DEFINITIONS LWIP_DEBUG=1) endif() include(${LWIP_DIR}/src/Filelists.cmake) include(${LWIP_DIR}/contrib/Filelists.cmake) # for any target dependent on lwip # target_include_directories(<app> PRIVATE ${LWIP_INCLUDE_DIRS}) # add to target set(LWIP_LIBRARIES lwipcontribapps lwipallapps lwipcore) ### TODO maybe make it a bit shared add_library(${PROJECT_NAME} STATIC ${SOURCES} ${BOARD_DIR_SOURCES}) target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_CONFIG_DEFINITIONS} ${PROJECT_TARGET} ${TARGET_COMPILE_DEFINITIONS} ${BOARD_DIR_DEFINITIONS} ) target_compile_features(${PROJECT_NAME} PUBLIC ${TARGET_COMPILE_FEATURES}) target_compile_options(${PROJECT_NAME} PUBLIC ${TARGET_COMPILE_OPTIONS}) target_link_options(${PROJECT_NAME} PUBLIC ${TARGET_LINK_OPTIONS}) target_include_directories( ${PROJECT_NAME} PUBLIC ${BOARD_DIR_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR} ${TARGET_LIBRARIES_INCLUDES} ${LWIP_INCLUDE_DIRS} ) target_link_libraries( ${PROJECT_NAME} module-bsp module-utils module-vfs module-sys ${BOARD_DIR_LIBRARIES} )
A module-lwip/README.md => module-lwip/README.md +20 -0
@@ 0,0 1,20 @@ # LwIP system integration ======================== # Why? Bluetooth APN needs IP & routing and level 2 TCP/IP stack. # How? LwIP sources needed are added as _shallow_ submodule in lib. Our needed sources, not from libraries are in interfaces (now only there) * module-lwip One place for LwIP code * lib Place for LwIP submodule * interfaces Our defined LwIP interfaces place. We need: * BNEP - bluetooth network encapsulation protocol - interface * PPP - gsm interface for PPP PDP communication
A module-lwip/includes/arch/cc.h => module-lwip/includes/arch/cc.h +13 -0
@@ 0,0 1,13 @@ #pragma once #define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) \ u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)] __attribute__((section(".sdram"))) __attribute__((aligned(4))); #define LWIP_PLATFORM_ASSERT(x) \ do { \ printf("Assertion \"%s\" failed at line %d in %s\n", x, __LINE__, __FILE__); \ abort(); \ } while (0) #define TCPIP_MBOX_SIZE 1028 #define TCPIP_THREAD_STACKSIZE 4096
A module-lwip/includes/lwipopts.h => module-lwip/includes/lwipopts.h +238 -0
@@ 0,0 1,238 @@ #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ /** * NO_SYS==1: Bare metal lwIP */ #define NO_SYS 0 /** * LWIP_NETCONN==0: Disable Netconn API (require to use api_lib.c) */ #define LWIP_NETCONN 0 /** * LWIP_SOCKET==0: Disable Socket API (require to use sockets.c) */ #define LWIP_SOCKET 0 /** * SYS_LIGHTWEIGHT_PROT==1: enable inter-task protection (and task-vs-interrupt * protection) for certain critical regions during buffer allocation, deallocation * and memory allocation and deallocation. * ATTENTION: This is required when using lwIP from more than one context! If * you disable this, you must be sure what you are doing! */ /** * SYS_LIGHTWEIGHT_PROT==0: */ #define SYS_LIGHTWEIGHT_PROT 0 /* ---------- Memory options ---------- */ /** * MEM_ALIGNMENT: should be set to the alignment of the CPU * 4 byte alignment -> #define MEM_ALIGNMENT 4 * 2 byte alignment -> #define MEM_ALIGNMENT 2 */ #ifndef MEM_ALIGNMENT #define MEM_ALIGNMENT 4 #endif /** * MEM_SIZE: the size of the heap memory. If the application will send * a lot of data that needs to be copied, this should be set high. */ #ifndef MEM_SIZE #define MEM_SIZE (64 * 1024) #endif /* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application sends a lot of data out of ROM (or other static memory), this should be set high. */ #ifndef MEMP_NUM_PBUF #define MEMP_NUM_PBUF 15 #endif /* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One per active UDP "connection". */ #ifndef MEMP_NUM_UDP_PCB #define MEMP_NUM_UDP_PCB 6 #endif /* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. */ #ifndef MEMP_NUM_TCP_PCB #define MEMP_NUM_TCP_PCB 10 #endif /* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. */ #ifndef MEMP_NUM_TCP_PCB_LISTEN #define MEMP_NUM_TCP_PCB_LISTEN 6 #endif /* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. */ #ifndef MEMP_NUM_TCP_SEG #define MEMP_NUM_TCP_SEG 22 #endif /* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. */ #ifndef MEMP_NUM_SYS_TIMEOUT #define MEMP_NUM_SYS_TIMEOUT 10 #endif /* ---------- Pbuf options ---------- */ /* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ #ifndef PBUF_POOL_SIZE #define PBUF_POOL_SIZE 9 #endif /* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ /* Default value is defined in lwip\src\include\lwip\opt.h as * LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)*/ /* ---------- TCP options ---------- */ #ifndef LWIP_TCP #define LWIP_TCP 1 #endif #ifndef TCP_TTL #define TCP_TTL 255 #endif /* Controls if TCP should queue segments that arrive out of order. Define to 0 if your device is low on memory. */ #ifndef TCP_QUEUE_OOSEQ #define TCP_QUEUE_OOSEQ 0 #endif /* TCP Maximum segment size. */ #ifndef TCP_MSS #define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */ #endif /* TCP sender buffer space (bytes). */ #ifndef TCP_SND_BUF #define TCP_SND_BUF (6 * TCP_MSS) // 2 #endif /* TCP sender buffer space (pbufs). This must be at least = 2 * TCP_SND_BUF/TCP_MSS for things to work. */ #ifndef TCP_SND_QUEUELEN #define TCP_SND_QUEUELEN (3 * TCP_SND_BUF) / TCP_MSS // 6 #endif /* TCP receive window. */ #ifndef TCP_WND #define TCP_WND (2 * TCP_MSS) #endif /* Enable backlog*/ #ifndef TCP_LISTEN_BACKLOG #define TCP_LISTEN_BACKLOG 1 #endif /* ---------- Network Interfaces options ---------- */ /* Support netif api (in netifapi.c). */ #ifndef LWIP_NETIF_API #define LWIP_NETIF_API 0 #endif /* ---------- ICMP options ---------- */ #ifndef LWIP_ICMP #define LWIP_ICMP 1 #endif /* ---------- DHCP options ---------- */ /* Define LWIP_DHCP to 1 if you want DHCP configuration of interfaces. DHCP is not implemented in lwIP 0.5.1, however, so turning this on does currently not work. */ #ifndef LWIP_DHCP #define LWIP_DHCP 1 #endif /* ---------- UDP options ---------- */ #ifndef LWIP_UDP #define LWIP_UDP 1 #endif #ifndef UDP_TTL #define UDP_TTL 255 #endif /* ---------- Statistics options ---------- */ #ifndef LWIP_STATS #define LWIP_STATS 0 #endif #ifndef LWIP_PROVIDE_ERRNO #define LWIP_PROVIDE_ERRNO 1 #endif /* -------------------------------------- ---------- Checksum options ---------- -------------------------------------- */ /* Some MCU allow computing and verifying the IP, UDP, TCP and ICMP checksums by hardware: - To use this feature let the following define uncommented. - To disable it and process by CPU comment the the checksum. */ //#define CHECKSUM_BY_HARDWARE #ifdef CHECKSUM_BY_HARDWARE /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ #define CHECKSUM_GEN_IP 0 /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/ #define CHECKSUM_GEN_UDP 0 /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/ #define CHECKSUM_GEN_TCP 0 /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/ #define CHECKSUM_CHECK_IP 0 /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/ #define CHECKSUM_CHECK_UDP 0 /* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/ #define CHECKSUM_CHECK_TCP 0 #else /* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/ #define CHECKSUM_GEN_IP 1 /* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/ #define CHECKSUM_GEN_UDP 1 /* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/ #define CHECKSUM_GEN_TCP 1 /* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/ #define CHECKSUM_CHECK_IP 1 /* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/ #define CHECKSUM_CHECK_UDP 1 /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/ #define CHECKSUM_CHECK_TCP 1 #endif /* ------------------------------------ ---------- Debugging options ---------- ------------------------------------ */ // #define LWIP_DEBUG // TODO: map these to <stdint.h> #ifdef LWIP_DEBUG // #define U8_F "c" // #define S8_F "c" // #define X8_F "02x" // #define U16_F "u" // #define S16_F "d" // #define X16_F "x" // #define U32_F "lu" // #define S32_F "ld" // #define X32_F "x" // #define SZT_F "lu" #endif #if (LWIP_DNS || LWIP_IGMP || LWIP_IPV6) && !defined(LWIP_RAND) /* When using IGMP or IPv6, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value*/ #include "lwip/arch.h" u32_t lwip_rand(void); #define LWIP_RAND() lwip_rand() #endif #endif /* __LWIPOPTS_H__ */ /*****END OF FILE****/
A module-lwip/lib/dhcp-server/LICENSE => module-lwip/lib/dhcp-server/LICENSE +21 -0
@@ 0,0 1,21 @@ The MIT License (MIT) Copyright (c) 2015 Fetisov Sergey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
A module-lwip/lib/dhcp-server/README => module-lwip/lib/dhcp-server/README +2 -0
@@ 0,0 1,2 @@ DHCP Server for lwIP from stm32 ethernet over usb (rndis + lwip) project https://github.com/fetisov/lrndis
A module-lwip/lib/dhcp-server/dhserver.c => module-lwip/lib/dhcp-server/dhserver.c +335 -0
@@ 0,0 1,335 @@ /* * The MIT License (MIT) * * Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "dhserver.h" /* DHCP message type */ #define DHCP_DISCOVER 1 #define DHCP_OFFER 2 #define DHCP_REQUEST 3 #define DHCP_DECLINE 4 #define DHCP_ACK 5 #define DHCP_NAK 6 #define DHCP_RELEASE 7 #define DHCP_INFORM 8 /* DHCP options */ enum DHCP_OPTIONS { DHCP_PAD = 0, DHCP_SUBNETMASK = 1, DHCP_ROUTER = 3, DHCP_DNSSERVER = 6, DHCP_HOSTNAME = 12, DHCP_DNSDOMAIN = 15, DHCP_MTU = 26, DHCP_BROADCAST = 28, DHCP_PERFORMROUTERDISC = 31, DHCP_STATICROUTE = 33, DHCP_NISDOMAIN = 40, DHCP_NISSERVER = 41, DHCP_NTPSERVER = 42, DHCP_VENDOR = 43, DHCP_IPADDRESS = 50, DHCP_LEASETIME = 51, DHCP_OPTIONSOVERLOADED = 52, DHCP_MESSAGETYPE = 53, DHCP_SERVERID = 54, DHCP_PARAMETERREQUESTLIST = 55, DHCP_MESSAGE = 56, DHCP_MAXMESSAGESIZE = 57, DHCP_RENEWALTIME = 58, DHCP_REBINDTIME = 59, DHCP_CLASSID = 60, DHCP_CLIENTID = 61, DHCP_USERCLASS = 77, /* RFC 3004 */ DHCP_FQDN = 81, DHCP_DNSSEARCH = 119, /* RFC 3397 */ DHCP_CSR = 121, /* RFC 3442 */ DHCP_MSCSR = 249, /* MS code for RFC 3442 */ DHCP_END = 255 }; typedef struct { uint8_t dp_op; /* packet opcode type */ uint8_t dp_htype; /* hardware addr type */ uint8_t dp_hlen; /* hardware addr length */ uint8_t dp_hops; /* gateway hops */ uint32_t dp_xid; /* transaction ID */ uint16_t dp_secs; /* seconds since boot began */ uint16_t dp_flags; uint8_t dp_ciaddr[4]; /* client IP address */ uint8_t dp_yiaddr[4]; /* 'your' IP address */ uint8_t dp_siaddr[4]; /* server IP address */ uint8_t dp_giaddr[4]; /* gateway IP address */ uint8_t dp_chaddr[16]; /* client hardware address */ uint8_t dp_legacy[192]; uint8_t dp_magic[4]; uint8_t dp_options[275]; /* options area */ } DHCP_TYPE; DHCP_TYPE dhcp_data; static struct udp_pcb *pcb = NULL; static dhcp_config_t *config = NULL; char magic_cookie[] = {0x63,0x82,0x53,0x63}; static dhcp_entry_t *entry_by_ip(uint32_t ip) { int i; for (i = 0; i < config->num_entry; i++) if (*(uint32_t *)config->entries[i].addr == ip) return &config->entries[i]; return NULL; } static dhcp_entry_t *entry_by_mac(uint8_t *mac) { int i; for (i = 0; i < config->num_entry; i++) if (memcmp(config->entries[i].mac, mac, 6) == 0) return &config->entries[i]; return NULL; } static __inline bool is_vacant(dhcp_entry_t *entry) { return memcmp("\0\0\0\0\0", entry->mac, 6) == 0; } static dhcp_entry_t *vacant_address(void) { int i; for (i = 0; i < config->num_entry; i++) if (is_vacant(config->entries + i)) return config->entries + i; return NULL; } static __inline void free_entry(dhcp_entry_t *entry) { memset(entry->mac, 0, 6); } static uint8_t *find_dhcp_option(uint8_t *attrs, int size, uint8_t attr) { int i = 0; while ((i + 1) < size) { int next = i + attrs[i + 1] + 2; if (next > size) return NULL; if (attrs[i] == attr) return attrs + i; i = next; } return NULL; } static int fill_options(void *dest, uint8_t msg_type, const char *domain, uint32_t dns, int lease_time, uint32_t serverid, uint32_t router, uint32_t subnet) { uint8_t *ptr = (uint8_t *)dest; /* ACK message type */ *ptr++ = 53; *ptr++ = 1; *ptr++ = msg_type; /* dhcp server identifier */ *ptr++ = DHCP_SERVERID; *ptr++ = 4; *(uint32_t *)ptr = serverid; ptr += 4; /* lease time */ *ptr++ = DHCP_LEASETIME; *ptr++ = 4; *ptr++ = (lease_time >> 24) & 0xFF; *ptr++ = (lease_time >> 16) & 0xFF; *ptr++ = (lease_time >> 8) & 0xFF; *ptr++ = (lease_time >> 0) & 0xFF; /* subnet mask */ *ptr++ = DHCP_SUBNETMASK; *ptr++ = 4; *(uint32_t *)ptr = subnet; ptr += 4; /* router */ if (router != 0) { *ptr++ = DHCP_ROUTER; *ptr++ = 4; *(uint32_t *)ptr = router; ptr += 4; } /* domain name */ if (domain != NULL) { int len = strlen(domain); *ptr++ = DHCP_DNSDOMAIN; *ptr++ = len; memcpy(ptr, domain, len); ptr += len; } /* domain name server (DNS) */ if (dns != 0) { *ptr++ = DHCP_DNSSERVER; *ptr++ = 4; *(uint32_t *)ptr = dns; ptr += 4; } /* end */ *ptr++ = DHCP_END; return ptr - (uint8_t *)dest; } static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, const struct ip4_addr *addr, u16_t port) { (void) arg; (void) addr; uint8_t *ptr; dhcp_entry_t *entry; struct pbuf *pp; unsigned int n = p->len; if (n > sizeof(dhcp_data)) n = sizeof(dhcp_data); memcpy(&dhcp_data, p->payload, n); switch (dhcp_data.dp_options[2]) { case DHCP_DISCOVER: entry = entry_by_mac(dhcp_data.dp_chaddr); if (entry == NULL) entry = vacant_address(); if (entry == NULL) break; dhcp_data.dp_op = 2; /* reply */ dhcp_data.dp_secs = 0; dhcp_data.dp_flags = 0; *(uint32_t *)dhcp_data.dp_yiaddr = *(uint32_t *)entry->addr; memcpy(dhcp_data.dp_magic, magic_cookie, 4); memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); fill_options(dhcp_data.dp_options, DHCP_OFFER, config->domain, *(uint32_t *)config->dns, entry->lease, *(uint32_t *)config->addr, *(uint32_t *)config->addr, *(uint32_t *)entry->subnet); pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); if (pp == NULL) break; memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); pbuf_free(pp); break; case DHCP_REQUEST: /* 1. find requested ipaddr in option list */ ptr = find_dhcp_option(dhcp_data.dp_options, sizeof(dhcp_data.dp_options), DHCP_IPADDRESS); if (ptr == NULL) break; if (ptr[1] != 4) break; ptr += 2; /* 2. does hw-address registered? */ entry = entry_by_mac(dhcp_data.dp_chaddr); if (entry != NULL) free_entry(entry); /* 3. find requested ipaddr */ entry = entry_by_ip(*(uint32_t *)ptr); if (entry == NULL) break; if (!is_vacant(entry)) break; /* 4. fill struct fields */ memcpy(dhcp_data.dp_yiaddr, ptr, 4); dhcp_data.dp_op = 2; /* reply */ dhcp_data.dp_secs = 0; dhcp_data.dp_flags = 0; memcpy(dhcp_data.dp_magic, magic_cookie, 4); /* 5. fill options */ memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); fill_options(dhcp_data.dp_options, DHCP_ACK, config->domain, *(uint32_t *)config->dns, entry->lease, *(uint32_t *)config->addr, *(uint32_t *)config->addr, *(uint32_t *)entry->subnet); /* 6. send ACK */ pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); if (pp == NULL) break; memcpy(entry->mac, dhcp_data.dp_chaddr, 6); memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); pbuf_free(pp); break; default: break; } pbuf_free(p); } err_t dhserv_init(dhcp_config_t *c) { err_t err; // udp_init(); already called from lwip_init dhserv_free(); pcb = udp_new(); if (pcb == NULL) return ERR_MEM; err = udp_bind(pcb, IP_ADDR_ANY, c->port); if (err != ERR_OK) { dhserv_free(); return err; } udp_recv(pcb, udp_recv_proc, NULL); config = c; return ERR_OK; } void dhserv_free(void) { if (pcb == NULL) return; udp_remove(pcb); pcb = NULL; }
A module-lwip/lib/dhcp-server/dhserver.h => module-lwip/lib/dhcp-server/dhserver.h +64 -0
@@ 0,0 1,64 @@ /* * The MIT License (MIT) * * Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* * version: 1.0 demo (7.02.2015) * brief: tiny dhcp ipv4 server using lwip (pcb) * ref: https://lists.gnu.org/archive/html/lwip-users/2012-12/msg00016.html */ #ifndef DHSERVER_H #define DHSERVER_H // #include <stdint.h> #include <stdbool.h> // #include <stdio.h> #include <string.h> #include "lwip/err.h" #include "lwip/udp.h" #include "netif/etharp.h" #include "lwip/ip_addr.h" typedef struct dhcp_entry { uint8_t mac[6]; uint8_t addr[4]; uint8_t subnet[4]; uint32_t lease; } dhcp_entry_t; typedef struct dhcp_config { uint8_t addr[4]; uint16_t port; uint8_t dns[4]; const char *domain; int num_entry; dhcp_entry_t *entries; } dhcp_config_t; err_t dhserv_init(dhcp_config_t *config); void dhserv_free(void); #endif /* DHSERVER_H */
A module-lwip/lib/lwip => module-lwip/lib/lwip +1 -0
A module-lwip/lwip-includes.cmake => module-lwip/lwip-includes.cmake +12 -0
@@ 0,0 1,12 @@ set (LWIP_DIR ${CMAKE_SOURCE_DIR}/module-lwip/lib/lwip) set (LWIP_CONTRIB_DIR ${CMAKE_SOURCE_DIR}/module-lwip/lib/lwip/contrib) set (LWIP_INCLUDE_DIRS "${LWIP_DIR}/src/include" "${LWIP_DIR}/contrib" "${LWIP_DIR}/contrib/ports/freertos/include" "${CMAKE_SOURCE_DIR}/module-lwip/includes/" "${CMAKE_SOURCE_DIR}/module-lwip/lib/" ) set(LWIP_LIBRARIES lwipcontribapps lwipallapps lwipcore)
A module-lwip/tests/CMakeLists.txt => module-lwip/tests/CMakeLists.txt +0 -0
M module-services/CMakeLists.txt => module-services/CMakeLists.txt +5 -0
@@ 3,6 3,8 @@ cmake_minimum_required(VERSION 3.14) project(module-services VERSION 1.0 DESCRIPTION "Library with all services.") include(${CMAKE_SOURCE_DIR}/module-lwip/lwip-includes.cmake) if(${PROJECT_TARGET} STREQUAL "TARGET_RT1051") include(targets/Target_RT1051.cmake) elseif(${PROJECT_TARGET} STREQUAL "TARGET_Linux") @@ 21,6 23,8 @@ add_subdirectory( service-appmgr ) add_subdirectory( service-db ) add_subdirectory( service-cellular ) add_subdirectory( service-audio ) add_subdirectory( service-bluetooth ) add_subdirectory( service-lwip ) add_subdirectory( service-desktop ) add_subdirectory( service-fota ) add_subdirectory( service-antenna ) @@ 33,6 37,7 @@ target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_TARGET}) target_compile_definitions(${PROJECT_NAME} PUBLIC ${TARGET_COMPILE_DEFINITIONS}) target_include_directories(${PROJECT_NAME} PUBLIC ${BOARD_DIR_INCLUDES}) target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_INCLUDES}) target_include_directories(${PROJECT_NAME} PUBLIC ${LWIP_INCLUDE_DIRS}) target_compile_features(${PROJECT_NAME} PUBLIC ${TARGET_COMPILE_FEATURES}) target_compile_options(${PROJECT_NAME} PUBLIC ${TARGET_COMPILE_OPTIONS})
A module-services/service-bluetooth/CMakeLists.txt => module-services/service-bluetooth/CMakeLists.txt +19 -0
@@ 0,0 1,19 @@ include_directories( ${CMAKE_PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_LIST_DIR}" ) include_directories( ${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_LIST_DIR}" ) message( "${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}" ) target_sources( ${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/ServiceBluetooth.cpp" )
A module-services/service-bluetooth/ServiceBluetooth.cpp => module-services/service-bluetooth/ServiceBluetooth.cpp +101 -0
@@ 0,0 1,101 @@ #include "ServiceBluetooth.hpp" #include "Service/Service.hpp" #include "Service/Message.hpp" #include "MessageType.hpp" #include "messages/BluetoothMessage.hpp" #include <log/log.hpp> #include <service-lwip/ServiceLwIP.hpp> const char *ServiceBluetooth::serviceName = "ServiceBluetooth"; ServiceBluetooth::ServiceBluetooth() : sys::Service(serviceName) { LOG_INFO("[ServiceBluetooth] Initializing"); testTimerID = CreateTimer(3000, true); ReloadTimer(testTimerID); } ServiceBluetooth::~ServiceBluetooth() { LOG_INFO("[ServiceBluetooth] Cleaning resources"); } // Invoked when timer ticked void ServiceBluetooth::TickHandler(uint32_t id) {} // This code is experimental: // this means it is an init point of bluetooth feature handling sys::ReturnCodes ServiceBluetooth::InitHandler() { LOG_ERROR("Bluetooth experimental!"); worker = std::make_unique<BluetoothWorker>(this); return sys::ReturnCodes::Success; } sys::ReturnCodes ServiceBluetooth::DeinitHandler() { return sys::ReturnCodes::Success; } sys::Message_t ServiceBluetooth::DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) { try { switch (static_cast<MessageType>(msg->messageType)) { case MessageType::BluetoothRequest: { BluetoothMessage *lmsg = dynamic_cast<BluetoothMessage *>(msg); LOG_INFO("Bluetooth request!"); switch (lmsg->req) { case BluetoothMessage::Start: worker->run(); break; case BluetoothMessage::Scan: if (worker->scan()) { return std::make_shared<sys::ResponseMessage>(sys::ReturnCodes::Success); } else { return std::make_shared<sys::ResponseMessage>(sys::ReturnCodes::Failure); } break; case BluetoothMessage::PAN: { /// TODO request lwip first... /// because TODO blocking message - wrecks system LOG_INFO("Request LwIP running!"); // auto ret = message_lwip(this, LwIP_message::Request::Start); // if (ret != sys::ReturnCodes::Success) { // LOG_ERROR("Request for LwIP start failed"); // } // else { /// TODO request PPP LOG_INFO("Start PAN"); worker->start_pan(); // } } break; case BluetoothMessage::Visible: worker->set_visible(); break; default: break; } break; } default: LOG_INFO("BT not handled!"); break; } } catch (std::exception &ex) { LOG_ERROR("Exception on BtService!: %s", ex.what()); } return std::make_shared<sys::ResponseMessage>(); } sys::ReturnCodes ServiceBluetooth::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_ERROR("TODO"); return sys::ReturnCodes::Success; }
A module-services/service-bluetooth/ServiceBluetooth.hpp => module-services/service-bluetooth/ServiceBluetooth.hpp +24 -0
@@ 0,0 1,24 @@ #pragma once #include "Service/Service.hpp" #include "Bluetooth/BluetoothWorker.hpp" #include <memory> class ServiceBluetooth : public sys::Service { public: ServiceBluetooth(); ~ServiceBluetooth(); virtual sys::Message_t DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) override; void TickHandler(uint32_t id) override; sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; virtual sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override; private: static const char *serviceName; uint32_t testTimerID; std::unique_ptr<BluetoothWorker> worker; };
A module-services/service-bluetooth/messages/BluetoothMessage.hpp => module-services/service-bluetooth/messages/BluetoothMessage.hpp +20 -0
@@ 0,0 1,20 @@ #pragma once #include "Service/Message.hpp" #include "MessageType.hpp" class BluetoothMessage : public sys::DataMessage { public: enum Request { None, Start, Scan, PAN, Visible, }; enum Request req = Request::None; BluetoothMessage(enum Request req = None) : sys::DataMessage(MessageType::BluetoothRequest), req(req){}; virtual ~BluetoothMessage() = default; };
A module-services/service-lwip/CMakeLists.txt => module-services/service-lwip/CMakeLists.txt +10 -0
@@ 0,0 1,10 @@ message( "${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}" ) include_directories( ${CMAKE_PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_LIST_DIR}" ) target_sources( ${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/ServiceLwIP.cpp" )
A module-services/service-lwip/ServiceLwIP.cpp => module-services/service-lwip/ServiceLwIP.cpp +110 -0
@@ 0,0 1,110 @@ #include "ServiceLwIP.hpp" #include <log/log.hpp> #include "MessageType.hpp" #include "Service/Message.hpp" #include "Service/Service.hpp" extern "C" { #include "dhcp-server/dhserver.h" #include "lwip/apps/httpd.h" #include "lwip/init.h" #include "lwip/opt.h" #include "lwip/tcpip.h" }; #define NUM_DHCP_ENTRY 3 extern "C" { static dhcp_entry_t entries[NUM_DHCP_ENTRY] = { /* mac ip address subnet mask lease time */ {{0}, {192, 168, 7, 2}, {255, 255, 255, 0}, 24 * 60 * 60}, {{0}, {192, 168, 7, 3}, {255, 255, 255, 0}, 24 * 60 * 60}, {{0}, {192, 168, 7, 4}, {255, 255, 255, 0}, 24 * 60 * 60}}; static dhcp_config_t dhcp_config = { {192, 168, 7, 1}, 67, /* server address, port */ {0, 0, 0, 0}, /* dns server */ NULL, /* dns suffix */ NUM_DHCP_ENTRY, /* num entry */ entries /* entries */ }; }; sys::ReturnCodes message_lwip(sys::Service *app, LwIP_message::Request req) { std::shared_ptr<LwIP_message> msg = std::make_shared<LwIP_message>(req); auto ret = sys::Bus::SendUnicast(msg, "ServiceLwIP", app, 5000); if (ret.first != sys::ReturnCodes::Success) { LOG_ERROR("err: %s", c_str(ret.first)); } return ret.first; } const char *ServiceLwIP::serviceName = "ServiceLwIP"; ServiceLwIP::ServiceLwIP() : sys::Service(serviceName) { LOG_INFO("[ServiceLwIP] Initializing"); testTimerID = CreateTimer(3000, true); ReloadTimer(testTimerID); LOG_INFO("Start lwip!"); tcpip_init(nullptr, nullptr); // lwip_init(); dhserv_init(&dhcp_config); httpd_init(); } void ServiceLwIP::TickHandler(uint32_t id) {} sys::ReturnCodes ServiceLwIP::InitHandler() { LOG_ERROR("LwIP experimental!"); return sys::ReturnCodes::Success; } sys::ReturnCodes ServiceLwIP::DeinitHandler() { LOG_ERROR("TODO"); return sys::ReturnCodes::Success; } sys::Message_t ServiceLwIP::DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) { LOG_ERROR("TRY START LWIP"); try { switch (static_cast<MessageType>(msg->messageType)) { case MessageType::LwIP_request: { LwIP_message *lmsg = dynamic_cast<LwIP_message *>(msg); switch (lmsg->req) { case LwIP_message::Request::Start: LOG_ERROR("START LWIP"); tcpip_init(nullptr, nullptr); // lwip_init(); dhserv_init(&dhcp_config); httpd_init(); LOG_INFO("LwIP started!"); break; default: LOG_ERROR("Not implemented: %d", lmsg->req); } } break; default: LOG_ERROR("Not handled messageType: %d", static_cast<int>(msg->messageType)); } } catch (std::exception &ex) { LOG_ERROR("Exception on BtService!: %s", ex.what()); } return std::make_shared<sys::ResponseMessage>(); } sys::ReturnCodes ServiceLwIP::SwitchPowerModeHandler(const sys::ServicePowerMode mode) { LOG_ERROR("TODO"); return sys::ReturnCodes::Success; }
A module-services/service-lwip/ServiceLwIP.hpp => module-services/service-lwip/ServiceLwIP.hpp +39 -0
@@ 0,0 1,39 @@ #pragma once #include <memory> #include "MessageType.hpp" #include "Service/Message.hpp" #include "Service/Service.hpp" class LwIP_message : public sys::DataMessage { public: enum Request { None, Start, Stop, }; enum Request req = Request::None; LwIP_message(enum Request req = None) : sys::DataMessage(MessageType::LwIP_request), req(req){}; virtual ~LwIP_message() = default; }; sys::ReturnCodes message_lwip(sys::Service *app, LwIP_message::Request req); class ServiceLwIP : public sys::Service { public: ServiceLwIP(); ~ServiceLwIP() = default; virtual sys::Message_t DataReceivedHandler(sys::DataMessage *msg, sys::ResponseMessage *resp) override; void TickHandler(uint32_t id) override; sys::ReturnCodes InitHandler() override; sys::ReturnCodes DeinitHandler() override; virtual sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override; private: static const char *serviceName; uint32_t testTimerID; };
M source/main.cpp => source/main.cpp +4 -0
@@ 26,6 26,7 @@ #include "service-appmgr/ApplicationManager.hpp" #include "service-audio/ServiceAudio.hpp" #include "service-audio/api/AudioServiceAPI.hpp" #include "service-bluetooth/ServiceBluetooth.hpp" #include "service-cellular/ServiceCellular.hpp" #include "service-cellular/api/CellularServiceAPI.hpp" #include "service-db/ServiceDB.hpp" @@ 33,6 34,7 @@ #include "service-desktop/ServiceDesktop.hpp" #include "service-evtmgr/Constants.hpp" #include "service-evtmgr/EventManager.hpp" #include "service-lwip/ServiceLwIP.hpp" #include "service-fota/ServiceFota.hpp" #include "service-antenna/ServiceAntenna.hpp" @@ 182,6 184,8 @@ int main() ret |= sys::SystemManager::CreateService(std::make_shared<FotaService::Service>(), sysmgr.get()); #endif ret |= sys::SystemManager::CreateService(std::make_shared<ServiceAudio>(), sysmgr.get()); ret |= sys::SystemManager::CreateService(std::make_shared<ServiceBluetooth>(), sysmgr.get()); ret |= sys::SystemManager::CreateService(std::make_shared<ServiceLwIP>(), sysmgr.get()); // Service Desktop disabled on master - pulling read on usb driver // ret |= sys::SystemManager::CreateService(std::make_shared<ServiceDesktop>(), sysmgr.get());