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?