412 lines
12 KiB
C
412 lines
12 KiB
C
//
|
|
// Created by zemon on 31.03.23.
|
|
//
|
|
|
|
#include "AtGsmSimcomSim7600_Gnss.h"
|
|
#include "AtCmdCommonProtected.h"
|
|
#include "SystemDelayInterface.h"
|
|
#include "BaseTypes/Strings.h"
|
|
#include <stdbool.h>
|
|
#include <memory.h>
|
|
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_EcallOnlyMode(tAtCmd *env, bool mode) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
if(mode){
|
|
AtCmdSendStatic(env, "AT+CECALLSTAT=1\r\n");
|
|
} else{
|
|
AtCmdSendStatic(env, "AT+CECALLSTAT=0\r\n");
|
|
}
|
|
return AtCmdOkErrAnswer(env, 2000 * env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_SimProfileSelect(tAtCmd *env, tStringLink profileData) {
|
|
char simProfile[*profileData.length];
|
|
memcpy(&simProfile, profileData.data, *profileData.length);
|
|
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdTxAddStatic(env, "AT+CSIM=");
|
|
AtCmdTxAddDecimalIntWithLimit(env, *profileData.length, 2);
|
|
AtCmdTxAddStatic(env, ", ");
|
|
AtCmdTxAddStatic(env, "\"");
|
|
AtCmdTxAdd(env, simProfile, *profileData.length);
|
|
AtCmdTxAddStatic(env, "\"");
|
|
AtCmdTxAddStatic(env, "\r\n");
|
|
AtCmdTxSendLn(env);
|
|
|
|
return AtCmdOkErrAnswer(env, 2000 * env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_SetModemGSMPowerMode(tAtCmd *env, const uint16_t *value) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdTxAddStatic(env, "AT^BODYSARGSM=");
|
|
AtCmdTxAddDecimalIntWithLimit(env, *value, 2);
|
|
AtCmdTxSendLn(env);
|
|
return AtCmdOkErrAnswer(env, env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_SetModemWCDMAPowerMode(tAtCmd *env, const uint16_t *value) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdTxAddStatic(env, "AT^BODYSARWCDMA=");
|
|
AtCmdTxAddDecimalIntWithLimit(env, *value, 2);
|
|
AtCmdTxSendLn(env);
|
|
return AtCmdOkErrAnswer(env, env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_SetModemLTEPowerMode(tAtCmd *env, const uint16_t *value) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdTxAddStatic(env, "AT^BODYSARLTE=");
|
|
AtCmdTxAddDecimalIntWithLimit(env, *value, 2);
|
|
AtCmdTxSendLn(env);
|
|
return AtCmdOkErrAnswer(env, env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_ManualPowerMode(tAtCmd *env, const bool *mode) {
|
|
AtCmdTxClear(env);
|
|
if(*mode){
|
|
AtCmdSendStatic(env, "AT^BODYSARON=1\r\n");
|
|
return AtCmdOkErrAnswer(env, 2000 * env->stdRxTimeout);
|
|
} else {
|
|
return AT_OK;
|
|
// AtCmdSendStatic(env, "AT^BODYSARON=0\r\n");
|
|
// return AtCmdOkErrAnswer(env, 2000 * env->stdRxTimeout);
|
|
}
|
|
}
|
|
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_EchoMode(tAtCmd *env, bool mode) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
if(mode){
|
|
AtCmdSendStatic(env, "ATE1\r\n");
|
|
} else{
|
|
AtCmdSendStatic(env, "ATE0\r\n");
|
|
}
|
|
|
|
return AtCmdOkErrAnswer(env, 2000 * env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_DeleteGpsInfo(tAtCmd *env) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdSendStatic(env, "AT+CGPSDEL\r\n");
|
|
return AtCmdOkErrAnswer(env, 2000 * env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_SetConfigureAudioProfile(tAtCmd *env, tString32 *profileData) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdTxAddStatic(env, "AT+CACDBFN=");
|
|
AtCmdTxAdd(env, profileData->data, profileData->length);
|
|
AtCmdTxAddStatic(env, "\r\n");
|
|
AtCmdTxSendLn(env);
|
|
|
|
return AtCmdOkErrAnswer(env, env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_SetConfigureStaticRMCThread(tAtCmd *env) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdSendStatic(env, "AT+CGPSINFOCFG=1,3\r\n");
|
|
return AtCmdOkErrAnswer(env, 2000 * env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_OpenADB(tAtCmd *env) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdSendStatic(env, "AT+CUSBADB=1\r\n");
|
|
return AtCmdOkErrAnswer(env, 2000 * env->stdRxTimeout);
|
|
}
|
|
|
|
/*
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_StartReceiver(tAtCmd *env, bool value) {
|
|
AtCmdTxClear(env);
|
|
AtCmdTxAddStatic(env, "AT+CGPS=");
|
|
AtCmdTxAddChar(env, value ? '1' : '0');
|
|
AtCmdTxSendLn(env);
|
|
|
|
return AtCmdOkErrAnswer(env, 5 * env->stdRxTimeout);
|
|
}
|
|
*/
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_StartReceiver(tAtCmd *env, bool value) {
|
|
AtCmdPrepare(env);
|
|
AtCmdRxClear(env);
|
|
AtCmdTxAddStatic(env, "AT+CGPS=");
|
|
AtCmdTxAddChar(env, value ? '1' : '0');
|
|
AtCmdTxSendLn(env);
|
|
|
|
uint32_t timeout = 5000;
|
|
uint32_t endMs = SystemGetMs() + timeout;
|
|
uint32_t leftMs = timeout;
|
|
|
|
while ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) {
|
|
leftMs = endMs - SystemGetMs();
|
|
|
|
if (AtCmdRxBeginWithStatic(env, "OK")) {
|
|
AtCmdRxClear(env);
|
|
|
|
if (value) {
|
|
return AT_OK;
|
|
}
|
|
|
|
continue;
|
|
|
|
} else if (AtCmdRxBeginWithStatic(env, "ERROR")) {
|
|
AtCmdRxClear(env);
|
|
return AT_ERROR;
|
|
|
|
} else if (AtCmdRxBeginWithStatic(env, "+CGPS: ")) {
|
|
AtCmdRxClear(env);
|
|
return AT_OK;
|
|
} else {
|
|
AtCmdProcessUnresolvedLine(env);
|
|
AtCmdRxClear(env);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return AT_TIMEOUT;
|
|
}
|
|
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_HotStartReceiver(tAtCmd *env) {
|
|
AtCmdPrepare(env);
|
|
AtCmdRxClear(env);
|
|
AtCmdSendStatic(env, "AT+CGPSHOT\r\n");
|
|
|
|
return AtCmdOkErrAnswer(env, 5 * env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_SetExternalLnaSupport(tAtCmd *env, eSimcomSim7600_ExternalLnaSupportMode value) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdTxAddStatic(env, "AT$GPSELNA=");
|
|
AtCmdTxAddChar(env, value);
|
|
AtCmdTxSendLn(env);
|
|
|
|
return AtCmdOkErrAnswer(env, 2 * env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_GetCGSN(tAtCmd *env, char *acpString, size_t *acpStringLen) {
|
|
AtCmdPrepare(env);
|
|
AtCmdRxClear(env);
|
|
AtCmdSendStatic(env, "AT+CGSN\r\n");
|
|
|
|
AtCommandResult res = AtCmdReceiveNextLine(env, 15000);
|
|
|
|
if(res == AT_OK){
|
|
if (!AtCmdRxBeginWithStatic(env, "$GPRMC")) {
|
|
while (AtCmdReceiveNextLine(env, 4000) == AT_OK) {
|
|
if(env->rxBuffer.len == 17) {
|
|
*acpStringLen = env->rxBuffer.len;
|
|
memcpy(acpString, env->rxBuffer.data, *acpStringLen);
|
|
return AT_OK;
|
|
}
|
|
}
|
|
}
|
|
if (AtCmdRxBeginWithStatic(env, "ERROR")) {
|
|
return AT_ERROR;
|
|
}
|
|
}
|
|
|
|
return AT_TIMEOUT;
|
|
}
|
|
|
|
static uint8_t findDelimiter(tAtBuffer *address, char ch) {
|
|
|
|
for (size_t i = 0; i < address->len; ++i) {
|
|
if (address->data[i] == ch)
|
|
return i;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_GetAudioFilesValidation(tAtCmd *env) {
|
|
AtCmdPrepare(env);
|
|
AtCmdRxClear(env);
|
|
AtCmdSendStatic(env, "AT+FSCD=E:/\r\n");
|
|
|
|
uint8_t fileCount = 0;
|
|
bool fl_findetFile = false;
|
|
while ( (AtCmdReceiveNextLine(env, 500) == AT_OK) ) {
|
|
if(AtCmdRxBeginWithStatic(env, "+FSCD: E:/") == AT_OK){
|
|
AtCmdPrepare(env);
|
|
AtCmdRxClear(env);
|
|
AtCmdSendStatic(env, "AT+FSLS\r\n");
|
|
while ((AtCmdReceiveNextLine(env, 200) == AT_OK)) {
|
|
if(env->rxBuffer.len < 6){
|
|
continue;
|
|
}
|
|
uint8_t index = findDelimiter(&env->rxBuffer, '.');
|
|
if(
|
|
(env->rxBuffer.data[index + 0] == '.' ) &&
|
|
(env->rxBuffer.data[index + 1] == 'm' ) &&
|
|
(env->rxBuffer.data[index + 2] == 'p' ) &&
|
|
(env->rxBuffer.data[index + 3] == '3' )
|
|
){
|
|
fileCount ++;
|
|
}
|
|
#if (AURUS_CAR_UI == 1)
|
|
if(fileCount == 61){
|
|
return AT_OK;
|
|
} else {
|
|
continue;
|
|
}
|
|
#endif
|
|
#if (AURUS_CAR_UI == 0)
|
|
if(fileCount == 49){
|
|
return AT_OK;
|
|
} else {
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
return AT_ERROR;
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
return AT_TIMEOUT;
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_GetSoftRevInModem(tAtCmd *env, char *cgmrStr, size_t *cgmrStrLen) {
|
|
AtCmdPrepare(env);
|
|
AtCmdRxClear(env);
|
|
AtCmdSendStatic(env, "AT+CGMR\r\n");
|
|
|
|
uint32_t leftMs;
|
|
uint32_t endMs = SystemGetMs() + 5000;
|
|
|
|
while (endMs > SystemGetMs()) {
|
|
leftMs = endMs - SystemGetMs();
|
|
if ((AtCmdReceiveNextLine(env, leftMs) == AT_OK) && (SystemGetMs() < endMs)) {
|
|
if (AtCmdRxBeginWithStatic(env, "+CGMR: ")) {
|
|
static const uint16_t prefixSize = sizeof("+CGMR: ") - 1;
|
|
*cgmrStrLen = env->rxBuffer.len - (prefixSize + 2);
|
|
memcpy(cgmrStr, env->rxBuffer.data+ prefixSize, *cgmrStrLen);
|
|
return AT_OK;
|
|
}
|
|
}
|
|
if (AtCmdRxBeginWithStatic(env, "ERROR")){
|
|
return AT_ERROR;
|
|
}
|
|
AtCmdProcessUnresolvedLine(env);
|
|
}
|
|
|
|
return AT_TIMEOUT;
|
|
}
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_SetWorkingState(tAtCmd *env, eSimcomSim7600_FuncMode funcMode) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
|
|
if(funcMode == SIMCOM_FUNC_MAXIMAL) {
|
|
AtCmdSendStatic(env, "AT+CFUN=1\r\n");
|
|
SystemDelayMs(1000);
|
|
uint32_t endMs = SystemGetMs() + 10000;
|
|
while (endMs > SystemGetMs()) {
|
|
if (AtCmdReceiveNextLine(env, 1000) == AT_OK) {
|
|
if (AtCmdRxBeginWithStatic(env, "PB DONE")) {
|
|
SystemDelayMs(100);
|
|
return AT_OK;
|
|
}
|
|
if (AtCmdRxBeginWithStatic(env, "OK")) {
|
|
SystemDelayMs(100);
|
|
return AT_OK;
|
|
}
|
|
|
|
if (AtCmdRxBeginWithStatic(env, "ERROR")) {
|
|
return AT_ERROR;
|
|
}
|
|
if (AtCmdRxBeginWithStatic(env, "+CME ERROR: SIM busy")) {
|
|
AtCmdRxClear(env);
|
|
return AT_ERROR;
|
|
}
|
|
|
|
AtCmdProcessUnresolvedLine(env);
|
|
}
|
|
}
|
|
return AT_ERROR;
|
|
}
|
|
|
|
if(funcMode == SIMCOM_FUNC_MINIMAL) {
|
|
AtCmdSendStatic(env, "AT+CFUN=0\r\n");
|
|
uint32_t endMs = SystemGetMs() + 8000;
|
|
|
|
while (endMs > SystemGetMs()) {
|
|
if (AtCmdRxBeginWithStatic(env, "ERROR")) {
|
|
return AT_ERROR;
|
|
}
|
|
if (AtCmdReceiveNextLine(env, 4000) == AT_OK) {
|
|
if (AtCmdRxBeginWithStatic(env, "+SIMCARD: NOT AVAILABLE")) {
|
|
while (endMs > SystemGetMs()) {
|
|
if (AtCmdReceiveNextLine(env, 4000) == AT_OK) {
|
|
if (AtCmdRxBeginWithStatic(env, "OK")) {
|
|
SystemDelayMs(500);
|
|
AtCmdRxClear(env);
|
|
return AT_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (AtCmdRxBeginWithStatic(env, "OK")) {
|
|
SystemDelayMs(500);
|
|
AtCmdRxClear(env);
|
|
return AT_OK;
|
|
}
|
|
|
|
SystemDelayMs(10);
|
|
}
|
|
}
|
|
|
|
return AT_ERROR;
|
|
}
|
|
return AT_ERROR;
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_GnssStopThread(tAtCmd *env) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdSendStatic(env, "AT+CGPSINFOCFG=0,0\r\n");
|
|
return AtCmdOkErrAnswer(env, 2 * env->stdRxTimeout);
|
|
}
|
|
|
|
AtCommandResult AtGsm_Gsnss_Simcom7600_GetCCID(tAtCmd *env, char *ssidStr, size_t *ssidStrLen) {
|
|
AtCmdPrepare(env);
|
|
AtCmdTxClear(env);
|
|
AtCmdSendStatic(env, "AT+CICCID\r\n");
|
|
|
|
uint32_t endMs = SystemGetMs() + 5000;
|
|
while (endMs > SystemGetMs()) {
|
|
if (AtCmdReceiveNextLine(env, 1000) == AT_OK) {
|
|
if (AtCmdRxBeginWithStatic(env, "+ICCID: ")) {
|
|
static const uint16_t prefixSize = sizeof("+ICCID: ") - 1;
|
|
*ssidStrLen = env->rxBuffer.len - (prefixSize + 2);
|
|
memcpy(ssidStr, env->rxBuffer.data + prefixSize, *ssidStrLen);
|
|
return AT_OK;
|
|
}
|
|
|
|
if (AtCmdRxBeginWithStatic(env, "ERROR")) {
|
|
return AT_ERROR;
|
|
}
|
|
if (AtCmdRxBeginWithStatic(env, "+CME ERROR: SIM busy")) {
|
|
AtCmdPrepare(env);
|
|
AtCmdRxClear(env);
|
|
continue;
|
|
}
|
|
|
|
AtCmdProcessUnresolvedLine(env);
|
|
}
|
|
}
|
|
|
|
return AT_TIMEOUT;
|
|
}
|
|
|