diff options
Diffstat (limited to 'fw/esp32/components/eos/cell_ussd.c')
-rw-r--r-- | fw/esp32/components/eos/cell_ussd.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/fw/esp32/components/eos/cell_ussd.c b/fw/esp32/components/eos/cell_ussd.c new file mode 100644 index 0000000..195feaf --- /dev/null +++ b/fw/esp32/components/eos/cell_ussd.c @@ -0,0 +1,103 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <esp_log.h> + +#include "eos.h" +#include "net.h" +#include "at_cmd.h" +#include "cell.h" + +static const char *TAG = "EOS USSD"; + +static char cmd[256]; +static int cmd_len; + +void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t size) { + int rv; + + buffer += 1; + size -= 1; + switch (mtype) { + case EOS_CELL_MTYPE_USSD_REQUEST: + if (size == 0) return; + + buffer[size] = '\0'; + cmd_len = snprintf(cmd, sizeof(cmd), "AT+CUSD=1,\"%s\",15\r", buffer); + if ((cmd_len < 0) || (cmd_len >= sizeof(cmd))) return; + + rv = eos_modem_take(1000); + if (rv) return; + + at_cmd(cmd); + rv = at_expect("^OK", "^ERROR", 1000); + + eos_modem_give(); + break; + + case EOS_CELL_MTYPE_USSD_CANCEL: + rv = eos_modem_take(1000); + if (rv) return; + + at_cmd("AT+CUSD=2\r"); + rv = at_expect("^OK", "^ERROR", 1000); + + eos_modem_give(); + break; + } + +} + +static void ussd_reply_handler(char *urc, regmatch_t m[]) { + int rep, rv; + unsigned char *buf; + uint16_t len; + char *_buf; + size_t _len; + regex_t re; + regmatch_t match[2]; + + rv = regcomp(&re, ".*(\",[0-9]+)$", REG_EXTENDED); + if (rv) return; + + sscanf(urc + m[1].rm_so, "%1d", &rep); + + buf = eos_net_alloc(); + buf[0] = EOS_CELL_MTYPE_USSD | EOS_CELL_MTYPE_USSD_REPLY; + buf[1] = rep; + len = 2; + + rv = EOS_OK; + _buf = (char *)buf + len; + strcpy(_buf, urc + m[2].rm_so); + do { + if (regexec(&re, _buf, 2, match, 0) == 0) { + ESP_LOGI(TAG, "MATCH:%ld %s", match[1].rm_so, _buf); + _buf[match[1].rm_so] = '\0'; + _len = strlen(_buf); + len += _len + 1; + break; + } else { + _len = strlen(_buf); + _buf[_len] = '\n'; + _buf += _len + 1; + len += _len + 1; + } + rv = eos_modem_readln(_buf, EOS_NET_MTU - len, 1000); + if (rv) break; + } while (1); + + if (rv) { + ESP_LOGE(TAG, "USSD error"); + eos_net_free(buf); + } else { + eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + } + regfree(&re); +} + +void eos_cell_ussd_init(void) { + at_urc_insert("\\+CUSD: ([0-9]),\"(.*)", ussd_reply_handler, REG_EXTENDED); + +}
\ No newline at end of file |