/* //device/system/reference-ril/atchannel.c
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#include "atchannel.h"
#include "at_tok.h"

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <ctype.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

#include "mbtk_log.h"
#include "mbtk_type.h"
#include "mbtk_utils.h"

#define MAX_AT_RESPONSE (8 * 1024)
#define HANDSHAKE_RETRY_COUNT 20
#define HANDSHAKE_TIMEOUT_MSEC 500
#define AT_BUFF_MAX 1024

static pthread_t s_tid_reader;
static int s_at_fd = -1;    /* fd of the AT channel */
static int s_uart_fd = -1;    /* fd of the UART channel */

static ATUnsolHandler s_unsolHandler;

/* for input buffering */

static char s_ATBuffer[MAX_AT_RESPONSE+1];
static char *s_ATBufferCur = s_ATBuffer;
static char s_UartBuffer[MAX_AT_RESPONSE+1];
static char *s_UartBufferCur = s_UartBuffer;

static mbtk_ril_at_state_enum at_state = RIL_AT_STATE_CLOSED;

#if AT_DEBUG
void  AT_DUMP(const char*  prefix, const char*  buff, int  len)
{
    if (len < 0)
        len = strlen(buff);
    LOGD("%.*s", len, buff);
}
#endif

/*
 * There is one reader thread |s_tid_reader| and potentially multiple writer
 * threads. |s_commandmutex| and |s_commandcond| are used to maintain the
 * condition that the writer thread will not read from |sp_response| until the
 * reader thread has signaled itself is finished, etc. |s_writeMutex| is used to
 * prevent multiple writer threads from calling at_send_command_full_nolock
 * function at the same time.
 */

// "Wait" when AT process...
static pthread_mutex_t s_commandmutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t s_commandcond = PTHREAD_COND_INITIALIZER;

static ATCommandType s_type;
static const char *s_responsePrefix = NULL;
static const char *s_smsPDU = NULL;
static ATResponse *sp_response = NULL;
static char s_curr_at[AT_BUFF_MAX];

static void (*s_onTimeout)(void) = NULL;
static void (*s_onReaderClosed)(void) = NULL;
static int s_readerClosed;

static void onReaderClosed();
static int writeCtrlZ (const char *s);
static int writeline (const char *s);

typedef struct
{
    char *at_command;
    long long timeout;  // ms
    bool timeout_close; // Close AT or not while AT response timeout.
} at_timeout_t;

static at_timeout_t at_timeout_list[] =
{
    {"AT+CRSM", 10000, false},
//    {"AT+COPS", 60000, false}
};

#define NS_PER_S 1000000000
static void setTimespecRelative(struct timespec *p_ts, long long msec)
{
    struct timeval tv;

    gettimeofday(&tv, (struct timezone *) NULL);

    p_ts->tv_sec = tv.tv_sec + (msec / 1000);
    p_ts->tv_nsec = (tv.tv_usec + (msec % 1000) * 1000L ) * 1000L;
    /* assuming tv.tv_usec < 10^6 */
    if (p_ts->tv_nsec >= NS_PER_S)
    {
        p_ts->tv_sec++;
        p_ts->tv_nsec -= NS_PER_S;
    }
}

static void sleepMsec(long long msec)
{
    struct timespec ts;
    int err;

    ts.tv_sec = (msec / 1000);
    ts.tv_nsec = (msec % 1000) * 1000 * 1000;

    do
    {
        err = nanosleep (&ts, &ts);
    }
    while (err < 0 && errno == EINTR);
}



/** add an intermediate response to sp_response*/
static void addIntermediate(const char *line)
{
    ATLine *p_new;

    p_new = (ATLine  *) malloc(sizeof(ATLine));

    p_new->line = strdup(line);

//    LOGD("line:%s", line);
//    LOGD("line-1:%s", p_new->line);

    /* note: this adds to the head of the list, so the list
       will be in reverse order of lines received. the order is flipped
       again before passing on to the command issuer */
    p_new->p_next = sp_response->p_intermediates;
    sp_response->p_intermediates = p_new;
}


/**
 * returns 1 if line is a final response indicating error
 * See 27.007 annex B
 * WARNING: NO CARRIER and others are sometimes unsolicited
 */
static const char * s_finalResponsesError[] =
{
    "ERROR",
    "+CMS ERROR:",
    "+CME ERROR:",
//    "NO CARRIER", /* sometimes! */ // Only for ATD ?
    "NO ANSWER",
    "NO DIALTONE",
};
static int isFinalResponseError(const char *line)
{
    size_t i;

    for (i = 0 ; i < ARRAY_SIZE(s_finalResponsesError) ; i++)
    {
        if (strStartsWith(line, s_finalResponsesError[i]))
        {
            return 1;
        }
    }

    if(!strncasecmp(s_curr_at, "ATD", 3) && strStartsWith(line, "NO CARRIER"))
    {
        return 1;
    }

    return 0;
}

/**
 * returns 1 if line is a final response indicating success
 * See 27.007 annex B
 * WARNING: NO CARRIER and others are sometimes unsolicited
 */
static const char * s_finalResponsesSuccess[] =
{
    "OK",
//    "CONNECT"       /* some stacks start up data on another channel */
};
static int isFinalResponseSuccess(const char *line)
{
    size_t i;

    for (i = 0 ; i < ARRAY_SIZE(s_finalResponsesSuccess) ; i++)
    {
        if (strStartsWith(line, s_finalResponsesSuccess[i]))
        {
            return 1;
        }
    }

    return 0;
}

/**
 * returns 1 if line is a final response, either  error or success
 * See 27.007 annex B
 * WARNING: NO CARRIER and others are sometimes unsolicited
 */
static int isFinalResponse(const char *line)
{
    return isFinalResponseSuccess(line) || isFinalResponseError(line);
}

/**
 * returns 1 if line is the first line in (what will be) a two-line
 * SMS unsolicited response
 */
static const char * s_smsUnsoliciteds[] =
{
    "+CMT:",
    "+CDS:",
    "+CBM:"
};
static int isSMSUnsolicited(const char *line)
{
    size_t i;

    for (i = 0 ; i < ARRAY_SIZE(s_smsUnsoliciteds) ; i++)
    {
        if (strStartsWith(line, s_smsUnsoliciteds[i]))
        {
            return 1;
        }
    }

    return 0;
}


/** assumes s_commandmutex is held */
static void handleFinalResponse(const char *line)
{
    sp_response->finalResponse = strdup(line);

    //LOGD("AT complete (pthread_cond_signal): %s",line);
    pthread_cond_signal(&s_commandcond);
}

static void handleUnsolicited(const char *line)
{
    if (s_unsolHandler != NULL)
    {
        s_unsolHandler(line, NULL);
    }
}

static void processLine(const char *line)
{
    pthread_mutex_lock(&s_commandmutex);
//    LOGD("LINE : %s", line);
    if (sp_response == NULL)
    {
        /* no command pending */
        handleUnsolicited(line);
    }
    else if (isFinalResponseSuccess(line))
    {
        sp_response->success = 1;
        handleFinalResponse(line);
    }
    else if (isFinalResponseError(line))
    {
        sp_response->success = 0;
        handleFinalResponse(line);
    }
    else if (s_smsPDU != NULL && 0 == strcmp(line, "> "))
    {
        // See eg. TS 27.005 4.3
        // Commands like AT+CMGS have a "> " prompt
        writeCtrlZ(s_smsPDU);
        s_smsPDU = NULL;
    }
    else switch (s_type)
        {
            case NO_RESULT:
                handleUnsolicited(line);
                break;
            case NUMERIC:
                if (sp_response->p_intermediates == NULL
                    && isdigit(line[0])
                   )
                {
                    addIntermediate(line);
                }
                else
                {
                    /* either we already have an intermediate response or
                       the line doesn't begin with a digit */
                    handleUnsolicited(line);
                }
                break;
            case SINGLELINE:
                if (sp_response->p_intermediates == NULL
                    && strStartsWith (line, s_responsePrefix)
                   )
                {
                    if(*line == '"')
                    {
                        char *line_temp = strdup(line);
						char *free_ptr = line_temp;
                        line_temp++;
                        if(strlen(line_temp) > 0)
                        {
                            char *ptr = line_temp + strlen(line_temp) - 1;
                            while(ptr >= line_temp && *ptr == '"')
                            {
                                *ptr = '\0';
                                ptr--;
                            }
                        }
                        addIntermediate(line_temp);
                        free(free_ptr);
                    }
                    else
                    {
                        addIntermediate(line);
                    }
                }
                else
                {
                    /* we already have an intermediate response */
                    handleUnsolicited(line);
                }
                break;
            case MULTILINE:
                if (strStartsWith (line, s_responsePrefix))
                {
                    addIntermediate(line);
                }
                else
                {
                    handleUnsolicited(line);
                }
                break;

            default: /* this should never be reached */
                LOGE("Unsupported AT command type %d\n", s_type);
                handleUnsolicited(line);
                break;
        }

    pthread_mutex_unlock(&s_commandmutex);
}


/**
 * Returns a pointer to the end of the next line
 * special-cases the "> " SMS prompt
 *
 * returns NULL if there is no complete line
 */
static char * findNextEOL(char *cur)
{
    if (cur[0] == '>' && cur[1] == ' ' && cur[2] == '\0')
    {
        /* SMS prompt character...not \r terminated */
        return cur+2;
    }

    // Find next newline
    while (*cur != '\0' && *cur != '\r' && *cur != '\n') cur++;

    return *cur == '\0' ? NULL : cur;
}


/**
 * 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()
{
    ssize_t count;

    char *p_read = NULL;
    char *p_eol = NULL;
    char *ret;

    /* this is a little odd. I use *s_ATBufferCur == 0 to
     * mean "buffer consumed completely". If it points to a character, than
     * the buffer continues until a \0
     */
    if (*s_ATBufferCur == '\0')
    {
        /* empty buffer */
        s_ATBufferCur = s_ATBuffer;
        *s_ATBufferCur = '\0';
        p_read = s_ATBuffer;
    }
    else       /* *s_ATBufferCur != '\0' */
    {
        /* there's data in the buffer from the last read */

        // skip over leading newlines
        while (*s_ATBufferCur == '\r' || *s_ATBufferCur == '\n')
            s_ATBufferCur++;

        p_eol = findNextEOL(s_ATBufferCur);

        if (p_eol == NULL)
        {
            /* a partial line. move it up and prepare to read more */
            size_t len;

            len = strlen(s_ATBufferCur);

            memmove(s_ATBuffer, s_ATBufferCur, len + 1);
            p_read = s_ATBuffer + len;
            s_ATBufferCur = s_ATBuffer;
        }
        /* Otherwise, (p_eol !- NULL) there is a complete line  */
        /* that will be returned the while () loop below        */
    }

    while (p_eol == NULL)
    {
        if (0 == MAX_AT_RESPONSE - (p_read - s_ATBuffer))
        {
            LOGE("ERROR: Input line exceeded buffer\n");
            /* ditch buffer and start over again */
            s_ATBufferCur = s_ATBuffer;
            *s_ATBufferCur = '\0';
            p_read = s_ATBuffer;
        }

        do
        {
            count = read(s_at_fd, p_read,
                         MAX_AT_RESPONSE - (p_read - s_ATBuffer));
            usleep(10000);
        }
        while (count < 0 && errno == EINTR);

        if (count > 0)
        {
            AT_DUMP( "<< ", p_read, count );

            p_read[count] = '\0';

            // skip over leading newlines
            while (*s_ATBufferCur == '\r' || *s_ATBufferCur == '\n')
                s_ATBufferCur++;

            p_eol = findNextEOL(s_ATBufferCur);
            p_read += count;
        }
        else if (count <= 0)
        {
            /* read error encountered or EOF reached */
            if(count == 0)
            {
                LOGD("atchannel: EOF reached");
            }
            else
            {
                LOGD("atchannel: read error %s", strerror(errno));
            }
            return NULL;
        }
    }

    /* a full line in the buffer. Place a \0 over the \r and return */

    ret = s_ATBufferCur;
    *p_eol = '\0';
    s_ATBufferCur = p_eol + 1; /* this will always be <= p_read,    */
    /* and there will be a \0 at *p_read */

    LOGD("AT< %s", ret);
    return ret;
}

static const char *readlineUrc()
{
    ssize_t count;

    char *p_read = NULL;
    char *p_eol = NULL;
    char *ret;

    /* this is a little odd. I use *s_ATBufferCur == 0 to
     * mean "buffer consumed completely". If it points to a character, than
     * the buffer continues until a \0
     */
    if (*s_UartBufferCur == '\0')
    {
        /* empty buffer */
        s_UartBufferCur = s_UartBuffer;
        *s_UartBufferCur = '\0';
        p_read = s_UartBuffer;
    }
    else       /* *s_ATBufferCur != '\0' */
    {
        /* there's data in the buffer from the last read */

        // skip over leading newlines
        while (*s_UartBufferCur == '\r' || *s_UartBufferCur == '\n')
            s_UartBufferCur++;

        p_eol = findNextEOL(s_UartBufferCur);

        if (p_eol == NULL)
        {
            /* a partial line. move it up and prepare to read more */
            size_t len;

            len = strlen(s_UartBufferCur);

            memmove(s_UartBuffer, s_UartBufferCur, len + 1);
            p_read = s_UartBuffer + len;
            s_UartBufferCur = s_UartBuffer;
        }
        /* Otherwise, (p_eol !- NULL) there is a complete line  */
        /* that will be returned the while () loop below        */
    }

    while (p_eol == NULL)
    {
        if (0 == MAX_AT_RESPONSE - (p_read - s_UartBuffer))
        {
            LOGE("ERROR: Input line exceeded buffer\n");
            /* ditch buffer and start over again */
            s_UartBufferCur = s_UartBuffer;
            *s_UartBufferCur = '\0';
            p_read = s_UartBuffer;
        }

        do
        {
            count = read(s_uart_fd, p_read,
                         MAX_AT_RESPONSE - (p_read - s_UartBuffer));
            usleep(10000);
        }
        while (count < 0 && errno == EINTR);

        if (count > 0)
        {
            AT_DUMP( "<< ", p_read, count );

            p_read[count] = '\0';

            // skip over leading newlines
            while (*s_UartBufferCur == '\r' || *s_UartBufferCur == '\n')
                s_UartBufferCur++;

            p_eol = findNextEOL(s_UartBufferCur);
            p_read += count;
        }
        else if (count <= 0)
        {
            /* read error encountered or EOF reached */
            if(count == 0)
            {
                LOGD("atchannel: EOF reached");
            }
            else
            {
                LOGD("atchannel: read error %s", strerror(errno));
            }
            return NULL;
        }
    }

    /* a full line in the buffer. Place a \0 over the \r and return */

    ret = s_UartBufferCur;
    *p_eol = '\0';
    s_UartBufferCur = p_eol + 1; /* this will always be <= p_read,    */
    /* and there will be a \0 at *p_read */

    LOGD("URC< %s", ret);
    return ret;
}



static void onReaderClosed()
{
    LOGD("onReaderClosed()");
    if (s_onReaderClosed != NULL && s_readerClosed == 0)
    {

        pthread_mutex_lock(&s_commandmutex);

        s_readerClosed = 1;

        pthread_cond_signal(&s_commandcond);

        pthread_mutex_unlock(&s_commandmutex);

        s_onReaderClosed();
    }
}

typedef struct
{
    int cid;
    bool act;
    bool waitting;
} info_cgact_wait_t;
extern info_cgact_wait_t cgact_wait;

static void *readerLoop(void *arg)
{
    UNUSED(arg);
    for (;;)
    {
        const char * line;

        line = readline();

        if (line == NULL)
        {
            break;
        }

        if(strStartsWith(line, "MBTK_AT_READY")) {
            //handleUnsolicited(line);
            continue;
        } else if(strStartsWith(line, "CONNECT")) {
            if(cgact_wait.waitting && cgact_wait.act) {
                cgact_wait.waitting = false;
            }
        }

        if(isSMSUnsolicited(line))
        {
            char *line1;
            const char *line2;

            // The scope of string returned by 'readline()' is valid only
            // till next call to 'readline()' hence making a copy of line
            // before calling readline again.
            line1 = strdup(line);
            line2 = readline();

            if (line2 == NULL)
            {
                free(line1);
                break;
            }

            if (s_unsolHandler != NULL)
            {
                s_unsolHandler (line1, line2);
            }
            free(line1);
        }
        else
        {
            processLine(line);
        }
    }

    onReaderClosed();

    return NULL;
}

static void *readerUrcLoop(void *arg)
{
    UNUSED(arg);
    for (;;)
    {
        const char *line;

        line = readlineUrc();

        if (line == NULL)
        {
            break;
        }

        handleUnsolicited(line);
    }

    onReaderClosed();

    return NULL;
}


/**
 * Sends string s to the radio with a \r appended.
 * Returns AT_ERROR_* on error, 0 on success
 *
 * This function exists because as of writing, android libc does not
 * have buffered stdio.
 */
static int writeline (const char *s)
{
    size_t cur = 0;
    size_t len = strlen(s);
    ssize_t written;

    if (s_at_fd < 0 || s_readerClosed > 0)
    {
        return AT_ERROR_CHANNEL_CLOSED;
    }

    LOGD("AT> %s", s);

    AT_DUMP( ">> ", s, strlen(s) );

    memset(s_curr_at, 0x0, AT_BUFF_MAX);
    memcpy(s_curr_at, s, strlen(s));

    /* the main string */
    while (cur < len)
    {
        do
        {
            written = write (s_at_fd, s + cur, len - cur);
        }
        while (written < 0 && errno == EINTR);

        if (written < 0)
        {
            return AT_ERROR_GENERIC;
        }

        cur += written;
    }

    /* the \r  */

    do
    {
        written = write (s_at_fd, "\r", 1);
    }
    while ((written < 0 && errno == EINTR) || (written == 0));

    if (written < 0)
    {
        return AT_ERROR_GENERIC;
    }

    return 0;
}

static int writeCtrlZ (const char *s)
{
    size_t cur = 0;
    size_t len = strlen(s);
    ssize_t written;

    if (s_at_fd < 0 || s_readerClosed > 0)
    {
        return AT_ERROR_CHANNEL_CLOSED;
    }

    LOGD("AT> %s^Z\n", s);

    AT_DUMP( ">* ", s, strlen(s) );

    /* the main string */
    while (cur < len)
    {
        do
        {
            written = write (s_at_fd, s + cur, len - cur);
        }
        while (written < 0 && errno == EINTR);

        if (written < 0)
        {
            return AT_ERROR_GENERIC;
        }

        cur += written;
    }

    /* the ^Z  */

    do
    {
        written = write (s_at_fd, "\032", 1);
    }
    while ((written < 0 && errno == EINTR) || (written == 0));

    if (written < 0)
    {
        return AT_ERROR_GENERIC;
    }

    return 0;
}

static void clearPendingCommand()
{
    if (sp_response != NULL)
    {
        at_response_free(sp_response);
    }

    sp_response = NULL;
    s_responsePrefix = NULL;
    s_smsPDU = NULL;
}


/**
 * Starts AT handler on stream "fd'
 * returns 0 on success, -1 on error
 */
int at_open(int at_fd, int uart_fd, ATUnsolHandler h)
{
    int ret;
    pthread_attr_t attr;

    s_at_fd = at_fd;
    s_uart_fd = uart_fd;
    s_unsolHandler = h;
    s_readerClosed = 0;
    s_responsePrefix = NULL;
    s_smsPDU = NULL;
    sp_response = NULL;

    pthread_attr_init (&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    ret = pthread_create(&s_tid_reader, &attr, readerLoop, NULL);
    if (ret < 0)
    {
        LOGE("AT thread create fail.");
        return -1;
    }

    pthread_t uart_tid_reader;
    ret = pthread_create(&uart_tid_reader, &attr, readerUrcLoop, NULL);
    if (ret < 0)
    {
        LOGE("Uart thread create fail.");
        return -1;
    }

    return 0;
}

/* FIXME is it ok to call this from the reader and the command thread? */
void at_close()
{
    LOGD("at_close()");
    if (s_at_fd >= 0)
    {
        close(s_at_fd);
    }
    if (s_uart_fd >= 0)
    {
        close(s_uart_fd);
    }
    s_at_fd = -1;
    s_uart_fd = -1;

    pthread_mutex_lock(&s_commandmutex);
    s_readerClosed = 1;
    pthread_cond_signal(&s_commandcond);
    pthread_mutex_unlock(&s_commandmutex);
    /* the reader thread should eventually die */

    at_state = RIL_AT_STATE_CLOSED;
}

static ATResponse * at_response_new()
{
    return (ATResponse *) calloc(1, sizeof(ATResponse));
}

void at_response_free(ATResponse *p_response)
{
    ATLine *p_line;

    if (p_response == NULL) return;

    p_line = p_response->p_intermediates;

    while (p_line != NULL)
    {
        ATLine *p_toFree;

        p_toFree = p_line;
        p_line = p_line->p_next;

        free(p_toFree->line);
        free(p_toFree);
    }

    free (p_response->finalResponse);
    free (p_response);
}

/**
 * The line reader places the intermediate responses in reverse order
 * here we flip them back
 */
static void reverseIntermediates(ATResponse *p_response)
{
    ATLine *pcur,*pnext;

    pcur = p_response->p_intermediates;
    p_response->p_intermediates = NULL;

    while (pcur != NULL)
    {
        pnext = pcur->p_next;
        pcur->p_next = p_response->p_intermediates;
        p_response->p_intermediates = pcur;
        pcur = pnext;
    }
}

static long long at_timeout_get(const char *at_command, bool *timeout_close)
{
    long long timeout = 0;
    int i;
    for(i = 0; i <  ARRAY_SIZE(at_timeout_list); i++)
    {
        if(!strncasecmp(at_command, at_timeout_list[i].at_command, strlen(at_timeout_list[i].at_command)))
        {
            timeout = at_timeout_list[i].timeout;
            *timeout_close = at_timeout_list[i].timeout_close;
            break;
        }
    }

    return timeout;
}

/**
 * Internal send_command implementation
 * Doesn't lock or call the timeout callback
 *
 * timeoutMsec == 0 means infinite timeout
 */
static int at_send_command_full_nolock (const char *command, ATCommandType type,
                                        const char *responsePrefix, const char *smspdu,
                                        long long timeoutMsec, ATResponse **pp_outResponse)
{
    int err = 0;
    bool tiemout_close = true;
    struct timespec ts;
    if(at_state == RIL_AT_STATE_READY)
        at_state = RIL_AT_STATE_BUSY;

    if(sp_response != NULL)
    {
        err = AT_ERROR_COMMAND_PENDING;
        goto error;
    }

    err = writeline (command);

    if (err < 0)
    {
        goto error;
    }

    s_type = type;
    s_responsePrefix = responsePrefix;
    s_smsPDU = smspdu;
    sp_response = at_response_new();

    if(timeoutMsec == 0)
    {
        timeoutMsec = at_timeout_get(command, &tiemout_close);
    }

    if (timeoutMsec != 0)
    {
        setTimespecRelative(&ts, timeoutMsec);
    }

    while (sp_response->finalResponse == NULL && s_readerClosed == 0)
    {
        //LOGD("AT wait time:%lld",timeoutMsec);
        if (timeoutMsec != 0)
        {
            err = pthread_cond_timedwait(&s_commandcond, &s_commandmutex, &ts);
        }
        else
        {
            err = pthread_cond_wait(&s_commandcond, &s_commandmutex);
        }

        //LOGD("AT continue:err - %d",err);
        if (err == ETIMEDOUT)
        {
            if(tiemout_close)
            {
                err = AT_ERROR_TIMEOUT_CLOSE;
            }
            else
            {
                err = AT_ERROR_TIMEOUT;
            }
            goto error;
        }
    }

    if (pp_outResponse == NULL)
    {
        at_response_free(sp_response);
    }
    else
    {
        /* line reader stores intermediate responses in reverse order */
        reverseIntermediates(sp_response);
        *pp_outResponse = sp_response;
    }

    sp_response = NULL;

    if(s_readerClosed > 0)
    {
        err = AT_ERROR_CHANNEL_CLOSED;
        goto error;
    }

    err = 0;
error:
    if(at_state == RIL_AT_STATE_BUSY)
        at_state = RIL_AT_STATE_READY;
    clearPendingCommand();

    return err;
}

/**
 * Internal send_command implementation
 *
 * timeoutMsec == 0 means infinite timeout
 */
static int at_send_command_full (const char *command, ATCommandType type,
                                 const char *responsePrefix, const char *smspdu,
                                 long long timeoutMsec, ATResponse **pp_outResponse)
{
    int err;

    if (0 != pthread_equal(s_tid_reader, pthread_self()))
    {
        /* cannot be called from reader thread */
        LOGE("cannot be called from reader thread.");
        return AT_ERROR_INVALID_THREAD;
    }

    // Waitting for previous AT complete.
    while(at_state == RIL_AT_STATE_BUSY)
    {
        usleep(10000);
    }

    pthread_mutex_lock(&s_commandmutex);

    err = at_send_command_full_nolock(command, type,
                                      responsePrefix, smspdu,
                                      timeoutMsec, pp_outResponse);

    pthread_mutex_unlock(&s_commandmutex);

    if (err == AT_ERROR_TIMEOUT_CLOSE && s_onTimeout != NULL)
    {
        s_onTimeout();
    }

    return err;
}


/**
 * Issue a single normal AT command with no intermediate response expected
 *
 * "command" should not include \r
 * pp_outResponse can be NULL
 *
 * if non-NULL, the resulting ATResponse * must be eventually freed with
 * at_response_free
 */
int at_send_command (const char *command, ATResponse **pp_outResponse)
{
    return at_send_command_full (command, NO_RESULT, NULL,
                                 NULL, 0, pp_outResponse);
}


int at_send_command_singleline (const char *command,
                                const char *responsePrefix,
                                ATResponse **pp_outResponse)
{
    int err;

    err = at_send_command_full (command, SINGLELINE, responsePrefix,
                                NULL, 0, pp_outResponse);

    if (err == 0 && pp_outResponse != NULL
        && (*pp_outResponse)->success > 0
        && (*pp_outResponse)->p_intermediates == NULL
       )
    {
        /* successful command must have an intermediate response */
        at_response_free(*pp_outResponse);
        *pp_outResponse = NULL;
        return AT_ERROR_INVALID_RESPONSE;
    }

    return err;
}

int at_send_command_singleline_with_timeout (const char *command,
        const char *responsePrefix,
        ATResponse **pp_outResponse,long long timeoutMsec)
{
    int err;

    err = at_send_command_full (command, SINGLELINE, responsePrefix,
                                NULL, timeoutMsec, pp_outResponse);

    if (err == 0 && pp_outResponse != NULL
        && (*pp_outResponse)->success > 0
        && (*pp_outResponse)->p_intermediates == NULL
       )
    {
        /* successful command must have an intermediate response */
        at_response_free(*pp_outResponse);
        *pp_outResponse = NULL;
        return AT_ERROR_INVALID_RESPONSE;
    }

    return err;
}



int at_send_command_numeric (const char *command,
                             ATResponse **pp_outResponse)
{
    int err;

    err = at_send_command_full (command, NUMERIC, NULL,
                                NULL, 0, pp_outResponse);

    if (err == 0 && pp_outResponse != NULL
        && (*pp_outResponse)->success > 0
        && (*pp_outResponse)->p_intermediates == NULL
       )
    {
        /* successful command must have an intermediate response */
        at_response_free(*pp_outResponse);
        *pp_outResponse = NULL;
        return AT_ERROR_INVALID_RESPONSE;
    }

    return err;
}


int at_send_command_sms (const char *command,
                         const char *pdu,
                         const char *responsePrefix,
                         ATResponse **pp_outResponse)
{
    int err;

    err = at_send_command_full (command, SINGLELINE, responsePrefix,
                                pdu, 0, pp_outResponse);

    if (err == 0 && pp_outResponse != NULL
        && (*pp_outResponse)->success > 0
        && (*pp_outResponse)->p_intermediates == NULL
       )
    {
        /* successful command must have an intermediate response */
        at_response_free(*pp_outResponse);
        *pp_outResponse = NULL;
        return AT_ERROR_INVALID_RESPONSE;
    }

    return err;
}


int at_send_command_multiline (const char *command,
                               const char *responsePrefix,
                               ATResponse **pp_outResponse)
{
    int err;

    err = at_send_command_full (command, MULTILINE, responsePrefix,
                                NULL, 0, pp_outResponse);

    return err;
}


/** This callback is invoked on the command thread */
void at_set_on_timeout(void (*onTimeout)(void))
{
    s_onTimeout = onTimeout;
}

/**
 *  This callback is invoked on the reader thread (like ATUnsolHandler)
 *  when the input stream closes before you call at_close
 *  (not when you call at_close())
 *  You should still call at_close()
 */

void at_set_on_reader_closed(void (*onClose)(void))
{
    s_onReaderClosed = onClose;
}


/**
 * Periodically issue an AT command and wait for a response.
 * Used to ensure channel has start up and is active
 */
int at_handshake()
{
//    int i;
    int err = 0;

    if (0 != pthread_equal(s_tid_reader, pthread_self()))
    {
        /* cannot be called from reader thread */
        return AT_ERROR_INVALID_THREAD;
    }
    pthread_mutex_lock(&s_commandmutex);

#if 0
    for (i = 0 ; i < HANDSHAKE_RETRY_COUNT ; i++)
    {
        /* some stacks start with verbose off */
        err = at_send_command_full_nolock("ATE0Q0V1", NO_RESULT,
                                          NULL, NULL, HANDSHAKE_TIMEOUT_MSEC, NULL);

        if (err == 0)
        {
            break;
        }
    }
#else
    err = at_send_command_full_nolock("ATE0Q0V1", NO_RESULT,
                                          NULL, NULL, 0, NULL);
#endif

    if (err == 0)
    {
        /* pause for a bit to let the input buffer drain any unmatched OK's
           (they will appear as extraneous unsolicited responses) */
        sleepMsec(HANDSHAKE_TIMEOUT_MSEC);
    }

    pthread_mutex_unlock(&s_commandmutex);


    return err;
}

/**
 * Returns error code from response
 * Assumes AT+CMEE=1 (numeric) mode
 */
AT_CME_Error at_get_cme_error(const ATResponse *p_response)
{
    int ret;
    int err;
    char *p_cur;

    if (p_response->success > 0)
    {
        return CME_SUCCESS;
    }

    if (p_response->finalResponse == NULL
        || !strStartsWith(p_response->finalResponse, "+CME ERROR:")
       )
    {
        return CME_ERROR_NON_CME;
    }

    p_cur = p_response->finalResponse;
    err = at_tok_start(&p_cur);

    if (err < 0)
    {
        return CME_ERROR_NON_CME;
    }

    err = at_tok_nextint(&p_cur, &ret);

    if (err < 0)
    {
        return CME_ERROR_NON_CME;
    }

    return ret;
}

mbtk_ril_at_state_enum at_state_get()
{
    return at_state;
}

void at_state_set(mbtk_ril_at_state_enum state)
{
    at_state = state;
}

bool at_rsp_check(ATResponse *p_response)
{
    if(!p_response || !p_response->success)
        return false;

    return true;
}

void unused_func()
{
    isFinalResponse(NULL);
}

