vshymanskyy / TinyGSM

A small Arduino library for GSM modules, that just works
GNU Lesser General Public License v3.0
1.91k stars 709 forks source link

Problem sending data with size 4kb #660

Open RodrigoPGoncalves opened 2 years ago

RodrigoPGoncalves commented 2 years ago

I'm using an esp32 together with a SIM800L. Its possible send more than 1460 bytes ? Because i have problemens to send my archive and i need a solution for this.

Gelemikke commented 1 year ago

This is probably a too late answer to be useful for you but it might be useful for someone else. I've been using a SIM7600 which has a limit of 1500 bytes that can be sent at once but the principle is the same. I simply fragment the message to be sent and send at most 1500 bytes at a time. On the receiver end this is received as one TCP stream for the application to read anyways. I implemented this as a stand-alone function but I think it really should really be implemented in the modemSend function of whichever modem client that is used (in my case TinyGsmSim7600) or possibly in the write function of GsmClient. Especially since it does not produce any errors (except in the AT commands) at the moment and and simply does not send anything.

/**
 * @brief Workaround to fragment and transmit messages longer than MAX_CHAR_PER_MESSAGE =1500
 * 
 * Iterates though the c_string and calls TinyGsmTCP::GsmClient::write(const uint8_t *buffer, size_t size) 
 * directly instead of the original call stack:
 * postData(TinyGsmClient &client, const String &message, String& replyBuffer)
 * -> Print::print(const String &) -> Print::write(const char *buffer, size_t size)
 * -> Print::write(const char *buffer, size_t size) -> TinyGsmTCP::GsmClient::write(const uint8_t *buffer, size_t size)
 * -> TinyGsmSim7600::modemSend(const void* buff, size_t len, uint8_t mux) -> HardwareSerial::write(const uint8_t *buffer, size_t size)
 * -> uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) -> uart_write_bytes(uart_port_t uart_num, const void* src, size_t size)
 *
 * @param client The client to transmit from
 * @param str The message the transmit
 * @return The number of transmitted char
 */
size_t print(TinyGsmClient &client, const String &str)
{
    const char* buff = str.c_str(); 
    size_t len = str.length();

    //buff is a pointer to the c string in the references string which has been cast from a const char* to a const uint8_t* (Print::write)
    size_t n_transmitted_bytes = 0;
    while (n_transmitted_bytes < len){
        size_t n_bytes_to_transmit;
        if (n_transmitted_bytes + MAX_CHAR_PER_MESSAGE <= len){
            n_bytes_to_transmit = MAX_CHAR_PER_MESSAGE;      // fill the whole allowed modem buffer
        }
        else{
            n_bytes_to_transmit = len - n_transmitted_bytes; // only transmit the remainder of the bytes
        }
        //n_transmitted_bytes += n_bytes_to_transmit;
        n_transmitted_bytes += client.write((const uint8_t *)buff, n_bytes_to_transmit);

        buff += n_bytes_to_transmit; // increment pointer past the transmitted part of the buffer
    }
    return n_transmitted_bytes;
}