This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

bsdlib AT socket API

Hi,

I really would like to be able interface with the modem at the lowest possible level. I got the bsdlib working.

I use the following procedure to send AT commands and receive responses:

init:

static void init(N91LTE_Context* pContext)
{
    NVIC_SetPriority(BSD_APPLICATION_IRQ, BSD_APPLICATION_IRQ_PRIORITY);
    NVIC_EnableIRQ(BSD_APPLICATION_IRQ);
    
    NVIC_SetPriority(BSD_NETWORK_IRQ, BSD_NETWORK_IRQ_PRIORITY);
    NVIC_EnableIRQ(BSD_NETWORK_IRQ);

    bsd_init();

    pContext->socket_fd = nrf_socket(NRF_AF_LTE, 0, NRF_PROTO_AT);
    ASSERT(pContext->socket_fd != -1,"AT socket error");
}

send:

sizeSend = nrf_send(pContext->socket_fd, pData, size, 0);

receive:

void bsd_os_errno_set(int err_code)
{
    /* Variables */
    N91LTE_Context* pContext = NULL;
    
    /* retrieve context */
    pContext = sContext;

    /* save last known error code */
    pContext->errorCode = err_code;
}

void BSD_APPLICATION_IRQ_HANDLER() //EGU1_IRQHandler
{
    /* Variables */
    N91LTE_Context*                 pContext                        = NULL;
    
    /* retrieve context */
    pContext = sContext;

    /* bsdlib requires this function to be called on application interrupts */
    bsd_os_application_irq_handler();

    if (pContext->socket_fd == 0)
    {
        return;
    }
    
    bsdPoll(sContext);
}

static void bsdPoll(SE_Context context)
{
    /* Variables */
    N91LTE_Context* pContext = NULL;
    struct nrf_pollfd pollfd = {0};

    /* retrieve context */
    pContext = (N91LTE_Context*)context;

    /* init the poll structure */
    pollfd.handle = pContext->socket_fd;
    pollfd.requested = NRF_POLLIN /* | NRF_POLLOUT | NRF_POLLINVAL | NRF_POLLERR */;
    pollfd.returned = 0;

    /* poll */
    if (nrf_poll(&pollfd, 1, 1) != 1)
    {
        /* number must be one, or no event happened */
        return;
    }
    
    /* process the events */
    if (pollfd.returned & NRF_POLLERR)
    {
      //  SE_debugString("poll error\r\n");
    }
    if (pollfd.returned & NRF_POLLOUT)
    {
       // SE_debugString("poll out\r\n");
    }
    if (pollfd.returned & NRF_POLLINVAL)
    {
      //  SE_debugString("socket not open\r\n");
    }
    if (pollfd.returned & NRF_POLLIN)
    {
        /* receive event happened */
       // SE_debugString("poll in\r\n");
        
        /* schedule the receive handler */
        runTaskNow(receiveData,sContext);
    }
}

static void receiveData(SE_Context context)
{
    /* Variables */
    N91LTE_Context* pContext = NULL;
    int32_t readSize = 0;
    bool bPostAgain = false;

    /* retrieve context */
    pContext = (N91LTE_Context*)context;
    
    /* do we got room to read more? */
    if( pContext->wrIndex < BUFFER_SIZE ) { // BUFFER_SIZE = 10
        /* read as much as we can, until the buffer full */
        readSize = nrf_recv(pContext->socket_fd, &pContext->pRxBuffer[pContext->wrIndex], BUFFER_SIZE - pContext->wrIndex, NRF_MSG_DONTWAIT);
        if( (readSize == -1) && (pContext->errorCode == NRF_EAGAIN) ) {
            /* no more bytes */
            readSize = 0;
        }

        /* did we get any bytes? */
        if (readSize > 0) {
            /* we got bytes, update the pointer */
            pContext->wrIndex += readSize;

            /* post again to handle any data still available in receive buffer. */
            bPostAgain = true;
        } else {
            /* receive buffer is empty, wait for a new modem event */
        }
    }

    /* do we still have some data in the buffer to forward to application? */
    if (pContext->wrIndex  > 0) {
        for (uint16_t i = 0; i < pContext->wrIndex; i++) {
            debugByte(pContext->pRxBuffer[i]);
        }

        if (dataForward(context, pContext->pRxBuffer, pContext->wrIndex) ) {
            /* data was accepted */
            pContext->wrIndex = 0;
        } else {
            /* data not accepted, try again later */
            bPostAgain = true;
        }
    }

    if (bPostAgain) {
        runTaskNow(receiveData,sContext);
    }
}

when I use a buffer of 1000 bytes and send the 'AT+CGMR' command, I get 'mfw-m1_nrf9160_0.6.8-30.alpha<CR><LF>OK<CR><LF><NUL>' as a response. Great!

But when I use a buffer of 10. I expect to able to use multiple nrf_recv calls to get the rest of the data. But the rest is not there anymore.

I only get 'mfw-m1_nrf', and the rest is not returned when i call 'nrf_recv' again.

Is this expected behaviour? Do I need to allocate a massive buffer to be sure I always get all of my data?

Parents Reply Children
No Data
Related