int at_send_command_to_data_channel(const char *command, ATResponse **pp_outResponse, RILChannelCtx *p_channel) { const char* line = NULL; int ret = writeline(command, p_channel); if (ret == 0) { p_channel->p_response = at_response_new(); do { line = readline(p_channel); if (line != NULL) RLOGI("readline: %s", line); else RLOGI("readline: EMPTY"); } while (line != NULL && !(strcmp(line, "OK") == 0 || strcmp(line, "NO CARRIER") == 0 || strStartsWith(line, "CONNECT") == 1 || strstr(line, "ERROR"))); if (line != NULL) { RLOGI("process line: %s", line); processLine(line, p_channel); if (pp_outResponse == NULL) { at_response_free(p_channel->p_response); } else { reverseIntermediates(p_channel->p_response); *pp_outResponse = p_channel->p_response; } return 0; } } return AT_ERROR_GENERIC; }
void waitForTargetPPPStopped(RILChannelCtx *p_channel) { const char* line = NULL; int count = 0; p_channel->p_response = at_response_new(); while (count < 60) { line = readline(p_channel); if (line != NULL && strcmp(line, "NO CARRIER") == 0) { RLOGI("readline: %s [%d]", line, count); break; } else { RLOGI("Still wait for NO CARRIER [%d]", count); ++count; sleep(1); } } at_response_free(p_channel->p_response); }
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; } 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(); return err; }
/** * 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 = AT_NOERROR; struct atcontext *ac = getAtContext(); /* Default to NULL, to allow caller to free securely even if * no response will be set below */ if (pp_outResponse != NULL) *pp_outResponse = NULL; /* FIXME This is to prevent future problems due to calls from other threads; should be revised. */ while (pthread_mutex_trylock(&ac->requestmutex) == EBUSY) pthread_cond_wait(&ac->requestcond, &ac->commandmutex); if(ac->response != NULL) { err = AT_ERROR_COMMAND_PENDING; goto finally; } ac->type = type; ac->responsePrefix = responsePrefix; ac->smsPDU = smspdu; ac->response = at_response_new(); if (ac->response == NULL) { err = AT_ERROR_MEMORY_ALLOCATION; goto finally; } err = writeline (command); if (err != AT_NOERROR) goto finally; while (ac->response->finalResponse == NULL && ac->readerClosed == 0) { if (timeoutMsec != 0) err = pthread_cond_timeout_np(&ac->commandcond, &ac->commandmutex, timeoutMsec); else err = pthread_cond_wait(&ac->commandcond, &ac->commandmutex); if (err == ETIMEDOUT) { err = AT_ERROR_TIMEOUT; goto finally; } } if (ac->response->success == 0) { err = at_get_error(ac->response); } if (pp_outResponse == NULL) at_response_free(ac->response); else { /* Line reader stores intermediate responses in reverse order. */ reverseIntermediates(ac->response); *pp_outResponse = ac->response; } ac->response = NULL; if(ac->readerClosed > 0) { err = AT_ERROR_CHANNEL_CLOSED; goto finally; } finally: clearPendingCommand(); pthread_cond_broadcast(&ac->requestcond); pthread_mutex_unlock(&ac->requestmutex); return err; }
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; }