1374 lines
37 KiB
C
1374 lines
37 KiB
C
/*
|
||
* 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-SUBMIT(MS -> 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;
|
||
}
|
||
#pragma GCC pop_options
|