#include #include #include #include #include #include #include #include #include "eos.h" #include "msgq.h" #include "net.h" #include "cell.h" #define CELL_SIZE_QUEUE 2 static const char *TAG = "EOS CELL"; static EOSBufQ cell_buf_q; static unsigned char *cell_bufq_array[CELL_SIZE_QUEUE]; static SemaphoreHandle_t mutex; static QueueHandle_t cell_queue; static void _cell_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]; switch (mtype & EOS_CELL_MTYPE_MASK) { case EOS_CELL_MTYPE_DEV: { switch (mtype & ~EOS_CELL_MTYPE_MASK) { case EOS_CELL_MTYPE_STATUS: { size_t _rv; if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) break; if (msg->size < 3) break; _rv = eos_modem_get_status(buffer + 1); eos_net_reply(EOS_NET_MTYPE_CELL, msg, _rv + 1); break; } case EOS_CELL_MTYPE_RESET: { rv = eos_modem_take(1000); if (rv) { ESP_LOGE(TAG, "Reset modem failed: %d", rv); break; } eos_modem_reset(); eos_modem_give(); break; } case EOS_CELL_MTYPE_UART_TAKE: { if (eos_modem_get_mode() == EOS_CELL_UART_MODE_ATCMD) { rv = eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY); if (rv) ESP_LOGE(TAG, "Set RELAY mode failed: %d", rv); } break; } case EOS_CELL_MTYPE_UART_GIVE: { if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) { rv = eos_modem_take(1000); if (!rv) { eos_modem_atinit(); eos_modem_give(); } rv = eos_modem_set_mode(EOS_CELL_UART_MODE_ATCMD); if (rv) ESP_LOGE(TAG, "Set ATCMD mode failed: %d", rv); } break; } case EOS_CELL_MTYPE_UART_DATA: { if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) { eos_modem_write(buffer + 1, len - 1); } break; } } break; } case EOS_CELL_MTYPE_VOICE: { eos_cell_voice_handler(_mtype, msg, len); break; } case EOS_CELL_MTYPE_SMS: { eos_cell_sms_handler(_mtype, msg, len); break; } case EOS_CELL_MTYPE_USSD: { eos_cell_ussd_handler(_mtype, msg, len); break; } case EOS_CELL_MTYPE_PDP: { eos_cell_pdp_handler(_mtype, msg, len); break; } } } static void cell_handler_task(void *pvParameters) { EOSMessage msg; EOSMsgItem mi; while (1) { if (xQueueReceive(cell_queue, &mi, portMAX_DELAY)) { eos_msg_init(&msg, mi.buffer, mi.size); _cell_handler(mi.type, &msg, mi.len); xSemaphoreTake(mutex, portMAX_DELAY); eos_bufq_push(&cell_buf_q, mi.buffer); xSemaphoreGive(mutex); } } vTaskDelete(NULL); } static void cell_handler(unsigned char type, EOSMessage *msg, uint16_t len) { EOSMsgItem mi; unsigned char *buffer; if (len < 1) return; if (len > EOS_CELL_MTU) return; if (eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ) { _cell_handler(type, msg, len); return; } xSemaphoreTake(mutex, portMAX_DELAY); buffer = eos_bufq_pop(&cell_buf_q); xSemaphoreGive(mutex); if (buffer == NULL) { ESP_LOGE(TAG, "CELL MESSAGE NOT HANDLED: %2x", msg->buffer[0]); return; } mi.type = type; mi.buffer = buffer; mi.size = EOS_CELL_MTU; memcpy(mi.buffer, msg->buffer, len); mi.len = len; xQueueSend(cell_queue, &mi, portMAX_DELAY); } void eos_cell_init(void) { int i; eos_bufq_init(&cell_buf_q, cell_bufq_array, CELL_SIZE_QUEUE); for (i=0; i