Skip to content

Cellular: UBLOX socket write data error #12461

Closed
@pilotak

Description

@pilotak

Description of defect

When trying to write to a TCP socket, AT command will trigger binary syntax mode meaning it sends socker_id + number of bytes and than <CR> which is fine.
But then the lib should wait until character @ is received. And this is where the problem is - current implementation doesn't wait and sends it straight after AT command resulting in -3012 error because library is waiting for a response from mdm, but mdm is waiting for that binary data.

[00081375ms][INFO][CELL]: AT TX ( 9): AT+USOWR=
[00081381ms][INFO][CELL]: AT TX ( 1): 0
[00081385ms][INFO][CELL]: AT TX ( 1): ,
[00081390ms][INFO][CELL]: AT TX ( 1): 4
[00081395ms][INFO][CELL]: AT TX ( 1): <cr>
[00081400ms][INFO][CELL]: AT TX ( 5): TEST<00>
[00081406ms][INFO][CELL]: AT RX (13): AT+USOWR=0,4<cr>
[00081424ms][INFO][CELL]: AT RX ( 3): <cr><ln>@
[00141376ms][DBG ][CELL]: AT error -3012
[00141381ms][ERR ][CELL]: Socket 0 sendto 52.215.34.155 error -3012

Target(s) affected by this defect ?

SARA-G350

Toolchain(s) (name and version) displaying this defect ?

GCC-ARM 8.3.1

What version of Mbed-os are you using (tag or sha) ?

3d038e5

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

mbed-cli 1.10.1

How is this defect reproduced ?

#include "mbed.h"
#include "UBLOX_AT.h"
#include "CellularContext.h"

#if MBED_CONF_MBED_TRACE_ENABLE
    #include "CellularLog.h"
#endif

EventQueue eQueue(32 * EVENTS_EVENT_SIZE);
CellularContext *mdm;
CellularDevice *mdm_device;

#define MDM_HW_FLOW

class myUblox : public UBLOX_AT {
  public:
    explicit myUblox(FileHandle *fh);

    virtual nsapi_error_t hard_power_on();
    virtual nsapi_error_t hard_power_off();
    virtual nsapi_error_t soft_power_on();
    virtual nsapi_error_t soft_power_off();

  private:
    DigitalOut pwrOn;
    DigitalOut rst;
};

myUblox::myUblox(FileHandle *fh) :
    UBLOX_AT(fh),
    pwrOn(MDM_PWRON_pin, 0),
    rst(MDM_RST_pin, 1) {
}

nsapi_error_t myUblox::hard_power_on() {
    rst.write(0);
    ThisThread::sleep_for(1000);
    return NSAPI_ERROR_OK;
}

nsapi_error_t myUblox::hard_power_off() {
    rst.write(1);

    return NSAPI_ERROR_OK;
}

nsapi_error_t myUblox::soft_power_on() {
    pwrOn.write(1);
    ThisThread::sleep_for(150);
    pwrOn.write(0);
    ThisThread::sleep_for(100);

    return NSAPI_ERROR_OK;
}

nsapi_error_t myUblox::soft_power_off() {
    pwrOn.write(1);
    ThisThread::sleep_for(1000);
    pwrOn.write(0);

    return NSAPI_ERROR_OK;
}

CellularDevice *CellularDevice::get_target_default_instance() {
    static BufferedSerial serial(MDM_TX_pin, MDM_RX_pin, 115200);

#if defined(MDM_HW_FLOW)
    serial.set_flow_control(SerialBase::RTSCTS, MDM_RTS_pin, MDM_CTS_pin);
#else
    static DigitalOut rts(MDM_RTS_pin, 0);
#endif

    static myUblox device(&serial);
    return &device;
}

bool serverConnect() {
    debug("Server connect\n");

    nsapi_error_t ret = NSAPI_ERROR_PARAMETER;
    TCPSocket socket;
    const char *echo_string = "TEST";
    char recv_buf[4];

    SocketAddress server;
    ret = mdm->gethostbyname("echo.mbedcloudtesting.com", &server);

    if (ret == NSAPI_ERROR_OK) {
        server.set_port(7);
        ret = socket.open(mdm);

        if (ret == NSAPI_ERROR_OK) {
            debug("open OK\n");

            ret = socket.connect(server);

            if (ret == NSAPI_ERROR_OK || ret == NSAPI_ERROR_IS_CONNECTED) {
                debug("connected\n");
                ret = socket.send((void*) echo_string, strlen(echo_string));

                if (ret >= NSAPI_ERROR_OK) {
                    debug("TCP: Sent %i Bytes\n", ret);
                    nsapi_size_or_error_t n = socket.recv((void*) recv_buf, sizeof(recv_buf));

                    socket.close();

                    if (n > 0) {
                        debug("Received from echo server %i bytes\n", n);
                        return true;

                    } else {
                        debug("Socket recv FAILED: %i\n", n);
                    }

                } else {
                    debug("Socket send FAILED: %i\n", ret);
                }

            } else {
                debug("connect FAILED: %i\n", ret);
            }

        } else {
            debug("open FAILED\n");
        }

    } else {
        printf("Couldn't resolve remote host, code: %d\n", ret);
    }

    return false;
}

void mdmConnect() {
    debug("MDM connect\n");
    nsapi_error_t ret = mdm->connect();

    if (ret == NSAPI_ERROR_OK) {
        debug("Network connected\n");
        serverConnect();
        return;
    }

    debug("Connecting failed\n");
}

bool mdmSetup() {
    debug("Device setup\n");
    mdm = CellularContext::get_default_instance();

    if (mdm != NULL) {
        mdm_device = mdm->get_device();

        if (mdm_device != NULL) {
            mdm_device->hard_power_on();

            uint16_t timeout[8] = {1, 2, 4, 8, 16, 32, 64, 128};
            mdm_device->set_retry_timeout_array(timeout, 8);

            mdm->set_credentials("internet");

            // mdm->attach(mdmCb);
            mdm->set_blocking(true);

            mdmConnect();

            return true;

        } else {
            debug("No interface\n");
        }

    } else {
        debug("No device\n");
    }

    return false;
}


#if MBED_CONF_MBED_TRACE_ENABLE
static Mutex trace_mutex;
static char time_st[50];

static char* trace_time(size_t ss) {
    snprintf(time_st, 49, "[%08llums]", Kernel::get_ms_count());
    return time_st;
}

static void trace_wait() {
    trace_mutex.lock();
}

static void trace_release() {
    trace_mutex.unlock();
}

void trace_init() {
    mbed_trace_init();
    mbed_trace_prefix_function_set(&trace_time);

    mbed_trace_mutex_wait_function_set(trace_wait);
    mbed_trace_mutex_release_function_set(trace_release);

    mbed_cellular_trace::mutex_wait_function_set(trace_wait);
    mbed_cellular_trace::mutex_release_function_set(trace_release);
}
#endif

int main() {
#if MBED_CONF_MBED_TRACE_ENABLE
    trace_init();
#endif

    Thread eQueueThread;

    if (eQueueThread.start(callback(&eQueue, &EventQueue::dispatch_forever)) != osOK) {
        debug("eQueueThread error\n");
    }

    mdmSetup();
    mdm->disconnect();

    while (1) {
        ThisThread::sleep_for(osWaitForever);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions