// // Created by xemon on 28.11.22. // #include #include "AtGsmSms_Utils.h" #include "AsciiStringParsingUtils.h" #include "stdbool.h" #include "AtCmdCommonProtected.h" #include "SimpleIndelibleMalloc.h" #include "SmsEncoderDecoder.h" #include "SystemDelayInterface.h" static AtCommandResult AtGsmSms_UtilsSendOnePdu(tAtCmd *env, uint8_t bufSmsId, char *pduBody) { uint8_t offset = 0; uint8_t serviceCenterPrefixSize = 0; uint8_t pduServiceCenterSize = iAsciiStringParseHexByte((pduBody + offset * 2)); offset += 1; serviceCenterPrefixSize += 1; if (pduServiceCenterSize) { uint8_t pduServiceCenterAddressType = iAsciiStringParseHexByte((pduBody + offset * 2)); offset += 1; serviceCenterPrefixSize += 1; // ServiceCenterAddress offset += pduServiceCenterSize; serviceCenterPrefixSize += pduServiceCenterSize; } //Flags offset += 1; //add pdu flags byte //Message Reference offset += 1; //add MR byte //Destination Address Length uint8_t pduAddressLen = iAsciiStringParseHexByte((pduBody + offset * 2)); offset += 1; //Destination Address Type offset += 1; // byte //Destination Address pduAddressLen = pduAddressLen / 2 + pduAddressLen % 2; offset += pduAddressLen; //Protocol Identifier offset += 1; //add PID byte //Data Coding Schema offset += 1; //add encoding byte if (false) { //Validity Period offset += 1; } //User Data Length uint8_t pduDataLen = iAsciiStringParseHexByte((pduBody + offset * 2)); uint8_t pduFullLen = offset + pduDataLen; uint8_t pduLen = pduFullLen - pduServiceCenterSize; pduFullLen += 1;//add pduDataLen byte to fullLen AtCommandResult atRes = AT_ERROR; uint32_t tm =0; tm = SystemGetMs() + 4000; while (tm > SystemGetMs()) { if (osMutexAcquire(env->access, 1000) == osOK) { atRes = AtGsmSms_DeleteById(env, bufSmsId); osMutexRelease(env->access); if (atRes == AT_OK){ break; } } } tm = SystemGetMs() + 4000; while (tm > SystemGetMs()) { if (osMutexAcquire(env->access, 1000) == osOK) { atRes = AtGsmSms_WriteNewPduSms(env, pduBody, pduFullLen * 2, pduLen); osMutexRelease(env->access); if (atRes == AT_OK){ break; } } } tm = SystemGetMs() + 4000; while (tm > SystemGetMs()) { if (osMutexAcquire(env->access, 1000) == osOK) { atRes = AtGsmSms_SendById(env, bufSmsId); osMutexRelease(env->access); if (atRes == AT_OK){ return AT_OK; } } } return AT_ERROR; } AtCommandResult AtGsmSms_BildPduData(char *pduPacket, uint16_t inpLenMes, char *pduDecodData, uint16_t *pduDecodLen) { volatile uint8_t SMS_BUFFER[1024 * 4]; tSimpleIndelibleMalloc simpleMalloc; tSmsPdu smsPdu; SimpleIndelibleMalloc_Init(&simpleMalloc, SMS_BUFFER, sizeof(SMS_BUFFER)); SimpleIndelibleMalloc_Clear(&simpleMalloc); tMemAllocInterface memInterface = SimpleIndelibleMalloc_GetInterface(&simpleMalloc); tSmsPdu_Init(&smsPdu, &memInterface); tSMS_Struct res; res = SmsPdu_Decode(&smsPdu, pduPacket, inpLenMes); *pduDecodLen = res.UDL * 2; if (*pduDecodLen) { memcpy(pduDecodData, res.UD, *pduDecodLen); return AT_OK; } else { return AT_ERROR; } } AtCommandResult AtGsmSms_UtilsSendPduData( tAtCmd *env, char *servNumber, uint8_t servNumberSize, char *phoneNumber, uint8_t phoneNumberSize, uint8_t *binaryData, uint8_t binaryDataSize ) { uint8_t SMS_BUFFER[1024 * 4]; tSimpleIndelibleMalloc simpleMalloc; tSmsPdu smsPdu; AtCommandResult atRes = AT_TIMEOUT; SimpleIndelibleMalloc_Init(&simpleMalloc, SMS_BUFFER, sizeof(SMS_BUFFER)); SimpleIndelibleMalloc_Clear(&simpleMalloc); tMemAllocInterface memInterface = SimpleIndelibleMalloc_GetInterface(&simpleMalloc); tSmsPdu_Init(&smsPdu, &memInterface); uint32_t tm = SystemGetMs() + 1000; while (tm > SystemGetMs()) { if (osMutexAcquire(env->access, 1000) == osOK) { atRes = AtGsmSms_SetMode(env, AT_GSM_SMS_MODE_PDU); osMutexRelease(env->access); if (atRes == AT_OK){ break; } } } if (atRes != AT_OK){ return AT_ERROR; } tm = SystemGetMs() + 4000; while (tm > SystemGetMs()) { if (osMutexAcquire(env->access, 1000) == osOK) { atRes = AtGsmSms_SetServiceCenter(env, servNumber, servNumberSize); osMutexRelease(env->access); if (atRes == AT_OK){ break; } } } if (atRes != AT_OK){ return AT_ERROR; } char nullPhone[phoneNumberSize + 1]; memcpy(nullPhone, phoneNumber, phoneNumberSize); nullPhone[phoneNumberSize] = 0; char hexDataString[1 + (binaryDataSize * 2)]; size_t hexDataLen = 0; vAsciiStringAddBytesAsHex(hexDataString, &hexDataLen, binaryData, binaryDataSize); hexDataString[hexDataLen] = 0; tPDUS *pdus = SmsPdu_Encode(&smsPdu, nullPhone, hexDataString, NULL, BIT8_HEX); AtCommandResult result = AT_ERROR; for (unsigned int i = 0; i < pdus->count; i++) { result = AtGsmSms_UtilsSendOnePdu(env, i, pdus->PDU[i]); // if (result != AT_OK) { // return return AT_OK;; // } } return result; return AT_OK; } AtCommandResult AtGsmSms_UtilsSendPduText( tAtCmd *env, char *servNumber, uint8_t servNumberSize, char *phoneNumber, uint8_t phoneNumberSize, char *textString, uint8_t textStringSize ) { uint8_t SMS_BUFFER[1024 * 4]; tSimpleIndelibleMalloc simpleMalloc; tSmsPdu smsPdu; SimpleIndelibleMalloc_Init(&simpleMalloc, SMS_BUFFER, sizeof(SMS_BUFFER)); SimpleIndelibleMalloc_Clear(&simpleMalloc); tMemAllocInterface memInterface = SimpleIndelibleMalloc_GetInterface(&simpleMalloc); tSmsPdu_Init(&smsPdu, &memInterface); char nullPhone[phoneNumberSize + 1]; memcpy(nullPhone, phoneNumber, phoneNumberSize); nullPhone[phoneNumberSize] = 0; char nullText[textStringSize + 1]; memcpy(nullText, textString, textStringSize); nullText[textStringSize] = 0; AT_INOKR(AtGsmSms_SetMode(env, AT_GSM_SMS_MODE_PDU)); if (servNumberSize) { AT_INOKR(AtGsmSms_SetServiceCenter(env, servNumber, servNumberSize)); } tPDUS *pdus = SmsPdu_Encode(&smsPdu, nullPhone, nullText, NULL, UCS2); for (unsigned int i = 0; i < pdus->count; i++) { AtCommandResult result = AtGsmSms_UtilsSendOnePdu(env, 1, pdus->PDU[i]); if (result != AT_OK) { return result; } } return AT_OK; }