SmsEncoderDecoder/Src/SmsEncoderDecoder.c

1375 lines
37 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* SMS.c
*
* Created on: Dec 4, 2020
* Author: FICOM-IT LTD
*/
/*
* SMS.c
*
* Created on: Dec 4, 2020
* Author: FICOM-IT LTD
*/
//gitfix
#include "SmsEncoderDecoderPrivate.h"
#include <SmsCharMap.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
static void SmsEncoderDecoder_mfree(tSmsPdu *env, void *pointer);
static void *SmsEncoderDecoder_malloc(tSmsPdu *env, size_t size);
// initialize PDU constants
void tSmsPdu_Init(tSmsPdu *env, tMemAllocInterface *mem) {
env->mCSMMR = 0;
env->mRD = false;
env->mSRR = false;
env->mSCA = "";
env->mVP = "";
env->mCSMIEI = BIT8MIEI;
env->mem = mem;
}
void SmsEncoderDecoder_mfree(tSmsPdu *env, void *pointer) {
Mem_Free(env->mem, pointer);
}
void *SmsEncoderDecoder_malloc(tSmsPdu *env, size_t size) {
return Mem_Alloc(env->mem, size);
}
char *cSub_str(tSmsPdu *env, const char *str, int start, int size) {
memset(env->temp, '\0', SUB_STR_SIZE);
if (size > 0)
strncpy(env->temp, str + start, size);
else if (size < 0)
strcpy(env->temp, str + start);
return env->temp;
}
#pragma GCC push_options
#pragma GCC optimize ("O0")
tSMS_Struct SmsPdu_Decode(tSmsPdu *env, const char *data, uint16_t len) {
tSMS_Struct sms;
int end_index;
int PDUType;
sms.SCA = cSCADecoding(env, data, &end_index);
PDUType = strtol(cSub_str(env, data, end_index, 2), NULL, 16);
end_index += 2;
sms.RP = PDUType & (1 << 7) ? true : false;
sms.UDHI = PDUType & (1 << 6) ? true : false;
sms.SRI = PDUType & (1 << 5) ? true : false;
sms.MMS = PDUType & (1 << 2) ? false : true;
sms.MTI = PDUType & 3;
sms.OA = cOADecoding(env, data, end_index, &end_index);
sms.PID = strtol(cSub_str(env, data, end_index, 2), NULL, 16);
end_index += 2;
int DCSType = strtol(cSub_str(env, data, end_index, 2), NULL, 16);
end_index += 2;
sms.TC = DCSType & (1 << 5);
sms.DCS = (tEnumDCS) ((DCSType >> 2) & 3);
if (DCSType & (1 << 4)) {
sms.MC = DCSType & 3;
} else {
sms.MC = -1;
}
sms.SCTS = cSCTSDecoding(env, data, end_index);
end_index += 14;
if (sms.UDHI) {
sms.UDH = NULL;
sms.UDL = end_index;
// sms.UDH = tUDHDecoding(data, end_index + 2);
} else {
sms.UDH = NULL;
}
sms.UD = cUserDataDecoding(env, data, end_index, sms.UDHI, sms.DCS, &sms.UDL, len);
return sms;
}
#pragma GCC pop_options
char *cSCADecoding(tSmsPdu *env, const char *data, int *EndIndex) {
int len;
char *result;
char *buf;
len = strtol(cSub_str(env, data, 0, 2), NULL, 16);
if (len == 0) {
*EndIndex = 2;
return NULL;
}
*EndIndex = (len + 1) * 2;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * len * 2);
//wmemset(result, '0', sizeof(char) * (len * 2 + 1));
buf = result;
len *= 2;
if (strncmp(data + 2, "91", 2) == 0) {
sprintf(buf++, "+");
}
for (int i = 4; i < *EndIndex;
i += 2) {
sprintf(buf++, "%c", data[i + 1]);
sprintf(buf++, "%c", data[i]);
}
if (result[strlen(result) - 1] == L'F') {
result[strlen(result) - 1] = L'\0';
}
return result;
}
char *cOADecoding(tSmsPdu *env, const char *data, int index, int *EndIndex) {
int len;
char *result, *buf;
len = strtol(cSub_str(env, data, index, 2), NULL, 16);
if (len == 0) {
*EndIndex = index + 2;
return NULL;
}
*EndIndex = index + 4 + len;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (len + 2));
//wmemset(result, 0, sizeof(char) * (len + 1));
buf = result;
if (strncmp(data + index + 2, "91", 2) == 0) {
sprintf(buf++, "+");
}
for (int i = 0; i < len;
i += 2) {
sprintf(buf++, "%c", data[index + i + 5]);
sprintf(buf++, "%c", data[index + i + 4]);
}
if (len % 2 != 0) {
result[strlen(result) - 1] = '\0';
(*EndIndex)++;
}
return result;
}
char *cSCTSDecoding(tSmsPdu *env, const char *data, int index) {
char *result;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * 32);
sprintf(result, "20%02d-%02d-%02d %02d:%02d:%02d",
iBCDDecoding(env, data, index, 0),
iBCDDecoding(env, data, index + 2, 0),
iBCDDecoding(env, data, index + 4, 0),
iBCDDecoding(env, data, index + 6, 0),
iBCDDecoding(env, data, index + 8, 0),
iBCDDecoding(env, data, index + 10, 0)
);
return result;
}
int iBCDDecoding(tSmsPdu *env, const char *data, int index, bool isMSB) {
int n1, n10;
n1 = strtol(cSub_str(env, data, index, 1), NULL, 10);
n10 = strtol(cSub_str(env, data, index + 1, 1), NULL, 10);
if (isMSB) {
if (n10 >= 8)
return -((n10 - 8) * 10 + n1);
else
return n10 * 10 + n1;
} else {
return n10 * 10 + n1;
}
}
tUDHS *UDHDecoding(tSmsPdu *env, const char *data, int index) {
int len;
tUDHS *result;
len = strtol(cSub_str(env, data, index, 2), NULL, 16);
index += 2;
int i = 0;
result = (tUDHS *) SmsEncoderDecoder_malloc(env, sizeof(tUDHS));
result->UDH = (tPDUUDH *) SmsEncoderDecoder_malloc(env, sizeof(tPDUUDH) * len);
result->count = 0;
memset(result->UDH, 0, sizeof(tPDUUDH) * len);
while (i < len) {
char IEI = strtol(cSub_str(env, data, index, 2), NULL, 16);
index += 2;
int IEDL = strtol(cSub_str(env, data, index, 2), NULL, 16);
index += 2;
char *IED = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (IEDL + 1));
for (int j = 0; j < IEDL;
j++) {
IED[j] = strtol(cSub_str(env, data, index, 2), NULL, 16);
index += 2;
}
result->UDH[result->count].IEI = IEI;
result->UDH[result->count].IED = IED;
result->count++;
i += IEDL + 2;
}
return result;
}
char *cUserDataDecoding(tSmsPdu *env, const char *data, int index, bool UDHI, tEnumDCS dcs, int *UDDL, uint16_t len) {
char *result;
char *buf;
uint16_t idWrite = 0;
int UDL = strtol(cSub_str(env, data, index, 2), NULL, 16);
index += 2;
int UDHL = 0;
if (UDHI) {
UDHL = strtol(cSub_str(env, data, index, 2), NULL, 16);
UDHL++;
index += UDHL << 1;
}
if (dcs == UCS2) {
int len = (UDL - UDHL) >> 1;
int utf8_len;
*UDDL = len;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (len * 3));
buf = result;
u_int32_t code[2];
for (int i = 0; i < len;
i++) {
code[0] = strtol(cSub_str(env, data, (i << 2) + index, 4), NULL, 16);
code[1] = 0;
utf32toutf8((wchar_t *) code, (unsigned char *) buf, len * 3, &utf8_len);
buf += utf8_len;
}
buf[0] = '\0';
return result;
} else if (dcs == BIT7) {
int Septets = UDL - (UDHL * 8 + 6) / 7;
*UDDL = Septets;
int FillBits = (UDHL * 8 + 6) / 7 * 7 - UDHL * 8;
return cBIT7Decoding(env, cBIT7Unpack(env, data, index, Septets, FillBits), Septets);
} else {// 8Bit
UDL -= UDHL;
*UDDL = UDL;
uint16_t pos = UDL;
pos = pos * 2;
char res[pos];
pos = len - pos;
uint16_t writeBits = UDL;
while (idWrite < sizeof(res)) {
res[idWrite] = data[pos];
idWrite++;
pos++;
writeBits++;
}
result = res;
UDL -= UDHL;
return result;
}
return 0;
}
char *cBIT7Unpack(tSmsPdu *env, const char *data, int index, int Septets, int FillBits) {
char *result;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (Septets + 1));
// 7-Bit
int PackLen = (Septets * 7 + FillBits + 7) / 8;
int n = 0;
int left = 0;
for (int i = 0; i < PackLen; i++) {
int Order = (i + (7 - FillBits)) % 7;
int Value = strtol(cSub_str(env, data, (i << 1) + index, 2), NULL, 16);
if (i != 0 || FillBits == 0) {
result[n++] = ((Value << Order) + left) & 0x7F;
}
left = Value >> (7 - Order);
if (Order == 6) {
if (n == Septets)
break;
result[n++] = left;
left = 0;
}
}
return result;
}
char *cBIT7Decoding(tSmsPdu *env, char *BIT7Data, unsigned int size) {
char *result, *buf;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (size + 1));
buf = result;
for (int i = 0; i < size;
i++) {
u_int16_t key = BIT7Data[i];
if (isBIT7Same(env, key)) {
sprintf(buf++, "%c", key);
} else if (SmsCharMapGetValue(BIT7ToUCS2, SMS_DC_EC_MAP_SIZE(BIT7ToUCS2), key) >= 0) {
u_int16_t value;
if (key == 0x1B) {
value = SmsCharMapGetValue(BIT7EToUCS2, SMS_DC_EC_MAP_SIZE(BIT7EToUCS2), BIT7Data[i + 1]);
if (i < size - 1 && value > 0) {
sprintf(buf++, "%c", value);
i++;
} else {
value = SmsCharMapGetValue(BIT7ToUCS2, SMS_DC_EC_MAP_SIZE(BIT7ToUCS2), key);
sprintf(buf++, "%c", value);
}
} else { ;
value = SmsCharMapGetValue(BIT7ToUCS2, SMS_DC_EC_MAP_SIZE(BIT7ToUCS2), key);
sprintf(buf++, "%c", value);
}
} else {
sprintf(buf++, "?");
}
}
return result;
}
int isBIT7Same(tSmsPdu *env, u_int16_t UCS2) {
if ((UCS2 >= 0x61 && UCS2 <= 0x7A) ||
(UCS2 >= 0x41 && UCS2 <= 0x5A) ||
(UCS2 >= 0x25 && UCS2 <= 0x3F) ||
(UCS2 >= 0x20 && UCS2 <= 0x23) ||
UCS2 == 0x0A || UCS2 == 0x0D) {
return 1;
}
return 0;
}
tPDUS *SmsPdu_Encode(tSmsPdu *env, char *DA, char *UDC, tUDHS *udhs, tEnumDCS DCS) {
return tPDUDoEncoding(env, "", DA, UDC, udhs, DCS);
}
//
//////DA- DestenationAddress
//tPDUS *tPDUEncodingRAWData(tSmsEncoderDecoder *env,char *DestenationAddress, uint8_t *UserData,uint16_t LengthOfData){
// sms_init();
// return tPDUDoEncodingRAWData("", DestenationAddress, UserData, LengthOfData);
//}
////
////
//tPDUS *tPDUDoEncodingRAWData(tSmsEncoderDecoder *env,char *SCA,char *DestenationAddress, uint8_t *UserData,uint16_t LengthOfData){
// tUDS *uds = tUDCSplitRAWData(UserData, LengthOfData);
// tPDUS *pdus;
//
// if (uds == NULL)
// return NULL;
// pdus = (tPDUS *) sms_malloc(env,sizeof(tPDUS));
// pdus->count = 0;
// pdus->PDU = (char **) sms_malloc(env,sizeof(char *) * uds->total);
//
// if (tSmsEncoderDecoder *env,uds->total > 1){
// int CSMMR = env->mCSMMR;
// if (++env->mCSMMR > 0xFFFF)
// env->mCSMMR = 0;
// for(int i = 0; i < uds->total; i++){
// tUDHS *CSMUDH = tUpdateUDH(env,udhs, CSMMR, uds->total, i);
// pdus->PDU[i] = cSoloPDUEncoding(env,SCA, DA, uds->Data[i], CSMUDH, DCS);
// pdus->count++;
// }
//
// }
// else {
// pdus->PDU[0] = cSoloPDUEncoding(env,SCA, DA, uds->Data[0], udhs, DCS);
// pdus->count = 1;
// }
//
// return pdus;
//}
tPDUS *newPdus(tSmsPdu *env, uint16_t opacity) {
tPDUS *pdus = (tPDUS *) SmsEncoderDecoder_malloc(env, sizeof(tPDUS));
pdus->count = 0;
pdus->opacity = opacity;
pdus->PDU = (char **) SmsEncoderDecoder_malloc(env, sizeof(char *) * opacity);
return pdus;
}
void deletePdus(tSmsPdu *env, tPDUS *pdus) {
for (unsigned int i = 0; i < pdus->opacity;
++i) {
SmsEncoderDecoder_mfree(env, pdus->PDU[i]);
}
SmsEncoderDecoder_mfree(env, pdus);
}
tPDUS *tPDUDoEncoding(tSmsPdu *env, char *SCA, char *DA, char *UDC, tUDHS *udhs, tEnumDCS DCS) {
tUDS *uds = tUDCSplit(env, UDC, udhs, DCS);
tPDUS *pdus;
if (uds == NULL) {
return NULL;
}
pdus = newPdus(env, uds->total);
if (uds->total > 1) {
int CSMMR = env->mCSMMR;
if (++env->mCSMMR > 0xFFFF)
env->mCSMMR = 0;
for (int i = 0; i < uds->total;
i++) {
tUDHS *CSMUDH = tUpdateUDH(env, udhs, CSMMR, uds->total, i);
pdus->PDU[i] = cSoloPDUEncoding(env, SCA, DA, uds->Data[i], CSMUDH, DCS);
deleteUDHS(env, CSMUDH);
pdus->count++;
}
} else {
pdus->PDU[0] = cSoloPDUEncoding(env, SCA, DA, uds->Data[0], udhs, DCS);
pdus->count = 1;
}
deleteUDS(env, uds);
return pdus;
}
int isGSMString(tSmsPdu *env, char *Data) {
if (Data == NULL || strcmp(Data, "") == 0)
return 1;
if (is_acsii((unsigned char *) Data) == 0) {
int len;
len = utf8len((unsigned char *) Data);
u_int16_t *code = (u_int16_t *) SmsEncoderDecoder_malloc(env, sizeof(u_int16_t) * len);
utf8toutf16((unsigned char *) Data, code, len, &len);
while (*code) {
if (!(isBIT7Same(env, *code) || SmsCharMapGetValue(UCS2ToBIT7, SMS_DC_EC_MAP_SIZE(UCS2ToBIT7), *code) >= 0))
return 0;
code++;
}
return 1;
} else
return 1;
}
char *newStringCopy(tSmsPdu *env, char *orgn, uint16_t length) {
char *newStr = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (length + 1));
memcpy(newStr, orgn, length);
newStr[length] = 0;
return newStr;
}
tUDS *newUDS(tSmsPdu *env) {
tUDS *uds = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
uds->total = 0;
uds->Data = (char **) SmsEncoderDecoder_malloc(env, MAX_SMS_NR * sizeof(char *));
return uds;
}
void deleteUDS(tSmsPdu *env, tUDS *uds) {
if (uds->Data) {
for (uint8_t idx = 0; idx < uds->total;
++idx) {
SmsEncoderDecoder_mfree(env, uds->Data[idx]);
}
}
SmsEncoderDecoder_mfree(env, uds->Data);
SmsEncoderDecoder_mfree(env, uds);
}
tUDS *tUDCSplitUCS2(tSmsPdu *env, char *UDC, tUDHS *udhs, tEnumDCS DCS) {
int UDHL = iGetUDHL(env, udhs);
tUDS *result;
uint16_t maximal_portion_length = UDHL > UCS2UDL ? 0 : UCS2UDL - UDHL;
if (!maximal_portion_length) {
if (!(UDC == NULL || strcmp(UDC, "") == 0)) {
return NULL;
}
}
uint16_t full_data_length = strlen((char *) UDC);
if (full_data_length < maximal_portion_length) {
result = newUDS(env);
result->Data[result->total] = newStringCopy(env, UDC, full_data_length);
++result->total;
return result;
}
if (UDHL == 0)
UDHL++;
if (env->mCSMIEI == BIT8MIEI) {
UDHL += 5; // 1byte
} else {
UDHL += 6; // 2byte
}
maximal_portion_length = UDHL > UCS2UDL ? 0 : UCS2UDL - UDHL;
if (!maximal_portion_length) {
return NULL;
}
result = newUDS(env);
uint16_t portion_length;
uint16_t left = full_data_length;
uint16_t begin_offset = 0;
for (;
begin_offset < full_data_length; begin_offset += portion_length, left -= portion_length) {
portion_length = left > maximal_portion_length ? maximal_portion_length : left;
result->Data[result->total] = newStringCopy(env, UDC + begin_offset, portion_length);
++result->total;
}
return result;
}
tUDS *tUDCSplit(tSmsPdu *env, char *UDC, tUDHS *udhs, tEnumDCS DCS) {
int UDHL = iGetUDHL(env, udhs);
tUDS *result;
if (DCS == BIT7) {
// 7-Bit
int room = BIT7UDL - (UDHL * 8 + 6) / 7;
if (room < 1) {
if (UDC == NULL || strcmp(UDC, "") == 0) {
result = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
result->Data = (char **) SmsEncoderDecoder_malloc(env, sizeof(char *));
result->total = 1;
result->Data[0] = UDC;
return result;
} else
return NULL;
}
if (iSeptetsLength(env, UDC) <= room) {
result = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
result->Data = (char **) SmsEncoderDecoder_malloc(env, sizeof(char *));
result->total = 1;
result->Data[0] = UDC;
return result;
} else {
if (UDHL == 0)
UDHL++;
if (env->mCSMIEI == BIT8MIEI)
UDHL += 5;
else
UDHL += 6;
room = BIT7UDL - (UDHL * 8 + 6) / 7;
if (room < 1)
return NULL;
int i = 0;
int len = strlen(UDC);
result = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
result->total = 0;
result->Data = (char **) SmsEncoderDecoder_malloc(env, MAX_SMS_NR * sizeof(char *));
while (i < len) {
int step = iSeptetsToChars(env, UDC, i, room);
if (i + step < len) {
result->Data[result->total] = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (step + 1));
strcpy(result->Data[result->total++], cSub_str(env, UDC, i, step));
} else {
result->Data[result->total] = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (len - i + 1));
strcpy(result->Data[result->total++], cSub_str(env, UDC, i, -1));
}
i += step;
}
return result;
}
}
if (DCS == BIT8) { // BIT8
int room = BIT8UDL - UDHL;
if (room < 1) {
if (UDC == NULL || strcmp(UDC, "") == 0) {
result = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
result->Data = (char **) SmsEncoderDecoder_malloc(env, sizeof(char *));
result->total = 1;
result->Data[0] = UDC;
return result;
} else
return NULL;
}
if (UDC == NULL || utf8len((unsigned char *) UDC) <= room) {
result = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
result->Data = (char **) SmsEncoderDecoder_malloc(env, sizeof(char *));
result->total = 1;
result->Data[0] = UDC;
return result;
} else {
if (UDHL == 0)
UDHL++;
if (env->mCSMIEI == BIT8MIEI)
UDHL += 5; // 1byte
else
UDHL += 6; // 2byte
room = BIT8UDL - UDHL;
if (room < 1)
return NULL;
int len = utf8len((unsigned char *) UDC);
result = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
result->total = 0;
result->Data = (char **) SmsEncoderDecoder_malloc(env, MAX_SMS_NR * sizeof(char *));
int index = 0;
for (int i = 0; i < len;
i += room) {
int real_size;
if (i + room < len) {
real_size = utf8_get_size((unsigned char *) (UDC + index), room);
result->Data[result->total] = (char *) SmsEncoderDecoder_malloc(env,
sizeof(char) * (real_size + 1));
strcpy(result->Data[result->total++], cSub_str(env, UDC, index, real_size));
} else {
real_size = utf8_get_size((unsigned char *) (UDC + index), len - i);
result->Data[result->total] = (char *) SmsEncoderDecoder_malloc(env,
sizeof(char) * (real_size + 1));
strcpy(result->Data[result->total++], cSub_str(env, UDC, index, -1));
}
index += real_size;
}
return result;
}
}
if (DCS == BIT8_HEX) { // BIT8
int room = BIT8UDL - UDHL;
uint8_t hexRoom = room * 2;
if (room < 1) {
if (UDC == NULL || strcmp(UDC, "") == 0) {
result = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
result->Data = (char **) SmsEncoderDecoder_malloc(env, sizeof(char *));
result->total = 1;
result->Data[0] = UDC;
return result;
} else
return NULL;
}
uint8_t dataLen = strlen(UDC) / 2;
if (UDC == NULL || dataLen <= room) {
result = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
result->Data = (char **) SmsEncoderDecoder_malloc(env, sizeof(char *));
result->total = 1;
result->Data[0] = UDC;
return result;
} else {
if (UDHL == 0)
UDHL++;
if (env->mCSMIEI == BIT8MIEI)
UDHL += 5; // 1byte
else
UDHL += 6; // 2byte
room = BIT8UDL - UDHL;
hexRoom = room * 2;
if (room < 1)
return NULL;
uint8_t hexDataLen = strlen(UDC) / 2;
//init empty
result = (tUDS *) SmsEncoderDecoder_malloc(env, sizeof(tUDS));
result->total = 0;
result->Data = (char **) SmsEncoderDecoder_malloc(env, MAX_SMS_NR * sizeof(char *));
//add pdus one by one
uint8_t lessThenFullRoom = 0;
int real_size;
for (int index = 0; index < hexDataLen;
index += hexRoom) {
lessThenFullRoom = index + hexRoom < hexDataLen;
real_size = lessThenFullRoom ? hexDataLen - index : hexRoom;
result->Data[result->total] = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (real_size + 1));
strcpy(result->Data[result->total++], cSub_str(env, UDC, index, real_size));
}
return result;
}
}
if (DCS == UCS2) { // UCS2
return tUDCSplitUCS2(env, UDC, udhs, DCS);
}
return NULL;
}
//
//tUDS *tUDCSplitRAWData(tSmsEncoderDecoder *env,char *UserData, unsigned int UserDataLength){
// tUserRawDataPackages *result;
//
//
// if (tSmsEncoderDecoder *env,BIT8UDL < 1){
//
// if (tSmsEncoderDecoder *env,UserData == NULL || UserDataLength==NULL){
// result = (tUserRawDataPackages *) sms_malloc(env,sizeof(tUserRawDataPackages));
// result->Packages = (tUserRawDataSinglePackage *)sms_malloc(env,sizeof(tUserRawDataSinglePackage *));
// result->total = 1;
// result->Packages[0].Data = UserData;
// result->Packages[0].Length = UserDataLength;
// return result;
// }
// else
// return NULL;
// }
// if (tSmsEncoderDecoder *env,UserData == NULL || UserDataLength <= BIT8UDL){
//
// result = (tUserRawDataPackages *) sms_malloc(env,sizeof(tUserRawDataPackages));
// result->Packages = (tUserRawDataSinglePackage **)sms_malloc(env,sizeof(tUserRawDataSinglePackage *));
// result->total = 1;
// result->Packages[0].Data = UserData;
// result->Packages[0].Length = UserDataLength;
//
// return result;
// }
// else
// {
// uint tail = UserDataLength%BIT8UDL;
//
// result = (tUserRawDataPackages *) sms_malloc(env,sizeof(tUserRawDataPackages));
// result->total = (UserDataLength / BIT8UDL) + tail?1:0;
// result->Packages = (tUserRawDataSinglePackage **)sms_malloc(env,sizeof(tUserRawDataSinglePackage *)*result->total);
//
//
// uint left = UserDataLength;
// for(int i = 0; i < result->total; ++i){
//
// result->Packages[i].Length = left<BIT8UDL? left: BIT8UDL;
// left-=BIT8UDL;
// result->Packages[i].Data = UserData;
// UserData = ((unsigned char*)UserData+result->Packages[i].Length);
//
// }
//
// return result;
// }
//
//
//
//
// return NULL;
//}
int iGetUDHL(tSmsPdu *env, tUDHS *udhs) {
if (udhs == NULL)
return 0;
int UDHL = 1;
for (int i = 0; i < udhs->count;
i++) {
UDHL += strlen(udhs->UDH[i].IED) + 2;
}
return UDHL;
}
int iSeptetsLength(tSmsPdu *env, char *source) {
if (source == NULL || strcmp(source, "") == 0) {
return 0;
}
int len = strlen(source);
while (*source) {
u_int16_t code = (u_int16_t) *source;
if (SmsCharMapGetValue(UCS2ToBIT7, SMS_DC_EC_MAP_SIZE(UCS2ToBIT7), code) > 0xFF) {
len++;
}
source++;
}
return len;
}
int iSeptetsToChars(tSmsPdu *env, char *source, int index, int septets) {
if (source == NULL || strcmp(source, "") == 0)
return 0;
int count = 0;
int i;
for (i = index; i < strlen(source); i++) {
u_int16_t code = (u_int16_t) source[i];
if (SmsCharMapGetValue(UCS2ToBIT7, SMS_DC_EC_MAP_SIZE(UCS2ToBIT7), code) > 0xFF)
count++;
if (++count >= septets) {
if (count == septets)
i++;
break;
}
}
return i - index;
}
tUDHS *newUDHS(tSmsPdu *env, int count) {
tUDHS *udhs = (tUDHS *) SmsEncoderDecoder_malloc(env, sizeof(tUDHS));
udhs->UDH = (tPDUUDH *) SmsEncoderDecoder_malloc(env, sizeof(tPDUUDH) * (count));
udhs->count = count;
return udhs;
}
void deleteUDHS(tSmsPdu *env, tUDHS *udhs) {
for (uint16_t idx = 0; idx < udhs->count;
++idx) {
SmsEncoderDecoder_mfree(env, udhs->UDH->IED);
}
SmsEncoderDecoder_mfree(env, udhs->UDH);
SmsEncoderDecoder_mfree(env, udhs);
}
void copytPDUUDH(tSmsPdu *env, tPDUUDH *target, tPDUUDH *source) {
memcpy(target, source, sizeof(tPDUUDH));
if (source->IED) {
target->IED = SmsEncoderDecoder_malloc(env, sizeof(char) * target->count);
memcpy(target->IED, source->IED, sizeof(target->count));
}
}
void copytPDUUDHS(tSmsPdu *env, tPDUUDH *target, tPDUUDH *source, uint16_t count) {
for (uint16_t i = 0; i < count;
++i) {
copytPDUUDH(env, target + count, source + count);
}
}
tUDHS *tUpdateUDH(tSmsPdu *env, tUDHS *udhs, int CSMMR, int total, int index) {
tUDHS *result;
if (udhs == NULL || udhs->count == 0) {
result = newUDHS(env, 1);
} else {
result = newUDHS(env, udhs->count + 1);
//UDH
copytPDUUDHS(env, result->UDH + 1, udhs->UDH, udhs->count);
}
if (env->mCSMIEI == BIT8MIEI) {
result->UDH[0].IED = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * 3);
result->UDH[0].count = 3;
result->UDH[0].IED[0] = CSMMR & 0xFF;
result->UDH[0].IED[1] = total;
result->UDH[0].IED[2] = index + 1;
result->UDH[0].IEI = 0;
} else {
result->UDH[0].IED = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * 4);
result->UDH[0].count = 4;
result->UDH[0].IED[0] = (CSMMR >> 8) & 0xFF;
result->UDH[0].IED[1] = CSMMR & 0xFF;
result->UDH[0].IED[2] = total;
result->UDH[0].IED[3] = index + 1;
result->UDH[0].IEI = 8;
}
return result;
}
char *cSoloPDUEncoding(tSmsPdu *env, char *SCA, char *DA, char *UC, tUDHS *udhs, tEnumDCS DCS) {
char *result;
char *buf, *ret;
int index;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * 400);
buf = result;
ret = cSCAEncoding(env, SCA);
index = strlen(ret);
sprintf(buf, "%s", ret);
buf += index;
SmsEncoderDecoder_mfree(env, ret);
bool hasUDH = !(udhs == NULL || udhs->count == 0);
ret = cPDUTypeEncoding(env, hasUDH);
sprintf(buf, "%s", ret);
buf += strlen(ret);
SmsEncoderDecoder_mfree(env, ret);
ret = cMREncoding(env);
sprintf(buf, "%s", ret);
buf += strlen(ret);
ret = cDAEncoding(env, DA);
sprintf(buf, "%s", ret);
buf += strlen(ret);
SmsEncoderDecoder_mfree(env, ret);
ret = cPIDEncoding(env);
sprintf(buf, "%s", ret);
buf += strlen(ret);
ret = cDCSEncoding(env, UC, DCS);
sprintf(buf, "%s", ret);
buf += strlen(ret);
sprintf(buf, "%s", env->mVP);
buf += strlen(env->mVP);
ret = cUDEncoding(env, UC, udhs, DCS);
sprintf(buf, "%s", ret);
SmsEncoderDecoder_mfree(env, ret);
return result;
}
char *cSoloPDUEncodingRAWData(tSmsPdu *env, char *SCA, char *DA, char *UserData, uint UserDataLength,
tUDHS *udhs) {
char *result;
char *buf, *ret;
int index;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * 400);
buf = result;
ret = cSCAEncoding(env, SCA);
index = strlen(ret);
sprintf(buf, "%s", ret);
buf += index;
if (udhs == NULL || udhs->count == 0) {
ret = cPDUTypeEncoding(env, false);
sprintf(buf, "%s", ret);
buf += strlen(ret);
} else {
ret = cPDUTypeEncoding(env, true);
sprintf(buf, "%s", ret);
buf += strlen(ret);
}
ret = cMREncoding(env);
sprintf(buf, "%s", ret);
buf += strlen(ret);
ret = cDAEncoding(env, DA);
sprintf(buf, "%s", ret);
buf += strlen(ret);
ret = cPIDEncoding(env);
sprintf(buf, "%s", ret);
// buf += strlen(ret);
// ret = cDCSEncoding(env,UC, DCS);
// sprintf(buf, "%s", ret);
//
//
// buf += strlen(ret);
// sprintf(buf, "%s", env->mVP);
//
//
// buf += strlen(env->mVP);
// ret = cUDEncoding(env,UC, udhs, DCS);
// sprintf(buf, "%s", ret);
return result;
}
char *cSCAEncoding(tSmsPdu *env, char *SCA) {
char *result;
if (SCA == NULL || strcmp(SCA, "") == 0) {
// SMS center on SIM or set AT+CSCA command
return newStringCopy(env, "00", 2);
}
char *buf;
int len;
len = strlen(SCA);
result = (char *) SmsEncoderDecoder_malloc(env, (len + 5) * sizeof(char));
buf = result;
int index = 0;
if (SCA[0] == '+') {
sprintf(buf, "%02X", len / 2 + 1);
buf += 2;
sprintf(buf, "91");
buf += 2;
index = 1;
} else {
sprintf(buf, "%02X", len / 2 + 1);
buf += 2;
sprintf(buf, "81");
buf += 2;
}
// SCA
for (; index < len; index += 2) {
if (index == len - 1) {
// “F”
sprintf(buf++, "F");
sprintf(buf++, "%c", SCA[index]);
} else {
sprintf(buf++, "%c", SCA[index + 1]);
sprintf(buf++, "%c", SCA[index]);
}
}
return result;
}
char *cPDUTypeEncoding(tSmsPdu *env, bool UDH) {
// Message Type Indicator
// 01 SMS-SUBMITMS -> SMSC
int PDUType = 0x01;
char *result;
result = (char *) SmsEncoderDecoder_malloc(env, 3 * sizeof(char));
// User Data Header Indicator
if (UDH) {
PDUType |= 0x40;
}
// Validity Period Format
if (strlen(env->mVP) == 2) {
// VP
PDUType |= 0x10;
} else if (strlen(env->mVP) == 14) {
// VP semi-octet
PDUType |= 0x18;
}
// Status Report Request
if (env->mSRR) {
// 请求状态报告
PDUType |= 0x20;
}
// Reject Duplicate
if (env->mRD) {
PDUType |= 0x04;
}
sprintf(result, "%02X", PDUType);
return result;
}
char *cMREncoding(tSmsPdu *env) {
return "00";
}
char *cDAEncoding(tSmsPdu *env, char *DA) {
if (DA == NULL || strcmp(DA, "") == 0) {
return newStringCopy(env, "0080", 4);
}
char *result, *buf;
int len = strlen(DA);
int index = 0;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (len + 5));
buf = result;
if (DA[0] == '+') {
sprintf(buf, "%02X", len - 1);
buf += 2;
sprintf(buf, "91");
buf += 2;
index = 1;
} else {
sprintf(buf, "%02X", len);
buf += 2;
sprintf(buf, "81");
buf += 2;
index = 0;
}
for (; index < len; index += 2) {
if (index == len - 1) {
sprintf(buf++, "F");
sprintf(buf++, "%c", DA[index]);
} else {
sprintf(buf++, "%c", DA[index + 1]);
sprintf(buf++, "%c", DA[index]);
}
}
return result;
}
char *cPIDEncoding(tSmsPdu *env) {
return "00";
}
char *cDCSEncoding(tSmsPdu *env, char *UD, tEnumDCS DCS) {
if (DCS == BIT7) {
// 7-Bit
return "00";
}
if (DCS == BIT8) {
//8-bit
return "04";
}
if (DCS == BIT8_HEX) {
//8-bit
return "04";
}
if (DCS == UCS2) {
// UCS2
return "08";
}
}
char *cUDEncoding(tSmsPdu *env, char *UD, tUDHS *udhs, tEnumDCS DCS) {
int UDHL;
char *result;
char *header = cUDHEncoding(env, udhs, &UDHL);
int UDCL;
char *body;
body = cUDCEncoding(env, UD, &UDCL, UDHL, DCS);
int UDL;
if (DCS == BIT7) {
// 7-Bit
UDL = (UDHL * 8 + 6) / 7 + UDCL;
} else {
// UCS2 8-Bit
UDL = UDHL + UDCL;
}
int len = strlen(header) + strlen(body) + 2;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (len + 1));
sprintf(result, "%02X%s%s", UDL, header, body);
SmsEncoderDecoder_mfree(env, header);
SmsEncoderDecoder_mfree(env, body);
return result;
}
char *cUDHEncoding(tSmsPdu *env, tUDHS *udhs, int *UDHL) {
*UDHL = 0;
if (udhs == NULL || udhs->count == 0)
return newStringCopy(env, "", 0);
for (int i = 0; i < udhs->count;
i++) {
*UDHL += udhs->UDH[i].count + 2;
}
char *result;
char *buf;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * ((*UDHL + 1) * 2 + 1));
buf = result;
sprintf(buf, "%02X", *UDHL);
buf += 2;
for (int i = 0; i < udhs->count;
i++) {
sprintf(buf, "%02X", udhs->UDH[i].IEI);
buf += 2;
sprintf(buf, "%02X", udhs->UDH[i].count);
buf += 2;
for (int j = 0; j < udhs->UDH[i].count;
j++) {
sprintf(buf, "%02X", udhs->UDH[i].IED[j]);
buf += 2;
}
}
(*UDHL)++;
return result;
}
char *cUDCEncoding(tSmsPdu *env, char *UDC, int *UDCL, int UDHL, tEnumDCS DCS) {
if (UDC == NULL || strcmp(UDC, "") == 0) {
*UDCL = 0;
return "";
}
if (DCS == BIT7) { // 7-Bit
return cBIT7Pack(env, tBIT7Encoding(env, UDC, UDCL), UDHL);
}
if (DCS == BIT8) { // 8-bit
int len = utf8len((unsigned char *) UDC);
//int len2;
// unsigned short *code;
//code = (unsigned short *) sms_malloc(env,sizeof(unsigned short) * len);
//utf8toutf16((unsigned char *) UDC, code, len, &len2);
*UDCL = len;
char *result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (*UDCL * 2 + 1));
char *buf = result;
for (int i = 0; i < len;
i++) {
sprintf(buf, "%02X", UDC[i]); //code[i]);
buf += 2;
}
// sms_mfree(env,code);
return result;
}
if (DCS == BIT8_HEX) { // 8-bit hex data
int len = strlen(UDC);
*UDCL = len / 2;
char *result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (len + 1));
memcpy(result, UDC, len);
return result;
}
if (DCS == UCS2) { // UCS2
int len = utf8len((unsigned char *) UDC);
int len2;
unsigned short *code;
code = (unsigned short *) SmsEncoderDecoder_malloc(env, sizeof(unsigned short) * len);
utf8toutf16((unsigned char *) UDC, code, len, &len2);
*UDCL = len * 2;
char *result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (*UDCL * 2 + 1));
char *buf = result;
for (int i = 0; i < len;
i++) {
sprintf(buf, "%04X", code[i]);
buf += 4;
}
SmsEncoderDecoder_mfree(env, code);
return result;
}
return "";
}
tByteArray *tBIT7Encoding(tSmsPdu *env, char *UDC, int *Septets) {
tByteArray *result;
int len = strlen(UDC);
result = (tByteArray *) SmsEncoderDecoder_malloc(env, sizeof(tByteArray));
result->len = 0;
result->array = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (len * 2 + 1));
*Septets = 0;
for (int i = 0; i < len;
i++) {
u_int16_t code = (u_int16_t) UDC[i];
if (isBIT7Same(env, code)) {
result->array[(*Septets)++] = code;
} else {
u_int16_t value = SmsCharMapGetValue(UCS2ToBIT7, SMS_DC_EC_MAP_SIZE(UCS2ToBIT7), code);
if (value >= 0) {
if (value > 0xFF) {
result->array[(*Septets)++] = value >> 8;
result->array[(*Septets)++] = value & 0xFF;
} else {
result->array[(*Septets)++] = value;
}
} else {
result->array[(*Septets)++] = (u_int16_t) '?';
}
}
}
result->len = *Septets;
return result;
}
char *cBIT7Pack(tSmsPdu *env, tByteArray *Bit7Array, int UDHL) {
// 7Bit
int fillBits = (UDHL * 8 + 6) / 7 * 7 - (UDHL * 8);
int len = Bit7Array->len;
int packLen = (len * 7 + fillBits + 7) / 8;
char *result;
char *buf;
result = (char *) SmsEncoderDecoder_malloc(env, sizeof(char) * (packLen * 2 + 1));
buf = result;
int left = 0;
for (int i = 0; i < len;
i++) {
int32_t Value = Bit7Array->array[i];
int32_t index = (i + 8 - fillBits) % 8;
if (index == 0) {
left = Value;
} else {
int32_t n = ((Value << (8 - index)) | left) & 0xFF;
sprintf(buf, "%02X", (unsigned int) n);
buf += 2;
left = Value >> index;
}
}
if ((len * 7 + fillBits) % 8 != 0) {
sprintf(buf, "%02X", left);
buf += 2;
}
buf[0] = '\0';
return result;
}