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?