Beispiel #1
0
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);

    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;
        }
    }

    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;
}
Beispiel #2
0
/**
 * 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 */
        return AT_ERROR_INVALID_THREAD;
    }

    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 && s_onTimeout != NULL) {
        s_onTimeout();
    }

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

    struct atcontext *ac = getAtContext();

    if (0 != pthread_equal(ac->tid_reader, pthread_self()))
        /* Cannot be called from reader thread. */
        return AT_ERROR_INVALID_THREAD;

    pthread_mutex_lock(&ac->commandmutex);

    for (i = 0 ; i < HANDSHAKE_RETRY_COUNT ; i++) {
        /* Some stacks start with verbose off. */
        err = at_send_command_full_nolock ("ATE0V1", NO_RESULT,
                    NULL, NULL, HANDSHAKE_TIMEOUT_MSEC, NULL);

        if (err == 0)
            break;
    }

    if (err == 0) {
        /* Pause for a bit to let the input buffer drain any unmatched OK's
           (they will appear as extraneous unsolicited responses). */
        ALOGD("%s() pausing %d ms to drain unmatched OK's...",
             __func__, HANDSHAKE_TIMEOUT_MSEC);
        sleepMsec(HANDSHAKE_TIMEOUT_MSEC);
    }

    pthread_mutex_unlock(&ac->commandmutex);

    return err;
}
Beispiel #4
0
/**
 * 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 useap, va_list ap)
{
    int err;

    struct atcontext *ac = getAtContext();
    static char strbuf[BUFFSIZE];
    const char *ptr;

    if (0 != pthread_equal(ac->tid_reader, pthread_self()))
        /* Cannot be called from reader thread. */
        return AT_ERROR_INVALID_THREAD;

    pthread_mutex_lock(&ac->commandmutex);
    if (useap) {
        if (!vsnprintf(strbuf, BUFFSIZE, command, ap)) {
           pthread_mutex_unlock(&ac->commandmutex);
           return AT_ERROR_STRING_CREATION;
        }
        ptr = strbuf;
    } else
        ptr = command;

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

    pthread_mutex_unlock(&ac->commandmutex);

    if (err == AT_ERROR_TIMEOUT && ac->onTimeout != NULL)
        ac->onTimeout();

    return err;
}
Beispiel #5
0
/**
 * 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, RILChannelCtx *p_channel)
{
	int err;

	if (0 != pthread_equal(p_channel->tid_reader, pthread_self())) {
		/* cannot be called from reader thread */
		RLOGD("Invalid Thread: send on %s, reader:%lu, self: %lu", p_channel->myName, p_channel->tid_reader, pthread_self());
		return AT_ERROR_INVALID_THREAD;
	}

	if (0 != p_channel->tid_myProxy) {
		/* This channel is occupied by some proxy */
		RLOGD("Occupied Thread: %s send on %s, pthread_self(): %lu, tid: %lu", command, p_channel->myName, pthread_self(), p_channel->tid_myProxy);
		assert(0);
		return AT_ERROR_INVALID_THREAD;
	}

	pthread_mutex_lock(&p_channel->commandmutex);

	/* Assign owner proxy */
	p_channel->tid_myProxy = pthread_self();

	RLOGD("AT send on %s, tid:%lu", p_channel->myName, p_channel->tid_myProxy);

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

	RLOGD("response received on %s, tid:%lu", p_channel->myName, p_channel->tid_myProxy);

	/* Release the proxy */
	p_channel->tid_myProxy = 0;

	pthread_mutex_unlock(&p_channel->commandmutex);

	if (err == AT_ERROR_TIMEOUT && s_onTimeout != NULL)
		s_onTimeout(p_channel);

	return err;
}
Beispiel #6
0
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;
#ifndef USE_NP
    struct timespec ts;
#endif /*USE_NP*/

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

    if (!strncmp(command, "ATD", 3))
        s_last_cme_error = CME_NO_ERROR;

    err = writeline (command);

    if (err < 0) {
        goto error;
    }

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

#ifndef USE_NP
    if (timeoutMsec != 0) {
        setTimespecRelative(&ts, timeoutMsec);
    }
#endif /*USE_NP*/

    while (sp_response->finalResponse == NULL && s_readerClosed == 0) {
        if (timeoutMsec != 0) {
#ifdef USE_NP
            err = pthread_cond_timeout_np(&s_commandcond, &s_commandmutex, timeoutMsec);
#else
            err = pthread_cond_timedwait(&s_commandcond, &s_commandmutex, &ts);
#endif /*USE_NP*/
        } else {
            err = pthread_cond_wait(&s_commandcond, &s_commandmutex);
        }

        if (err == ETIMEDOUT) {
            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:
    clearPendingCommand();

    /* Have to save the error message right away */
    if (pp_outResponse && !(*pp_outResponse)->success && !err && !strncmp(command, "ATD", 3)) {
        ATResponse *err_resp;
        err = at_send_command_full_nolock("AT+CEER", SINGLELINE, "+CEER:", NULL,
            timeoutMsec, &err_resp);
        if (!err) {
			if (err_resp->p_intermediates != NULL) {
				free(s_last_errmsg);
				s_last_errmsg = strdup(err_resp->p_intermediates->line);
			}
            at_response_free(err_resp);
        }
    }
    return err;
}