From cf7c06297d04bade9cd04c056f9ed510e64dd7bd Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 5 Aug 2020 03:39:22 +0200 Subject: code -> fw --- fw/esp32/components/eos/gsm.c | 453 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 453 insertions(+) create mode 100644 fw/esp32/components/eos/gsm.c (limited to 'fw/esp32/components/eos/gsm.c') diff --git a/fw/esp32/components/eos/gsm.c b/fw/esp32/components/eos/gsm.c new file mode 100644 index 0000000..788722e --- /dev/null +++ b/fw/esp32/components/eos/gsm.c @@ -0,0 +1,453 @@ +#include +#include +#include + +#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> 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