#include #include #include #include #include "eos.h" #include "net.h" #include "at_cmd.h" #include "cell.h" static const char *TAG = "EOS CELL USSD"; extern char *at_cmd_buf; void eos_cell_ussd_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { unsigned char mtype; unsigned char *buffer = msg->buffer; int rv; if (len < 1) return; mtype = buffer[0] & ~EOS_CELL_MTYPE_MASK; buffer++; len--; switch (mtype) { case EOS_CELL_MTYPE_USSD_REQUEST: { if (len > EOS_CELL_USSD_SIZE_REQ) break; rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CUSD=1,\"%.*s\",15\r", len, buffer); if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) break; rv = eos_modem_take(1000); if (rv) break; 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) break; 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[]) { EOSMessage msg; uint16_t len; char *rbuf; size_t rlen; int rep, rv; sscanf(urc + m[1].rm_so, "%1d", &rep); eos_net_alloc(&msg); if (msg.size < 2) { eos_net_free(&msg); return; } msg.buffer[0] = EOS_CELL_MTYPE_USSD | EOS_CELL_MTYPE_USSD_REPLY; msg.buffer[1] = rep; len = 2; if (m[2].rm_so == -1) { rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, len); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); return; } rbuf = (char *)msg.buffer + len; rlen = m[2].rm_eo - m[2].rm_so - 2; if (msg.size < rlen + len + 1) { eos_net_free(&msg); return; } memcpy(rbuf, urc + m[2].rm_so + 2, rlen); rbuf[rlen] = '\0'; rv = EOS_OK; do { char *end; end = strchr(rbuf, '"'); if (end) { len += end - rbuf; break; } else { rlen = strlen(rbuf); rbuf[rlen] = '\n'; rbuf += rlen + 1; len += rlen + 1; } rv = eos_modem_readln(rbuf, msg.size - len, 1000); if (rv) break; } while (1); if (rv) { ESP_LOGE(TAG, "ERROR"); eos_net_free(&msg); return; } rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, len); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } void eos_cell_ussd_init(void) { int rv; rv = at_urc_insert("^\\+CUSD: ([0-9])(,\".*)?", ussd_reply_handler, REG_EXTENDED); assert(rv == EOS_OK); }