#include #include #include #include #include "eos.h" #include "net.h" #include "at_cmd.h" #include "cell.h" static const char *TAG = "EOS USSD"; extern char *at_cmd_buf; void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { int rv; buffer++; buf_len--; switch (mtype) { case EOS_CELL_MTYPE_USSD_REQUEST: { if (buf_len > EOS_CELL_USSD_SIZE_REQ) return; buffer[buf_len] = '\0'; rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CUSD=1,\"%s\",15\r", buffer); if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; rv = eos_modem_take(1000); if (rv) return; at_cmd(at_cmd_buf); 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; 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; if (m[2].rm_so == -1) { eos_net_send(EOS_NET_MTYPE_CELL, buf, len); return; } _buf = (char *)buf + len; _len = m[2].rm_eo - m[2].rm_so - 2; if (_len > EOS_NET_SIZE_BUF - len) { eos_net_free(buf); return; } memcpy(_buf, urc + m[2].rm_so + 2, _len); len += _len; rv = EOS_OK; do { char *end; end = strchr(_buf, '"'); if (end) { len += end - _buf; break; } else { _len = strlen(_buf); _buf[_len] = '\n'; _buf += _len + 1; len += _len + 1; } rv = eos_modem_readln(_buf, EOS_NET_SIZE_BUF - len, 1000); if (rv) break; } while (1); if (rv) { ESP_LOGE(TAG, "error"); eos_net_free(buf); return; } eos_net_send(EOS_NET_MTYPE_CELL, buf, len); } void eos_cell_ussd_init(void) { at_urc_insert("^\\+CUSD: ([0-9])(,\".*)?", ussd_reply_handler, REG_EXTENDED); }