~aleteoryx/muditaos

87b5938e3716c101ec45e926539e4b2f7ae2b33b — Kuba 5 years ago 9759443
[EGD-5594] Fix sending multiple cmux frames

Sending multiple cmux frames was broken. Sending at command
longer than 127 bytes caused the modem to freeze.
M module-cellular/Modem/TS0710/TS0710_DATA.cpp => module-cellular/Modem/TS0710/TS0710_DATA.cpp +6 -4
@@ 53,11 53,12 @@ void TS0710_DATA::request(DLCI_t DLCI, DLC_ESTABL_SystemParameters_t sysParams, 
                31 30 2E 30 2E 38 5F 42 55 49
                4C 44 30 33 0D 0A 0D 0A 47 F9   UIH Frame
*/
    auto constexpr maximumFrameLength = 127;
    TS0710_Frame::frame_t frame;
    frame.Address = static_cast<uint8_t>(DLCI << 2) /*| (1 << 1)*/; // set C/R = 1 - command
    frame.Control = static_cast<uint8_t>(TypeOfFrame_e::UIH);

    if (User_data.size() < static_cast<size_t>(sysParams.MaxFrameSize)) {
    if (User_data.size() <= static_cast<size_t>(maximumFrameLength)) {
        frame.data = User_data;
        TS0710_Frame frame_c(frame);
        // UartSend(frame_c.getSerData().data(), frame_c.getSerData().size());


@@ 66,18 67,19 @@ void TS0710_DATA::request(DLCI_t DLCI, DLC_ESTABL_SystemParameters_t sysParams, 
    else { // if data size > max frame size
        int dataLeft                     = User_data.size();
        std::vector<uint8_t>::iterator i = User_data.begin();
        uint32_t parts                   = User_data.size() / sysParams.MaxFrameSize + 1; // add reminder
        uint32_t parts                   = User_data.size() / maximumFrameLength + 1; // add reminder
        LOG_DEBUG("SENDING %" PRIu32 " parts", parts);
        while (parts--) {
            std::vector<uint8_t>::iterator last =
                i + (dataLeft < sysParams.MaxFrameSize ? dataLeft : sysParams.MaxFrameSize); // distinguish reminder
                i + (dataLeft <= maximumFrameLength ? dataLeft : maximumFrameLength); // distinguish reminder
            frame.data = std::vector<uint8_t>(i, last);
            i          = last;
            TS0710_Frame frame_c(frame);
            // UartSend(frame_c.getSerData().data(), frame_c.getSerData().size());
            // while(!pv_cellular->GetSendingAllowed());
            pv_cellular->Write(static_cast<void *>(frame_c.getSerData().data()), frame_c.getSerData().size());
            // vTaskDelay(1);
            dataLeft -= (dataLeft < sysParams.MaxFrameSize ? dataLeft : sysParams.MaxFrameSize);
            dataLeft -= (dataLeft <= maximumFrameLength ? dataLeft : maximumFrameLength);
        }
    }
}

M module-cellular/Modem/TS0710/TS0710_Frame.h => module-cellular/Modem/TS0710/TS0710_Frame.h +0 -1
@@ 78,7 78,6 @@ class TS0710_Frame
            FCS = 0xFF - FCS;
            ret.push_back(FCS);
            ret.push_back(TS0710_FLAG);

            return ret;
        }


M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +26 -26
@@ 1391,7 1391,7 @@ bool ServiceCellular::sendSMS(SMSRecord record)
    uint32_t textLen = record.body.length();

    auto commandTimeout                 = at::factory(at::AT::CMGS).getTimeout();
    constexpr uint32_t singleMessageLen = 30;
    constexpr uint32_t singleMessageLen = 67;
    bool result                         = false;
    auto channel                        = cmux->get(TS0710::Channel::Commands);
    auto receiver                       = record.number.getEntered();


@@ 1412,8 1412,9 @@ bool ServiceCellular::sendSMS(SMSRecord record)
                }
                else {
                    result = false;
                    LOG_ERROR("Message to: %s send failure", receiver.c_str());
                }
                if (!result)
                    LOG_ERROR("Message to: %s send failure", receiver.c_str());
            }
        }
        // split text, and send concatenated messages


@@ 1426,41 1427,40 @@ bool ServiceCellular::sendSMS(SMSRecord record)

            if (messagePartsCount > maxConcatenatedCount) {
                LOG_ERROR("Message to long");
                return false;
                result = false;
            }
            else {
                auto channel = cmux->get(TS0710::Channel::Commands);

            auto channel = cmux->get(TS0710::Channel::Commands);

            for (uint32_t i = 0; i < messagePartsCount; i++) {
                for (uint32_t i = 0; i < messagePartsCount; i++) {

                uint32_t partLength = singleMessageLen;
                if (i * singleMessageLen + singleMessageLen > record.body.length()) {
                    partLength = record.body.length() - i * singleMessageLen;
                }
                UTF8 messagePart = record.body.substr(i * singleMessageLen, partLength);
                    uint32_t partLength = singleMessageLen;
                    if (i * singleMessageLen + singleMessageLen > record.body.length()) {
                        partLength = record.body.length() - i * singleMessageLen;
                    }
                    UTF8 messagePart = record.body.substr(i * singleMessageLen, partLength);

                std::string command(at::factory(at::AT::QCMGS) + UCS2(UTF8(receiver)).str() + "\",120," +
                                    std::to_string(i + 1) + "," + std::to_string(messagePartsCount));
                    std::string command(at::factory(at::AT::QCMGS) + UCS2(UTF8(receiver)).str() + "\",120," +
                                        std::to_string(i + 1) + "," + std::to_string(messagePartsCount));

                if (cmux->CheckATCommandPrompt(
                        channel->SendCommandPrompt(command.c_str(), 1, commandTimeout.count()))) {
                    // prompt sign received, send data ended by "Ctrl+Z"
                    if (channel->cmd(UCS2(messagePart).str() + "\032", commandTimeout, 2)) {
                        result = true;
                    if (cmux->CheckATCommandPrompt(
                            channel->SendCommandPrompt(command.c_str(), 1, commandTimeout.count()))) {
                        // prompt sign received, send data ended by "Ctrl+Z"
                        if (channel->cmd(UCS2(messagePart).str() + "\032", commandTimeout, 2)) {
                            result = true;
                        }
                        else {
                            result = false;
                            LOG_ERROR("Message send failure");
                            break;
                        }
                    }
                    else {
                        result = false;
                        if (!result)
                            LOG_ERROR("Message send failure");
                        LOG_ERROR("Message send failure");
                        break;
                    }
                }
                else {
                    result = false;
                    if (!result)
                        LOG_ERROR("Message send failure");
                    break;
                }
            }
        }
    }