diff options
author | Uros Majstorovic <majstor@majstor.org> | 2020-08-05 03:10:01 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2020-08-05 03:10:01 +0200 |
commit | 9fcfdb87e3de42232544cf61d82cedc3661364cf (patch) | |
tree | 53e6b04f62f625a80dbe72a56916234b1c20e2f0 | |
parent | ba38183139e19d5e07a4f30822eb285dde9bd7ca (diff) |
sms pdu mode impl added
-rw-r--r-- | code/esp32/components/eos/gsm.c | 453 | ||||
-rw-r--r-- | code/esp32/components/eos/gsm_cp.c | 109 | ||||
-rw-r--r-- | code/esp32/components/eos/include/gsm.h | 117 |
3 files changed, 679 insertions, 0 deletions
diff --git a/code/esp32/components/eos/gsm.c b/code/esp32/components/eos/gsm.c new file mode 100644 index 0000000..788722e --- /dev/null +++ b/code/esp32/components/eos/gsm.c @@ -0,0 +1,453 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "gsm.h" + +#define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0)) + +uint8_t pdu_getc(char *pdu) { + int ch; + sscanf(pdu, "%2X", &ch); + return ch; +} + +void pdu_putc(uint8_t ch, char *pdu) { + sprintf(pdu, "%.2X", ch); +} + +void pdu_puts(uint8_t *s, int s_len, char *pdu) { + int i; + + for (i=0; i<s_len; i++) { + sprintf(pdu + 2 * i, "%.2X", s[i]); + } +} + +void pdu_gets(char *pdu, uint8_t *s, int s_len) { + int i, ch; + + for (i=0; i<s_len; i++) { + sscanf(pdu + 2 * i, "%2X", &ch); + s[i] = ch; + } +} + +void gsm_dcs_dec(uint8_t dcs, uint8_t *enc, uint16_t *flags) { + if ((dcs & GSM_DCS_GENERAL_IND) == 0) { + *enc = dcs & GSM_DCS_ENC; + if (dcs & GSM_DCS_CLASS_IND) { + *flags |= GSM_FLAG_CLASS; + *flags |= (uint16_t)(dcs & GSM_DCS_CLASS) << 8; + } + if (dcs & GSM_DCS_COMPRESS_IND) *flags |= GSM_FLAG_COMPRESS; + if (dcs & GSM_DCS_DELETE_IND) *flags |= GSM_FLAG_DELETE; + } else { + uint8_t group = dcs & GSM_DCS_GROUP; + + switch (group) { + case GSM_DCS_MWI_DISCARD: + case GSM_DCS_MWI_STORE_GSM7: + case GSM_DCS_MWI_STORE_UCS2: + if (group == GSM_DCS_MWI_STORE_UCS2) { + *enc = GSM_ENC_UCS2; + } else { + *enc = GSM_ENC_7BIT; + } + if (GSM_DCS_MWI_DISCARD) *flags |= GSM_FLAG_DISCARD; + *flags |= GSM_FLAG_MWI; + *flags |= (uint16_t)(dcs & (GSM_DCS_MWI_SENSE | GSM_DCS_MWI_TYPE)) << 12; + break; + + case GSM_DCS_ENCLASS: + *flags |= GSM_FLAG_CLASS; + *flags |= (uint16_t)(dcs & GSM_DCS_CLASS) << 8; + *enc = dcs & GSM_DCS_ENCLASS_ENC ? GSM_ENC_8BIT : GSM_ENC_7BIT; + break; + } + } +} + +void gsm_dcs_enc(uint8_t enc, uint16_t flags, uint8_t *dcs) { + *dcs = enc; + if (flags & GSM_FLAG_CLASS) { + *dcs |= GSM_DCS_CLASS_IND; + *dcs |= (flags >> 8) & GSM_DCS_CLASS; + } + if (flags & GSM_FLAG_COMPRESS) *dcs |= GSM_DCS_COMPRESS_IND; + if (flags & GSM_FLAG_DELETE) *dcs |= GSM_DCS_DELETE_IND; +} + +int gsm_ts_enc(char *ts, char *pdu, int pdu_size) { + uint8_t tz; + int tz_hh, tz_mm; + + if (pdu_size < 14) return GSM_ERR; + + pdu[1] = ts[2]; // YY + pdu[0] = ts[3]; + + pdu[3] = ts[5]; // MM + pdu[2] = ts[6]; + + pdu[5] = ts[8]; // DD + pdu[4] = ts[9]; + + pdu[7] = ts[11]; // hh + pdu[6] = ts[12]; + + pdu[9] = ts[14]; // mm + pdu[8] = ts[15]; + + pdu[11] = ts[17]; // ss + pdu[10] = ts[18]; + + sscanf(ts + 20, "%2d:%2d", &tz_hh, &tz_mm); + tz = tz_hh * 4 + tz_mm / 15; + tz = (tz / 10) | ((tz % 10) << 4); + if (ts[19] == '-') tz |= 0x08; + + pdu_putc(tz, pdu + 12); + + return 14; +} + +int gsm_ts_dec(char *pdu, int pdu_len, char *ts) { + uint8_t tz; + + if (pdu_len < 14) return GSM_ERR; + + ts[0] = '2'; + ts[1] = '0'; + ts[2] = pdu[1]; // YY + ts[3] = pdu[0]; + ts[4] = '-'; + ts[5] = pdu[3]; // MM + ts[6] = pdu[2]; + ts[7] = '-'; + ts[8] = pdu[5]; // DD + ts[9] = pdu[4]; + ts[10] = 'T'; + ts[11] = pdu[7]; // hh + ts[12] = pdu[6]; + ts[13] = ':'; + ts[14] = pdu[9]; // mm + ts[15] = pdu[8]; + ts[16] = ':'; + ts[17] = pdu[11]; // ss + ts[18] = pdu[10]; + + tz = pdu_getc(pdu + 12); + if (tz & 0x08) { + ts[19] = '-'; + tz = tz & ~0x08; + } else { + ts[19] = '+'; + } + tz = (tz & 0x0f) * 10 + (tz >> 4); + sprintf(ts + 20, "%.2d:%.2d", tz / 4, (tz % 4) * 15); + + return 14; +} + +int gsm_7bit_enc(char *text, int text_len, char *pdu, int padb) { + uint8_t carry = 0; + int i = 0, pdu_len = 0, shc = 0; + + if (!text_len) return 0; + + if (padb) { + shc = 7 - padb; + } else { + carry = *text; + i++; + } + + while (i < text_len) { + pdu_putc(carry | (*(text + i) << (7 - shc)), pdu + pdu_len); + pdu_len += 2; + + shc++; + shc = shc % 7; + if (!shc) { + i++; + if (i == text_len) return pdu_len; + } + + carry = *(text + i) >> shc; + i++; + } + pdu_putc(carry, pdu + pdu_len); + pdu_len += 2; + + return pdu_len; +} + +int gsm_7bit_dec(char *pdu, char *text, int text_len, int padb) { + uint8_t ch; + uint8_t carry = 0; + int i = 0, pdu_len = 0, shc = 0; + + if (!text_len) return 0; + + if (padb) { + ch = pdu_getc(pdu); + pdu_len += 2; + if (padb == 1) { + *text = ch >> 1; + i++; + } else { + carry = ch >> padb; + shc = 8 - padb; + } + } + + while (i < text_len) { + ch = pdu_getc(pdu + pdu_len); + pdu_len += 2; + + *(text + i) = ((ch << shc) | carry) & 0x7f; + carry = ch >> (7 - shc); + i++; + + shc++; + shc = shc % 7; + if (!shc && (i < text_len)) { + *(text + i) = carry; + carry = 0; + i++; + } + } + + return pdu_len; +} + +int gsm_addr_enc(char *addr, int addr_len, uint8_t addr_type, char *pdu, int pdu_size) { + int _pdu_len; + + addr_type |= GSM_EXT; + + if ((addr_type & GSM_TON) == GSM_TON_ALPHANUMERIC) { + int _addr_len = DIVC(addr_len * 7, 4); + + _pdu_len = 4 + DIVC(_addr_len, 2) * 2; + if (pdu_size < _pdu_len) return GSM_ERR; + + pdu_putc(_addr_len, pdu); + pdu_putc(addr_type, pdu + 2); + gsm_7bit_enc(addr, addr_len, pdu, 0); + } else { + int i; + + if (addr_type & GSM_TON_INTERNATIONAL) { + if (addr[0] != '+') return GSM_ERR; + addr++; + addr_len--; + } + _pdu_len = 4 + DIVC(addr_len, 2) * 2; + if (pdu_size < _pdu_len) return GSM_ERR; + + pdu_putc(addr_len, pdu); + pdu_putc(addr_type, pdu + 2); + for (i=0; i<addr_len / 2; i++) { + pdu[4 + 2 * i] = addr[2 * i + 1]; + pdu[4 + 2 * i + 1] = addr[2 * i]; + } + if (addr_len % 2 != 0) { + pdu[4 + 2 * i] = 'F'; + pdu[4 + 2 * i + 1] = addr[2 * i]; + } + } + + return _pdu_len; +} + +int gsm_addr_dec(char *pdu, int pdu_len, char *addr, int addr_size, int *addr_len, uint8_t *addr_type) { + int _pdu_len; + + if (pdu_len < 4) return GSM_ERR; + + *addr_len = pdu_getc(pdu); + *addr_type = pdu_getc(pdu + 2); + + if (!(*addr_type & GSM_EXT)) return GSM_ERR; + + _pdu_len = 4 + DIVC(*addr_len, 2) * 2; + if (pdu_len < _pdu_len) return GSM_ERR; + + if ((*addr_type & GSM_TON) == GSM_TON_ALPHANUMERIC) { + *addr_len = (*addr_len * 4) / 7; + if (addr_size < *addr_len) return GSM_ERR; + + gsm_7bit_dec(pdu + 4, addr, *addr_len, 0); + } else { + int i; + int _addr_len = *addr_len; + + if (*addr_type & GSM_TON_INTERNATIONAL) { + addr[0] = '+'; + addr++; + (*addr_len)++; + } + if (addr_size < *addr_len) return GSM_ERR; + + for (i=0; i<_addr_len / 2; i++) { + addr[2 * i] = pdu[4 + 2 * i + 1]; + addr[2 * i + 1] = pdu[4 + 2 * i]; + } + if (_addr_len % 2 != 0) { + addr[2 * i] = pdu[4 + 2 * i + 1]; + } + } + + return _pdu_len; +} + +int gsm_sms_enc(uint8_t pid, char *addr, int addr_len, uint8_t addr_type, uint8_t *udh, int udh_len, uint8_t *msg, int msg_len, uint8_t enc, uint16_t flags, char *pdu, int pdu_size) { + int rv, _pdu_len = 0; + uint8_t mti = GSM_MTI_SUBMIT; + uint8_t dcs = 0; + uint8_t udl; + + if (udh_len) mti |= GSM_UDHI; + + if (pdu_size < 4) return GSM_ERR; + pdu_putc(mti, pdu); + pdu_putc(00, pdu + 2); + _pdu_len += 4; + + rv = gsm_addr_enc(addr, addr_len, addr_type, pdu + _pdu_len, pdu_size - _pdu_len); + if (rv < 0) return rv; + _pdu_len += rv; + + if (pdu_size < _pdu_len + 4) return GSM_ERR; + gsm_dcs_enc(enc, flags, &dcs); + pdu_putc(pid, pdu + _pdu_len); + pdu_putc(dcs, pdu + _pdu_len + 2); + _pdu_len += 4; + + if (enc == GSM_ENC_7BIT) { + int udh_blen = 0; + int padb = 0; + + if (udh_len) { + udh_blen = 8 * (udh_len + 1); + padb = DIVC(udh_blen, 7) * 7 - udh_blen; + } + udl = DIVC(udh_blen, 7) + msg_len; + + if (pdu_size < _pdu_len + (DIVC(udl * 7, 8) + 1) * 2) return GSM_ERR; + pdu_putc(udl, pdu + _pdu_len); + _pdu_len += 2; + + if (udh_len) { + pdu_putc(udh_len, pdu + _pdu_len); + pdu_puts(udh, udh_len, pdu + _pdu_len + 2); + _pdu_len += (udh_len + 1) * 2; + } + + rv = gsm_7bit_enc((char *)msg, msg_len, pdu + _pdu_len, padb); + if (rv < 0) return rv; + _pdu_len += rv; + } else { + udl = msg_len + (udh_len ? udh_len + 1 : 0); + + if (pdu_size < _pdu_len + (udl + 1) * 2) return GSM_ERR; + pdu_putc(udl, pdu + _pdu_len); + _pdu_len += 2; + + if (udh_len) { + pdu_putc(udh_len, pdu + _pdu_len); + pdu_puts(udh, udh_len, pdu + _pdu_len + 2); + _pdu_len += (udh_len + 1) * 2; + } + + pdu_puts(msg, msg_len, pdu + _pdu_len); + _pdu_len += msg_len * 2; + } + + return _pdu_len; +} + +int gsm_sms_dec(char *pdu, int pdu_len, uint8_t *pid, char *addr, int addr_size, int *addr_len, uint8_t *addr_type, uint8_t *udh, int udh_size, int *udh_len, uint8_t *msg, int msg_size, int *msg_len, char *ts, uint8_t *enc, uint16_t *flags) { + int rv, _pdu_len = 0; + uint8_t mti; + uint8_t dcs; + uint8_t udl; + + if (pdu_len < 2) return GSM_ERR; + mti = pdu_getc(pdu); + _pdu_len += 2; + if ((mti & GSM_MTI) != GSM_MTI_DELIVER) return GSM_ERR; + + rv = gsm_addr_dec(pdu + _pdu_len, pdu_len - _pdu_len, addr, addr_size, addr_len, addr_type); + if (rv < 0) return rv; + _pdu_len += rv; + + if (pdu_len < _pdu_len + 4) return GSM_ERR; + *pid = pdu_getc(pdu + _pdu_len); + dcs = pdu_getc(pdu + _pdu_len + 2); + _pdu_len += 4; + gsm_dcs_dec(dcs, enc, flags); + + rv = gsm_ts_dec(pdu + _pdu_len, pdu_len - _pdu_len, ts); + if (rv < 0) return rv; + _pdu_len += rv; + + if (pdu_len < _pdu_len + 2) return GSM_ERR; + udl = pdu_getc(pdu + _pdu_len); + _pdu_len += 2; + + if ((mti & GSM_UDHI) && (udl == 0)) return GSM_ERR; + *udh_len = 0; + + if (*enc == GSM_ENC_7BIT) { + int udh_blen = 0; + int padb = 0; + + if (pdu_len < _pdu_len + DIVC(udl * 7, 8) * 2) return GSM_ERR; + + if (mti & GSM_UDHI) { + *udh_len = pdu_getc(pdu + _pdu_len); + udh_blen = 8 * (*udh_len + 1); + padb = DIVC(udh_blen, 7) * 7 - udh_blen; + + if (udl * 7 < udh_blen) return GSM_ERR; + if (udh_size < *udh_len) return GSM_ERR; + + pdu_gets(pdu + _pdu_len + 2, udh, *udh_len); + _pdu_len += (*udh_len + 1) * 2; + } else { + *udh_len = 0; + } + + *msg_len = udl - DIVC(udh_blen, 7); + if (msg_size < *msg_len) return GSM_ERR; + + rv = gsm_7bit_dec(pdu + _pdu_len, (char *)msg, *msg_len, padb); + if (rv < 0) return rv; + _pdu_len += rv; + } else { + if (pdu_len < _pdu_len + udl * 2) return GSM_ERR; + + if (mti & GSM_UDHI) { + *udh_len = pdu_getc(pdu + _pdu_len); + + if (udl < *udh_len + 1) return GSM_ERR; + if (udh_size < *udh_len) return GSM_ERR; + + pdu_gets(pdu + _pdu_len + 2, udh, *udh_len); + _pdu_len += (*udh_len + 1) * 2; + } else { + *udh_len = 0; + } + + *msg_len = udl - (*udh_len ? *udh_len + 1 : 0); + if (msg_size < *msg_len) return GSM_ERR; + + pdu_gets(pdu + _pdu_len, msg, *msg_len); + _pdu_len += *msg_len * 2; + } + + return _pdu_len; +} diff --git a/code/esp32/components/eos/gsm_cp.c b/code/esp32/components/eos/gsm_cp.c new file mode 100644 index 0000000..3ab98c5 --- /dev/null +++ b/code/esp32/components/eos/gsm_cp.c @@ -0,0 +1,109 @@ +#include <stdint.h> + +#include "gsm.h" + +#define UCS2_SUPL_SIZE 11 + +static const uint16_t gsm7_to_ucs2[128] = { + 0x0040, 0x00a3, 0x0024, 0x00a5, 0x00e8, 0x00e9, 0x00f9, 0x00ec, 0x00f2, 0x00c7, 0x000a, 0x00d8, 0x00f8, 0x000d, 0x00c5, 0x00e5, + 0x0394, 0x005f, 0x03a6, 0x0393, 0x039b, 0x03a9, 0x03a0, 0x03a8, 0x03a3, 0x0398, 0x039e, 0x001b, 0x00c6, 0x00e6, 0x00df, 0x00c9, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00a1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00d1, 0x00dc, 0x00a7, + 0x00bf, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00f1, 0x00fc, 0x00e0 +}; + +static const uint16_t gsm7e_to_ucs2[128] = { + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x000c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x005e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x007b, 0x007d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x005c, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x005b, 0x007e, 0x005d, 0xffff, + 0x007c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x20ac, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff +}; + +static const uint16_t ucs2_to_gsm7[256] = { + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x000a, 0xffff, 0x1b0a, 0x000d, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x001b, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0002, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0000, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x1b3c, 0x1b2f, 0x1b3e, 0x1b14, 0x0011, + 0xffff, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x1b28, 0x1b40, 0x1b29, 0x1b3d, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x0040, 0xffff, 0x0001, 0x0024, 0x0003, 0xffff, 0x005f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0060, + 0xffff, 0xffff, 0xffff, 0xffff, 0x005b, 0x000e, 0x001c, 0x0009, 0xffff, 0x001f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x005d, 0xffff, 0xffff, 0xffff, 0xffff, 0x005c, 0xffff, 0x000b, 0xffff, 0xffff, 0xffff, 0x005e, 0xffff, 0xffff, 0x001e, + 0x007f, 0xffff, 0xffff, 0xffff, 0x007b, 0x000f, 0x001d, 0xffff, 0x0004, 0x0005, 0xffff, 0xffff, 0x0007, 0xffff, 0xffff, 0xffff, + 0xffff, 0x007d, 0x0008, 0xffff, 0xffff, 0xffff, 0x007c, 0xffff, 0x000c, 0x0006, 0xffff, 0xffff, 0x007e, 0xffff, 0xffff, 0xffff +}; + +static const uint16_t ucs2_to_gsm7_supl[UCS2_SUPL_SIZE][2] = { + {0x0394, 0x10}, + {0x03a6, 0x12}, + {0x0393, 0x13}, + {0x039b, 0x14}, + {0x03a9, 0x15}, + {0x03a0, 0x16}, + {0x03a8, 0x17}, + {0x03a3, 0x18}, + {0x0398, 0x19}, + {0x039e, 0x1a}, + {0x20ac, 0x1b65} +}; + +int gsm_ucs2_to_7bit(uint16_t ucs2, char *gsm7, int gsm7_size) { + uint16_t ch = 0xffff; + int ret = 0; + + if (gsm7_size < 1) return GSM_ERR; + + if (ucs2 < 256) { + ch = ucs2_to_gsm7[ucs2]; + } else { + int i; + + for (i=0; i<UCS2_SUPL_SIZE; i++) { + if (ucs2_to_gsm7_supl[i][0] == ucs2) { + ch = ucs2_to_gsm7_supl[i][1]; + break; + } + } + } + if (ch == 0xffff) return GSM_ERR; + if (ch & 0xff00) { + if (gsm7_size < 2) return GSM_ERR; + *gsm7 = 0x1b; + gsm7++; + ret++; + } + *gsm7 = ch & 0x7f; + ret++; + + return ret; +} + +int gsm_7bit_to_ucs2(char *gsm7, int gsm7_len, uint16_t *ucs2) { + int ret; + + if (gsm7_len < 1) return GSM_ERR; + if (*gsm7 != 0x1b) { + *ucs2 = gsm7_to_ucs2[*gsm7 & 0x7f]; + ret = 1; + } else { + if (gsm7_len < 2) return GSM_ERR; + gsm7++; + ret = 2; + *ucs2 = gsm7e_to_ucs2[*gsm7 & 0x7f]; + } + if (*ucs2 == 0xffff) return GSM_ERR; + + return ret; +} diff --git a/code/esp32/components/eos/include/gsm.h b/code/esp32/components/eos/include/gsm.h new file mode 100644 index 0000000..2c4f7b4 --- /dev/null +++ b/code/esp32/components/eos/include/gsm.h @@ -0,0 +1,117 @@ +#define GSM_OK 0 +#define GSM_ERR -1 + +/* Message-Type-Indicator */ +#define GSM_MTI 0x03 +#define GSM_MTI_DELIVER 0x00 +#define GSM_MTI_DELIVER_REPORT 0x00 +#define GSM_MTI_SUBMIT 0x01 +#define GSM_MTI_SUBMIT_REPORT 0x01 +#define GSM_MTI_COMMAND 0x02 +#define GSM_MTI_COMMAND_REPORT 0x02 + +#define GSM_MMS 0x04 /* More-Messages-to-Send */ +#define GSM_RD 0x04 /* Reject-Duplicates */ +#define GSM_LP 0x08 /* Loop-Prevention */ + +/* Validity-Period-Format */ +#define GSM_VPF 0x18 +#define GSM_VPF_NONE 0x00 +#define GSM_VPF_ENHANCED 0x08 +#define GSM_VPF_RELATIVE 0x10 +#define GSM_VPF_ABSOLUTE 0x18 + +#define GSM_SRI 0x20 /* Status-Report-Indication */ +#define GSM_SRR 0x20 /* Status-Report-Request */ +#define GSM_SRQ 0x20 /* Status-Report-Qualifier */ +#define GSM_UDHI 0x40 /* User-Data-Header-Indicator */ +#define GSM_RP 0x80 /* Reply-Path */ + +/* Type-of-Number */ +#define GSM_TON 0x70 +#define GSM_TON_UNKNOWN 0x00 +#define GSM_TON_INTERNATIONAL 0x10 +#define GSM_TON_NATIONAL 0x20 +#define GSM_TON_NETWORK 0x30 +#define GSM_TON_SUBSCRIBER 0x40 +#define GSM_TON_ALPHANUMERIC 0x50 +#define GSM_TON_ABBRREVIATED 0x60 + +/* Numbering-Plan-Identification */ +#define GSM_NPI 0x0f +#define GSM_NPI_UNKNOWN 0x00 +#define GSM_NPI_TELEPHONE 0x01 +#define GSM_NPI_DATA 0x03 +#define GSM_NPI_TELEX 0x04 +#define GSM_NPI_SCS1 0x05 +#define GSM_NPI_SCS2 0x06 +#define GSM_NPI_NATIONAL 0x08 +#define GSM_NPI_PRIVATE 0x09 +#define GSM_NPI_ERMES 0x0a + +#define GSM_EXT 0x80 + +/* Protocol-Identifier */ +#define GSM_PID_DEFAULT 0 +#define GSM_PID_TYPE0 64 + +/* Data-Coding-Scheme */ +#define GSM_DCS_CLASS 0x03 +#define GSM_DCS_ENC 0x0c + +#define GSM_DCS_CLASS_IND 0x10 +#define GSM_DCS_COMPRESS_IND 0x20 +#define GSM_DCS_DELETE_IND 0x40 +#define GSM_DCS_GENERAL_IND 0x80 +#define GSM_DCS_GROUP 0xf0 + +#define GSM_DCS_MWI_DISCARD 0xc0 +#define GSM_DCS_MWI_STORE_GSM7 0xd0 +#define GSM_DCS_MWI_STORE_UCS2 0xe0 +#define GSM_DCS_MWI_SENSE 0x08 +#define GSM_DCS_MWI_TYPE 0x03 + +#define GSM_DCS_ENCLASS 0xf0 +#define GSM_DCS_ENCLASS_ENC 0x04 + +/* Parameter-Indicator */ +#define GSM_PI_PID 0x01 +#define GSM_PI_DCS 0x02 +#define GSM_PI_UD 0x04 +#define GSM_PI_EXT 0x08 + +/* character set */ +#define GSM_ENC_7BIT 0x00 +#define GSM_ENC_8BIT 0x04 +#define GSM_ENC_UCS2 0x08 + +/* message waiting indication */ +#define GSM_MWI_TYPE_VOICEMAIL 0x00 +#define GSM_MWI_TYPE_FAX 0x01 +#define GSM_MWI_TYPE_EMAIL 0x02 +#define GSM_MWI_TYPE_OTHER 0x03 + +/* flags */ +#define GSM_FLAG_COMPRESS 0x0001 +#define GSM_FLAG_DELETE 0x0002 +#define GSM_FLAG_DISCARD 0x0004 + +/* message class */ +#define GSM_FLAG_CLASS 0x0400 +#define GSM_FLAG_CLASS0 0x0000 /* Flash */ +#define GSM_FLAG_CLASS1 0x0100 /* ME-specific */ +#define GSM_FLAG_CLASS2 0x0200 /* (U)SIM-specific */ +#define GSM_FLAG_CLASS4 0x0300 /* TE-specific */ +#define GSM_FLAG_CLASS_MASK 0x0f00 + +/* message waiting indication */ +#define GSM_FLAG_MWI 0x4000 +#define GSM_FLAG_MWI_SENSE 0x8000 +#define GSM_FLAG_MWI_VOICEMAIL 0x0000 +#define GSM_FLAG_MWI_FAX 0x1000 +#define GSM_FLAG_MWI_EMAIL 0x2000 +#define GSM_FLAG_MWI_OTHER 0x3000 +#define GSM_FLAG_MWI_MASK 0xf000 + +int gsm_7bit_enc(char *text, int text_len, char *pdu, int padb); +int gsm_7bit_dec(char *pdu, char *text, int text_len, int padb); |