~aleteoryx/muditaos

b53dec1ff2880625daa7cfc15f62779f818d9077 — Lefucjusz 2 years ago 824cb5a
[MOS-1012] Fix occasional crash when unplugging Pure from PC

Fix of the unhandled error issue that resulted
in occasional device crash when disconnecting
from PC with MC app running.
M module-bsp/CMakeLists.txt => module-bsp/CMakeLists.txt +1 -1
@@ 51,7 51,7 @@ target_compile_definitions(${PROJECT_NAME}
        -D__STARTUP_INITIALIZE_NONCACHEDATA
        -D__USE_CMSIS
        -DDEBUG_VCOM=1
        -DDEBUG_USB=1
        -DDEBUG_USB=0
        )

target_include_directories(${PROJECT_NAME}

M module-bsp/board/linux/usb_cdc/usb_cdc.cpp => module-bsp/board/linux/usb_cdc/usb_cdc.cpp +36 -32
@@ 9,7 9,7 @@
#include <sys/inotify.h>
#include <limits.h>

#ifndef DEUBG_USB
#if DEBUG_USB == 0
#undef LOG_PRINTF
#undef LOG_TRACE
#undef LOG_DEBUG


@@ 28,14 28,16 @@
#define LOG_FATAL(...)
#define LOG_CUSTOM(loggerLevel, ...)
#endif

namespace
{
    xTaskHandle taskHandleReceive;
}

namespace bsp
{
    int fd;
    int fdNofity;
    int fdNotify;
    xQueueHandle USBReceiveQueue;
    xQueueHandle USBIrqQueue;
    constexpr auto ptsFileName = "/tmp/purephone_pts_name";


@@ 58,34 60,38 @@ namespace bsp

    void checkUsbStatus()
    {
        char eventsBuff[((sizeof(inotify_event) + NAME_MAX + 1))];
        int len = read(fdNofity, eventsBuff, ((sizeof(inotify_event) + NAME_MAX + 1)));
        if (len > 0) {
            const inotify_event *event = (inotify_event *)&eventsBuff[0];
            if (event->mask & IN_OPEN) {
                USBDeviceStatus notification = USBDeviceStatus::Configured;
                xQueueSend(USBIrqQueue, &notification, 0);
            }
            if (event->mask & IN_CLOSE_WRITE) {
                USBDeviceStatus notification = USBDeviceStatus::Disconnected;
                xQueueSend(USBIrqQueue, &notification, 0);
            }
        constexpr auto eventsBufferSize = sizeof(inotify_event) + NAME_MAX + 1;
        char eventsBuffer[eventsBufferSize];

        const auto len = read(fdNotify, eventsBuffer, sizeof(eventsBuffer));
        if (len <= 0) {
            return;
        }

        const auto event = reinterpret_cast<inotify_event *>(eventsBuffer);
        if (event->mask & IN_OPEN) {
            USBDeviceStatus notification = USBDeviceStatus::Configured;
            xQueueSend(USBIrqQueue, &notification, 0);
        }
        if (event->mask & IN_CLOSE_WRITE) {
            USBDeviceStatus notification = USBDeviceStatus::Disconnected;
            xQueueSend(USBIrqQueue, &notification, 0);
        }
    }

    int usbCDCReceive([[maybe_unused]] void *ptr)
    ssize_t usbCDCReceive([[maybe_unused]] void *ptr)
    {
        LOG_INFO("[ServiceDesktop:BSP_Driver] Start reading on fd:%d", fd);
        char inputData[SERIAL_BUFFER_LEN];
        char inputData[constants::serial::bufferLength];

        while (1) {
        while (true) {

            checkUsbStatus();

            if (uxQueueSpacesAvailable(USBReceiveQueue) != 0) {
                memset(inputData, 0, SERIAL_BUFFER_LEN);
                memset(inputData, 0, sizeof(inputData));

                const auto length = read(fd, &inputData[0], SERIAL_BUFFER_LEN);
                const auto length = read(fd, inputData, sizeof(inputData));
                if (length > 0) {
                    LOG_DEBUG("[ServiceDesktop:BSP_Driver] Received: %d signs", static_cast<int>(length));
#if USBCDC_ECHO_ENABLED


@@ 107,8 113,8 @@ namespace bsp
                        continue;
                    }
#endif
                    std::string *receiveMsg = new std::string(inputData, inputData + length);
                    xQueueSend(USBReceiveQueue, &receiveMsg, portMAX_DELAY);
                    auto receivedMsg = new std::string(inputData, inputData + length);
                    xQueueSend(USBReceiveQueue, &receivedMsg, portMAX_DELAY);
                }
                else {
                    // yielding task because nothing in a buffer


@@ 130,14 136,12 @@ namespace bsp
    std::size_t usbCDCSendRaw(const char *dataPtr, std::size_t dataLen)
    {
        const auto t = write(fd, dataPtr, dataLen);
        if (t >= 0) {
            LOG_DEBUG("[ServiceDesktop:BSP_Driver] Sent: %d", static_cast<int>(t));
            return 0;
        }
        else {
        if (t < 0) {
            LOG_ERROR("[ServiceDesktop:BSP_Driver] Writing to PTY failed with code: %d", errno);
            return -1;
        }
        LOG_DEBUG("[ServiceDesktop:BSP_Driver] Sent: %dB", static_cast<int>(t));
        return 0;
    }

    void writePtsToFile(const char *ptsname)


@@ 179,8 183,8 @@ namespace bsp
            return -1;
        }

        fdNofity = inotify_init1(O_NONBLOCK);
        inotify_add_watch(fdNofity, pts_name, IN_OPEN | IN_CLOSE_WRITE);
        fdNotify = inotify_init1(O_NONBLOCK);
        inotify_add_watch(fdNotify, pts_name, IN_OPEN | IN_CLOSE_WRITE);

        writePtsToFile(pts_name);
        LOG_INFO("bsp::usbInit linux ptsname: %s", pts_name);


@@ 192,7 196,7 @@ namespace bsp
        tcgetattr(fd, &oldtio);

        newtio             = oldtio;
        newtio.c_cflag     = SERIAL_BAUDRATE | CS8 | CLOCAL | CREAD;
        newtio.c_cflag     = constants::serial::baudRate | CS8 | CLOCAL | CREAD;
        newtio.c_iflag     = 0;
        newtio.c_oflag     = 0;
        newtio.c_lflag     = 0;


@@ 200,8 204,8 @@ namespace bsp
        newtio.c_cc[VTIME] = 0;
        tcflush(fd, TCIFLUSH);

        cfsetispeed(&newtio, SERIAL_BAUDRATE);
        cfsetospeed(&newtio, SERIAL_BAUDRATE);
        cfsetispeed(&newtio, constants::serial::baudRate);
        cfsetospeed(&newtio, constants::serial::baudRate);
        tcsetattr(fd, TCSANOW, &newtio);

        USBReceiveQueue = initParams.queueHandle;


@@ 209,7 213,7 @@ namespace bsp

        const auto task_error = xTaskCreate(&bsp::usbDeviceTask,
                                            "USBLinuxReceive",
                                            SERIAL_BUFFER_LEN * 8,
                                            constants::serial::bufferLength * 8,
                                            nullptr,
                                            tskIDLE_PRIORITY,
                                            &taskHandleReceive);

M module-bsp/bsp/usb/usb.hpp => module-bsp/bsp/usb/usb.hpp +7 -4
@@ 17,11 17,14 @@ extern "C"
#include <string.h>
#include <unistd.h>

inline constexpr auto SERIAL_BUFFER_LEN = 512;
inline constexpr auto SERIAL_BAUDRATE   = 115200;

namespace bsp
{
    namespace constants::serial
    {
        inline constexpr auto bufferLength = 512;
        inline constexpr auto baudRate = 115200;
    }

    enum class USBDeviceStatus : std::uint32_t
    {
        Disconnected,


@@ 42,7 45,7 @@ namespace bsp
    };

    int usbInit(const usbInitParams &initParams);
    int usbCDCReceive(void *ptr);
    ssize_t usbCDCReceive(void *ptr);
    std::size_t usbCDCSend(std::string *sendMsg);
    std::size_t usbCDCSendRaw(const char *dataPtr, std::size_t dataLen);
    void usbDeinit();

M pure_changelog.md => pure_changelog.md +1 -0
@@ 21,6 21,7 @@
* Fixed handsfree device still ringing after caller has hung up
* Fixed missing contact entries when scrolling through the contact list
* Fixed misunderstanding holes in sms conversations
* Fixed occasional crash when unplugging Pure from PC when connected with Mudita Center

## [1.7.2 2023-07-28]


M third-party/usb_stack => third-party/usb_stack +1 -1
@@ 1,1 1,1 @@
Subproject commit dcdbdddc3043e6317f8de8882975c733d0f98df2
Subproject commit 2f3587173896b16cfa62895fe9b690e3ea5cc7ef