src/atchannel.c
/**
 * Reads a line from the AT channel, returns NULL on timeout.
 * Assumes it has exclusive read access to the FD
 *
 * This line is valid only until the next call to readline
 *
 * This function exists because as of writing, android libc does not
 * have buffered stdio.
 */
Reads a line from the AT channel, returns NULL on timeout.
Assumes it has exclusive read access to the FD

This line is valid only until the next call to readline

This function exists because as of writing, android libc does not
have buffered stdio.
Reads a line from the AT channel returns NULL on timeout . Assumes it has exclusive read access to the FD This line is valid only until the next call to readline This function exists because as of writing android libc does not have buffered stdio .
static const char *readline(ATChannel* atch)
{
    ssize_t count;
    char *p_read = NULL;
    char *p_eol = NULL;
    char *ret;
    if (*atch->impl->ATBufferCur == '\0') {
        atch->impl->ATBufferCur = atch->impl->ATBuffer;
        *atch->impl->ATBufferCur = '\0';
        p_read = atch->impl->ATBuffer;
    } else {   
        while (*atch->impl->ATBufferCur == '\r' || *atch->impl->ATBufferCur == '\n')
            atch->impl->ATBufferCur++;
        p_eol = findNextEOL(atch->impl->ATBufferCur);
        if (p_eol == NULL) {
            size_t len;
            len = strlen(atch->impl->ATBufferCur);
            memmove(atch->impl->ATBuffer, atch->impl->ATBufferCur, len + 1);
            p_read = atch->impl->ATBuffer + len;
            atch->impl->ATBufferCur = atch->impl->ATBuffer;
        }
    }
    while (p_eol == NULL) {
        if (0 == MAX_AT_RESPONSE - (size_t)(p_read - atch->impl->ATBuffer)) {
            RLOGE(atch, "ERROR: Input line exceeded buffer.");
            atch->impl->ATBufferCur = atch->impl->ATBuffer;
            *atch->impl->ATBufferCur = '\0';
            p_read = atch->impl->ATBuffer;
        }
        do {
            count = read(atch->fd, p_read,
                            MAX_AT_RESPONSE - (size_t)(p_read - atch->impl->ATBuffer));
        } while (count < 0 && errno == EINTR);
        if (count > 0) {
            AT_DUMP( atch, "<< ", p_read, count );
            p_read[count] = '\0';
            while (*atch->impl->ATBufferCur == '\r' || *atch->impl->ATBufferCur == '\n')
                atch->impl->ATBufferCur++;
            p_eol = findNextEOL(atch->impl->ATBufferCur);
            p_read += count;
        } else if (count <= 0) {
            if(count == 0) {
                RLOGD(atch, "atchannel: EOF reached.");
            } else {
                RLOGE(atch, "atchannel: read error %s.", strerror(errno));
            }
            return NULL;
        }
    }
    ret = atch->impl->ATBufferCur;
    *p_eol = '\0';
    atch->impl->ATBufferCur = p_eol + 1; 
    RLOGD(atch, "AT< %s", ret);
    return ret;
}
static const char * readline ( ATChannel * atch ) { ssize_t count ; char * p_read = NULL ; char * p_eol = NULL ; char * ret ; if ( * atch -> impl -> ATBufferCur == ' \0 ' ) { atch -> impl -> ATBufferCur = atch -> impl -> ATBuffer ; * atch -> impl -> ATBufferCur = ' \0 ' ; p_read = atch -> impl -> ATBuffer ; } else { while ( * atch -> impl -> ATBufferCur == ' \r ' || * atch -> impl -> ATBufferCur == ' \n ' ) atch -> impl -> ATBufferCur ++ ; p_eol = findNextEOL ( atch -> impl -> ATBufferCur ) ; if ( p_eol == NULL ) { size_t len ; len = strlen ( atch -> impl -> ATBufferCur ) ; memmove ( atch -> impl -> ATBuffer , atch -> impl -> ATBufferCur , len + 1 ) ; p_read = atch -> impl -> ATBuffer + len ; atch -> impl -> ATBufferCur = atch -> impl -> ATBuffer ; } } while ( p_eol == NULL ) { if ( 0 == MAX_AT_RESPONSE - ( size_t ) ( p_read - atch -> impl -> ATBuffer ) ) { RLOGE ( atch , " " ) ; atch -> impl -> ATBufferCur = atch -> impl -> ATBuffer ; * atch -> impl -> ATBufferCur = ' \0 ' ; p_read = atch -> impl -> ATBuffer ; } do { count = read ( atch -> fd , p_read , MAX_AT_RESPONSE - ( size_t ) ( p_read - atch -> impl -> ATBuffer ) ) ; } while ( count < 0 && errno == EINTR ) ; if ( count > 0 ) { AT_DUMP ( atch , " " , p_read , count ) ; p_read [ count ] = ' \0 ' ; while ( * atch -> impl -> ATBufferCur == ' \r ' || * atch -> impl -> ATBufferCur == ' \n ' ) atch -> impl -> ATBufferCur ++ ; p_eol = findNextEOL ( atch -> impl -> ATBufferCur ) ; p_read += count ; } else if ( count <= 0 ) { if ( count == 0 ) { RLOGD ( atch , " " ) ; } else { RLOGE ( atch , " " , strerror ( errno ) ) ; } return NULL ; } } ret = atch -> impl -> ATBufferCur ; * p_eol = ' \0 ' ; atch -> impl -> ATBufferCur = p_eol + 1 ; RLOGD ( atch , " " , ret ) ; return ret ; }
Reads a line from the AT channel, returns NULL on timeout.
Reads a line from the AT channel returns NULL on timeout .
/* this is a little odd. I use *ATBufferCur == 0 to
     * mean "buffer consumed completely". If it points to a character, than
     * the buffer continues until a \0
     */ /* empty buffer */ /* *ATBufferCur != '\0' */ /* there's data in the buffer from the last read */ // skip over leading newlines /* a partial line. move it up and prepare to read more */ /* Otherwise, (p_eol !- NULL) there is a complete line  */ /* that will be returned the while () loop below        */ /* ditch buffer and start over again */ // skip over leading newlines /* read error encountered or EOF reached */ /* a full line in the buffer. Place a \0 over the \r and return */ /* this will always be <= p_read,    */ /* and there will be a \0 at *p_read */