SIM800 TCP/IP connection fails when SERVER send back a JSON - SERVER in Qt C++

Hi all,
I am new in this blog so forgive me if I will do some mistakes.

I have to setup a remote control of a MCU.

I am using a GPRS modem based on the SIM808 module.

I setup a TCPIP connection with a remote SERVER at its IP address and port. Everything is based on the official SIM900_TCPIP_Application Note_V1.02 and I compared the implementation with TCP Connection over GPRS using SIM900 and AT Commands | Vishnu's Blogs and TCP Client using SIM900A GPRS and PIC18F4550 | PIC Controllers and https://www.cooking-hacks.com/documentation/tutorials/gprs-gsm-quadband-module-arduino-raspberry-pi-tutorial-sim-900#introduction

The connection with the SERVER takes place regularly, the JSON string from the client to the server is sent properly and the GUI APP at the server side receives the JSON and update the GUI interface properly, as expected.
Therefore the remote monitoring works perfectly, continuoulsy, and forever (untill the SERVER is not stopped).

The GUI APP is written is Qt C++.

When the Qt APP (aka server), tries to send back a JSON:

  1. ATMEGA receives a string into the UART buffer;
  2. if ATMEGA parses the JSON, it is like expected but the GPRS modem never releases the SEND OK.
  3. So ATMEGA cannot send any other JSON and update the remote monitor.
  4. The only way out is the reset of the modem and cancel the TCPIP session.

After the reset it is again possible to send all the JSON wanted, but at the first tentative to send a JSON from the Qt APP to the ATMEGA1284P the modem becomes blocked again and does not accept any other AT command.
ATMEGA has to reset it.
It doesn't matter the length of the JSON has to leave the SERVER, short or long always the same matter, the JSON arrives but the modem never releases the SEND OK.

About the SERVER this is how we are reading/writing data from application.

#include "communicationhandler.h"
#include <QTcpSocket>
#include <QJsonDocument>
#include <QJsonObject>
#include <QtDebug>

CommunicationHandler::CommunicationHandler(QObject *parent)
    : QObject(parent)
{
    init();
}

void CommunicationHandler::init()
{
    tcpServer = new QTcpServer(this);
}

bool CommunicationHandler::startServer(int port)
{
    if (tcpServer->isListening())
        return true;

    if (port <= 0)
    {
        return false;
    }

    if (tcpServer->listen(QHostAddress::AnyIPv4, port))
    {
        connect(tcpServer, &QTcpServer::newConnection,
                this, &CommunicationHandler::onNewConnection);

        return true;
    }

    return false;
}

bool  CommunicationHandler::stopServer()
{
    if (!tcpServer->isListening())
        return true;

    tcpServer->close();
    return true;
}

bool CommunicationHandler::isServerListening()
{
    return  tcpServer->isListening();
}

void CommunicationHandler::onNewConnection()
{
    connectionSocket = tcpServer->nextPendingConnection();
    connect(connectionSocket, &QTcpSocket::readyRead, this, &CommunicationHandler::onData);
}

void CommunicationHandler::onData()
{
    QTcpSocket* socket = (QTcpSocket*)sender();
    if (socket)
    {
        QByteArray data = socket->readAll();

        jsonData += data;

        qDebug() << jsonData;
        QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);
        if (!jsonDoc.isEmpty())
        {
            emit jsonReceived(jsonDoc);
            dataToBeSent = jsonData;
            jsonData.clear();
        }
    }
}

void CommunicationHandler::sendParameterData(const QByteArray& data)
{
    QJsonDocument jsonDoc = QJsonDocument::fromJson(data);
    if (!jsonDoc.isEmpty())
    {
        QJsonDocument fullJsonDoc = QJsonDocument::fromJson(dataToBeSent);
        if (!fullJsonDoc.isEmpty())
        {
            //"{\"buzzer\":\"y\",\"deltaRpm\":50,\"door\":11,\"function\":\"a\",\"ins\":{\"l1\":120,\"l2\":100,\"l3\":80,\"l4\":20},\"powerMode\":\"b\",\"pressure\":35,\"reactTime\":12,\"rel\":{\"l1\":220,\"l2\":180,\"l3\":45,\"l4\":0},\"rpm\":2800,\"service\":127,\"test\":\"y\"}"

            QVariantMap map = jsonDoc.toVariant().toMap();

            QVariantMap fullMap = fullJsonDoc.toVariant().toMap();

            fullMap["buzzer"] = map.value("buzzer");
            fullMap["deltaRpm"] = map.value("deltaRpm");
            fullMap["door"] = map.value("door");
            fullMap["function"] = map.value("function");
            fullMap["ins"] = map.value("ins");
            fullMap["powerMode"] = map.value("powerMode");
            fullMap["pressure"] = map.value("pressure");
            fullMap["reactTime"] = map.value("reactTime");
            fullMap["rel"] = map.value("rel");
            fullMap["rpm"] = map.value("rpm");
            fullMap["service"] = map.value("service");
            fullMap["test"] = map.value("test");

            QJsonDocument doc  = QJsonDocument::fromVariant(fullMap);
            QByteArray jsonData = doc.toJson(QJsonDocument::Compact);

            sendData(jsonData);
        }
    }
}

void CommunicationHandler::sendData(const QByteArray& data)
{
    if (connectionSocket!=nullptr)
    {
        qDebug() << "Sending Data to Device: " << data;
        QByteArray dataToBeSent = data;
        dataToBeSent.append('\r');
        connectionSocket->write(dataToBeSent);
        connectionSocket->flush();
    }
}

Why the APP at the SERVER SIDE, when sends a JSON to the ATMEGA client blocks the GPRS modem? Is there any handshake to do at the Server side before to reply a JSON back to the ATMEGA?

How the TCPIP layer at the Server side informs that it is ready to accept a string to send to the client? At ATMEGA side after the AT+CIPSEND, the TCPIP layer releases a prompt > and only after this prompt it is possible to send the JSON. When the transmission is successfully completed (received by the SERVER) the TCPIP layer releases a SEND OK, really the OK to send a new JSON. Nothing similar at the SERVER side?

I have not find any useful explanation on how and when the SERVER can send a JSON back to the client. At the SERVER side, immediately after the JSON from the ATMEGA is received, and without any care about any prompts from the TCPIP layer, can I send a JSON back?

Is it better to insert a delay at the SERVER side?
I am going with 19200 baud rate. The JSON is 670chars, so the transmission takes 500msec minimum, say 1 sec ... better to insert a delay of 2 seconds at the SERVER side?

If at the ATMEGA side I am quite skilled, my ability with the Server code is limited
.... probably this is not the right forum!!?? forgive me. Any suggestion where I should find satisfaction at my troubles?).

Of course, I can post the C code about the ATMEGA but I think the trouble is at the SERVER side and not at the ATMEGA side.

Thank you for any help.

Best regards.
Mario