Firmware/src/at_commands.c
int decode_input(int32_t timeout, void *ctx, char_callback_t char_cb, eol_callback_t eol_cb)
{
    struct buf rb;
    b_init(&rb);
    uint8_t b, prev = ' ';
    bool is_urc = false;

    while (modem_read(&b, timeout))
    {
        if (b == '+' && rb.size == 0)
        {
            is_urc = true;
        }
        b_add(&rb, b);
        if (char_cb)
        {
            char_cb(ctx, &rb, b, is_urc, isspace(b));
        }
        if (rb.size >= 4)
        {
            if (b_is(&rb, "OK\r\n", 4))
            {
                LOG_DBG("Got OK");
                return AT_OK;
            }
            if (b_is(&rb, "ERROR\r\n", 7))
            {
                LOG_DBG("Got ERROR");
                return AT_ERROR;
            }
        }
        if (prev == '\r' && b == '\n')
        {
            if (eol_cb)
            {
                eol_cb(ctx, &rb, is_urc);
            }
            b_reset(&rb);
            is_urc = false;
            // Yield to the rest of the world
            k_yield();
        }
        // Additional URCs to support:
        //  - CEREG
        //  - NPSMR
        //  - CSCON
        //  - UFOTAS

        prev = b;
    }
    return AT_TIMEOUT;
}
// Each decoder is largely the same so we use a strategy pattern for each. The char
// callback is called for each character input and the EOL callback is called when a
// new line is found. The buffer will contain the *first* 9 characters of the line
// so it might be truncated.
Each decoder is largely the same so we use a strategy pattern for each. The char
callback is called for each character input and the EOL callback is called when a
new line is found. The buffer will contain the *first* 9 characters of the line
so it might be truncated.
Each decoder is largely the same so we use a strategy pattern for each . The char callback is called for each character input and the EOL callback is called when a new line is found . The buffer will contain the * first * 9 characters of the line so it might be truncated .
int decode_input(int32_t timeout, void *ctx, char_callback_t char_cb, eol_callback_t eol_cb)
{
    struct buf rb;
    b_init(&rb);
    uint8_t b, prev = ' ';
    bool is_urc = false;
    while (modem_read(&b, timeout))
    {
        if (b == '+' && rb.size == 0)
        {
            is_urc = true;
        }
        b_add(&rb, b);
        if (char_cb)
        {
            char_cb(ctx, &rb, b, is_urc, isspace(b));
        }
        if (rb.size >= 4)
        {
            if (b_is(&rb, "OK\r\n", 4))
            {
                LOG_DBG("Got OK");
                return AT_OK;
            }
            if (b_is(&rb, "ERROR\r\n", 7))
            {
                LOG_DBG("Got ERROR");
                return AT_ERROR;
            }
        }
        if (prev == '\r' && b == '\n')
        {
            if (eol_cb)
            {
                eol_cb(ctx, &rb, is_urc);
            }
            b_reset(&rb);
            is_urc = false;
            k_yield();
        }
        prev = b;
    }
    return AT_TIMEOUT;
}
int decode_input ( int32_t timeout , void * ctx , char_callback_t char_cb , eol_callback_t eol_cb ) { struct buf rb ; b_init ( & rb ) ; uint8_t b , prev = ' ' ; bool is_urc = false ; while ( modem_read ( & b , timeout ) ) { if ( b == ' ' && rb . size == 0 ) { is_urc = true ; } b_add ( & rb , b ) ; if ( char_cb ) { char_cb ( ctx , & rb , b , is_urc , isspace ( b ) ) ; } if ( rb . size >= 4 ) { if ( b_is ( & rb , " \r \n " , 4 ) ) { LOG_DBG ( " " ) ; return AT_OK ; } if ( b_is ( & rb , " \r \n " , 7 ) ) { LOG_DBG ( " " ) ; return AT_ERROR ; } } if ( prev == ' \r ' && b == ' \n ' ) { if ( eol_cb ) { eol_cb ( ctx , & rb , is_urc ) ; } b_reset ( & rb ) ; is_urc = false ; k_yield ( ) ; } prev = b ; } return AT_TIMEOUT ; }
Each decoder is largely the same so we use a strategy pattern for each.
Each decoder is largely the same so we use a strategy pattern for each .
// Yield to the rest of the world // Additional URCs to support: //  - CEREG //  - NPSMR //  - CSCON //  - UFOTAS