diff options
Diffstat (limited to 'fw/esp32/components/eos/net.c')
| -rw-r--r-- | fw/esp32/components/eos/net.c | 383 |
1 files changed, 208 insertions, 175 deletions
diff --git a/fw/esp32/components/eos/net.c b/fw/esp32/components/eos/net.c index 0ba2a2d..dd3180a 100644 --- a/fw/esp32/components/eos/net.c +++ b/fw/esp32/components/eos/net.c @@ -27,60 +27,77 @@ #define SPI_GPIO_SCLK 38 #define SPI_GPIO_CS 8 -#define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 4) -#define SPI_SIZE_HDR 3 - #define SPI_HOST SPI3_HOST +#define NET_SIZE_BUFQ 8 +#define NET_SIZE_SNDQ 8 + +#define NET_SIZE_HDR 3 +#define NET_SIZE_BUF (EOS_NET_MTU + 4) + +// #define EOS_DEBUG 1 + static EOSBufQ net_buf_q; -static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; +static unsigned char *net_bufq_array[NET_SIZE_BUFQ]; static EOSMsgQ net_send_q; -static EOSMsgItem net_sndq_array[EOS_NET_SIZE_SNDQ]; +static EOSMsgItem net_sndq_array[NET_SIZE_SNDQ]; static NETConfig net_config; static eos_net_handler_t net_handler[EOS_NET_MAX_MTYPE]; static spi_bus_config_t net_spi_bus_cfg; static spi_slave_interface_config_t net_spi_iface_cfg; -static spi_slave_transaction_t net_spi_tr_cfg; static const char *TAG = "EOS NET"; -static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - ESP_LOGE(TAG, "bad handler: 0x%.2X len: %d", mtype, buf_len); +static void bad_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { + ESP_LOGE(TAG, "BAD HANDLER: 0x%.2X LEN: %d", mtype, len); +} + +static void IRAM_ATTR net_bridge(unsigned char mtype, EOSMessage *msg, uint16_t len) { + EOSMessage _msg; + int rv; + + eos_app_alloc(&_msg); + if (len > _msg.size) { + eos_app_free(&_msg); + return; + } + memcpy(_msg.buffer, msg->buffer, len); + rv = eos_app_send(mtype & EOS_NET_MTYPE_MASK, &_msg, len); + if (rv) ESP_LOGE(TAG, "BRIDGE ERR: %d", rv); } -static void net_msg_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +static void IRAM_ATTR net_msg_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { uint8_t idx; - idx = mtype & EOS_NET_MTYPE_MASK; - if (idx && (idx <= EOS_NET_MAX_MTYPE) && (buf_len <= EOS_NET_MTU)) { - net_handler[idx - 1](mtype, buffer, buf_len); + idx = mtype & EOS_NET_MTYPE_FLAG_BRIDGE ? EOS_NET_MTYPE_BRIDGE : mtype & EOS_NET_MTYPE_MASK; + if ((idx < EOS_NET_MAX_MTYPE) && (len <= msg->size)) { + net_handler[idx](mtype, msg, len); } else { - bad_handler(mtype, buffer, buf_len); + bad_handler(mtype, msg, len); } } /* Called after a transaction is queued and ready for pickup by master */ -static void _post_setup_cb(spi_slave_transaction_t *trans) { +static void IRAM_ATTR _post_setup_cb(spi_slave_transaction_t *trans) { NETConfig *config = trans->user; gpio_set_level(config->gpio_cts, 0); } /* Called after transaction is sent/received */ -static void _post_trans_cb(spi_slave_transaction_t *trans) { +static void IRAM_ATTR _post_trans_cb(spi_slave_transaction_t *trans) { NETConfig *config = trans->user; gpio_set_level(config->gpio_cts, 1); } -static void net_goto_sleep(NETConfig *config) { +static void net_sleep(NETConfig *config) { esp_err_t ret; uint8_t msgq_len; - xSemaphoreTake(config->mutex, portMAX_DELAY); msgq_len = eos_msgq_len(config->send_q); if (msgq_len) { @@ -93,13 +110,12 @@ static void net_goto_sleep(NETConfig *config) { ret = spi_slave_free(config->spi_host); assert(ret == ESP_OK); - /* for deep sleep */ - gpio_hold_en(config->gpio_cts); - eos_power_sleep_rdy(config->dev); - vTaskSuspend(NULL); +} - gpio_hold_dis(config->gpio_cts); +static void net_wake(NETConfig *config) { + esp_err_t ret; + uint8_t msgq_len; ret = spi_slave_initialize(config->spi_host, config->spi_bus_cfg, config->spi_iface_cfg, SPI_DMA_CH_AUTO); assert(ret == ESP_OK); @@ -115,180 +131,164 @@ static void net_goto_sleep(NETConfig *config) { xSemaphoreGive(config->mutex); } -void eos_net_xchg_task(void *param) { +void IRAM_ATTR eos_net_xchg_task(void *param) { NETConfig *config = param; - int present, skip_msg = 0, sleep_msg = 0; + int skip_msg = 0, sleep_msg = 0; unsigned char mtype = 0; unsigned char mtype_flags = 0; - unsigned char *buffer; - unsigned char *buf_send = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); - unsigned char *buf_recv = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); - uint16_t buf_len; + unsigned char *snd_buf; + unsigned char *rcv_buf; + EOSMessage msg; + uint16_t snd_buf_len, rcv_buf_len; size_t trans_len; spi_bus_config_t *spi_bus_cfg = config->spi_bus_cfg; spi_slave_interface_config_t *spi_iface_cfg = config->spi_iface_cfg; - spi_slave_transaction_t *spi_tr_cfg = config->spi_tr_cfg; + spi_slave_transaction_t _spi_tr_cfg, *spi_tr_cfg; esp_err_t ret; - assert(buf_send != NULL); - assert(buf_recv != NULL); + if (!config->present) { + vTaskDelete(NULL); + return; + } - /* Configuration for the SPI bus */ - spi_bus_cfg->mosi_io_num = config->gpio_mosi; - spi_bus_cfg->miso_io_num = config->gpio_miso; - spi_bus_cfg->sclk_io_num = config->gpio_sclk; + snd_buf = spi_bus_dma_memory_alloc(config->spi_host, NET_SIZE_BUF, MALLOC_CAP_DMA); + assert(snd_buf != NULL); + + rcv_buf = spi_bus_dma_memory_alloc(config->spi_host, NET_SIZE_BUF, MALLOC_CAP_DMA); + assert(rcv_buf != NULL); + + memset(&_spi_tr_cfg, 0, sizeof(_spi_tr_cfg)); + spi_tr_cfg = &_spi_tr_cfg; - /* Configuration for the SPI slave interface */ - spi_iface_cfg->mode = 0; - spi_iface_cfg->spics_io_num = config->gpio_cs; - spi_iface_cfg->queue_size = 2; - spi_iface_cfg->flags = 0; spi_iface_cfg->post_setup_cb = _post_setup_cb; spi_iface_cfg->post_trans_cb = _post_trans_cb; - spi_tr_cfg->tx_buffer = buf_send; - spi_tr_cfg->rx_buffer = buf_recv; - spi_tr_cfg->length = SPI_SIZE_BUF * 8; + spi_tr_cfg->tx_buffer = snd_buf; + spi_tr_cfg->rx_buffer = rcv_buf; + spi_tr_cfg->length = NET_SIZE_BUF * 8; spi_tr_cfg->user = config; - xSemaphoreTake(config->mutex, portMAX_DELAY); - present = config->present; - xSemaphoreGive(config->mutex); - if (!present) { + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + _eos_net_deep_wake(config); vTaskSuspend(NULL); + net_wake(config); + } else { + ret = spi_slave_initialize(config->spi_host, spi_bus_cfg, spi_iface_cfg, SPI_DMA_CH_AUTO); + assert(ret == ESP_OK); } - /* Initialize SPI slave interface */ - ret = spi_slave_initialize(config->spi_host, spi_bus_cfg, spi_iface_cfg, SPI_DMA_CH_AUTO); - assert(ret == ESP_OK); - while (1) { if (!skip_msg) { + int msg_free; + xSemaphoreTake(config->mutex, portMAX_DELAY); - eos_msgq_pop(config->send_q, &mtype, &buffer, &buf_len); + msg_free = 0; + snd_buf_len = 0; + eos_msgq_pop(config->send_q, &mtype, &msg, &snd_buf_len); if (mtype) { - buf_send[0] = mtype; - buf_send[1] = buf_len >> 8; - buf_send[2] = buf_len & 0xFF; - if (buffer) { - memcpy(buf_send + SPI_SIZE_HDR, buffer, buf_len); - xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); - eos_bufq_push(config->buf_q, buffer); - xSemaphoreGive(config->bufq_mutex); - xSemaphoreGive(config->bufq_semaph); +#ifdef EOS_DEBUG + ESP_LOGI(TAG, "SEND:0x%.2X DEV:0x%.8lX LEN:%d", mtype, config->dev, snd_buf_len); +#endif + snd_buf[0] = mtype; + snd_buf[1] = snd_buf_len >> 8; + snd_buf[2] = snd_buf_len & 0xFF; + if (msg.buffer) { + memcpy(snd_buf + NET_SIZE_HDR, msg.buffer, snd_buf_len); + msg_free = 1; } } else if (!sleep_msg && config->sleep_req) { - buf_send[0] = EOS_NET_MTYPE_SLEEP; - buf_send[1] = 0; - buf_send[2] = 0; + snd_buf[0] = EOS_NET_MTYPE_SLEEP; + snd_buf[1] = 0; + snd_buf[2] = 0; sleep_msg = 1; config->sleep_req = 0; - if (config->dev == NET_DEV_NET) config->sleep = 1; + config->sleep = 1; } else { gpio_set_level(config->gpio_rts, 1); - buf_send[0] = 0; - buf_send[1] = 0; - buf_send[2] = 0; + snd_buf[0] = 0; + snd_buf[1] = 0; + snd_buf[2] = 0; } xSemaphoreGive(config->mutex); + + if (msg_free) _eos_net_free(config, &msg); } skip_msg = 0; - buf_recv[0] = 0; - buf_recv[1] = 0; - buf_recv[2] = 0; + rcv_buf[0] = 0; + rcv_buf[1] = 0; + rcv_buf[2] = 0; + ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); assert(ret == ESP_OK); trans_len = spi_tr_cfg->trans_len / 8; - ESP_LOGI(TAG, "RECV:0x%.2X DEV:0x%.8lX LEN:%d", buf_recv[0], config->dev, trans_len); +#ifdef EOS_DEBUG + ESP_LOGI(TAG, "RECV:0x%.2X DEV:0x%.8lX LEN:%d", rcv_buf[0], config->dev, trans_len); +#endif - if (sleep_msg && (config->dev == NET_DEV_NET)) { - net_goto_sleep(config); + if (sleep_msg) { + net_sleep(config); + vTaskSuspend(NULL); + net_wake(config); sleep_msg = 0; continue; } - if (trans_len < 1) { - ESP_LOGE(TAG, "RECV LEN:%d", trans_len); - continue; - } - /* SPI reset */ - if ((trans_len == 1) && (buf_recv[0] == 0)) { - if (buf_send[0]) skip_msg = 1; + if (trans_len < NET_SIZE_HDR) { + if (snd_buf[0]) skip_msg = 1; continue; } - mtype = buf_recv[0] & EOS_NET_MTYPE_MASK; - mtype_flags = buf_recv[0] & ~EOS_NET_MTYPE_MASK; - if (buf_send[0] && (mtype_flags & EOS_NET_MTYPE_FLAG_ONEW)) { + mtype = rcv_buf[0] & EOS_NET_MTYPE_MASK; + mtype_flags = rcv_buf[0] & ~EOS_NET_MTYPE_MASK; + if (snd_buf[0] && (mtype_flags & EOS_NET_MTYPE_FLAG_ONEW)) { skip_msg = 1; } + rcv_buf_len = (uint16_t)rcv_buf[1] << 8; + rcv_buf_len |= (uint16_t)rcv_buf[2] & 0xFF; + + if (snd_buf[0] && (trans_len < snd_buf_len + NET_SIZE_HDR) && !skip_msg) { + spi_tr_cfg->tx_buffer = snd_buf + trans_len; + spi_tr_cfg->rx_buffer = rcv_buf + trans_len; + spi_tr_cfg->length = (NET_SIZE_BUF - trans_len) * 8; - if (buf_send[0] && (trans_len < buf_len + SPI_SIZE_HDR) && !skip_msg) { - spi_tr_cfg->tx_buffer = buf_send + trans_len; - spi_tr_cfg->rx_buffer = buf_recv + trans_len; - spi_tr_cfg->length = (SPI_SIZE_BUF - trans_len) * 8; ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); assert(ret == ESP_OK); + trans_len += spi_tr_cfg->trans_len / 8; - spi_tr_cfg->tx_buffer = buf_send; - spi_tr_cfg->rx_buffer = buf_recv; - spi_tr_cfg->length = SPI_SIZE_BUF * 8; + spi_tr_cfg->tx_buffer = snd_buf; + spi_tr_cfg->rx_buffer = rcv_buf; + spi_tr_cfg->length = NET_SIZE_BUF * 8; } - if (mtype == 0) continue; - - if (mtype == EOS_NET_MTYPE_SLEEP) { - uint8_t mode; - - mode = EOS_PWR_SMODE_LIGHT; - - switch (config->dev) { - case NET_DEV_NET: { - eos_power_sleep_req(mode, EOS_PWR_DEV_ALL); - break; - } - case NET_DEV_APP: { - uint8_t msgq_len; - - xSemaphoreTake(config->mutex, portMAX_DELAY); - msgq_len = eos_msgq_len(config->send_q); - if (msgq_len == 0) { - config->sleep = 1; - config->sleep_req = 0; - } - xSemaphoreGive(config->mutex); - if (msgq_len == 0) { - net_goto_sleep(config); - sleep_msg = 0; - } - break; - } - } + if (rcv_buf[0] == EOS_NET_MTYPE_SLEEP) { + eos_power_sleep_req(config->dev); continue; } - if (trans_len < SPI_SIZE_HDR) { - ESP_LOGE(TAG, "RECV LEN:%d", trans_len); - continue; - } - buf_len = (uint16_t)buf_recv[1] << 8; - buf_len |= (uint16_t)buf_recv[2] & 0xFF; - buffer = buf_recv + SPI_SIZE_HDR; - config->msg_handler(buf_recv[0], buffer, buf_len); + if (mtype == 0) continue; + + eos_msg_init(&msg, rcv_buf + NET_SIZE_HDR, EOS_NET_MTU); + if (mtype_flags & EOS_NET_MTYPE_FLAG_REPL) eos_msg_set_flags(&msg, EOS_MSG_FLAG_RPLY_REQ); + config->handler(rcv_buf[0], &msg, rcv_buf_len); - if (mtype_flags & EOS_NET_MTYPE_FLAG_REPL) { - spi_tr_cfg->tx_buffer = buf_recv; + if (eos_msg_flags(&msg) & EOS_MSG_FLAG_RPLY_REQ) { + if (!(eos_msg_flags(&msg) & EOS_MSG_FLAG_RPLY_REP)) { + // eos_net_reply(EOS_MTYPE_ERR, msg, 0); + } + spi_tr_cfg->tx_buffer = rcv_buf; spi_tr_cfg->rx_buffer = NULL; + ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); assert(ret == ESP_OK); - spi_tr_cfg->tx_buffer = buf_send; - spi_tr_cfg->rx_buffer = buf_recv; + + spi_tr_cfg->tx_buffer = snd_buf; + spi_tr_cfg->rx_buffer = rcv_buf; } } @@ -315,12 +315,12 @@ void eos_net_init(void) { SemaphoreHandle_t bufq_semaph; int i; - eos_msgq_init(&net_send_q, net_sndq_array, EOS_NET_SIZE_SNDQ); - eos_bufq_init(&net_buf_q, net_bufq_array, EOS_NET_SIZE_BUFQ); - for (i=0; i<EOS_NET_SIZE_BUFQ; i++) { + eos_msgq_init(&net_send_q, net_sndq_array, NET_SIZE_SNDQ); + eos_bufq_init(&net_buf_q, net_bufq_array, NET_SIZE_BUFQ); + for (i=0; i<NET_SIZE_BUFQ; i++) { unsigned char *buffer; - buffer = malloc(EOS_NET_SIZE_BUF); + buffer = malloc(EOS_NET_MTU); assert(buffer != NULL); eos_bufq_push(&net_buf_q, buffer); } @@ -333,38 +333,42 @@ void eos_net_init(void) { assert(mutex != NULL); bufq_mutex = xSemaphoreCreateBinary(); assert(bufq_mutex != NULL); - bufq_semaph = xSemaphoreCreateCounting(EOS_NET_SIZE_BUFQ, EOS_NET_SIZE_BUFQ); + bufq_semaph = xSemaphoreCreateCounting(NET_SIZE_BUFQ, NET_SIZE_BUFQ); assert(bufq_semaph != NULL); xSemaphoreGive(mutex); xSemaphoreGive(bufq_mutex); - net_config.sleep = 0; + net_config.sleep = esp_reset_reason() == ESP_RST_DEEPSLEEP ? 1 : 0; net_config.sleep_req = 0; net_config.present = 1; net_config.dev = NET_DEV_NET; - net_config.gpio_mosi = SPI_GPIO_MOSI; - net_config.gpio_miso = SPI_GPIO_MISO; - net_config.gpio_sclk = SPI_GPIO_SCLK; - net_config.gpio_cs = SPI_GPIO_CS; net_config.gpio_rts = SPI_GPIO_RTS; net_config.gpio_cts = SPI_GPIO_CTS; net_config.spi_host = SPI_HOST; net_config.spi_bus_cfg = &net_spi_bus_cfg; net_config.spi_iface_cfg = &net_spi_iface_cfg; - net_config.spi_tr_cfg = &net_spi_tr_cfg; net_config.mutex = mutex; net_config.bufq_mutex = bufq_mutex; net_config.bufq_semaph = bufq_semaph; net_config.buf_q = &net_buf_q; net_config.send_q = &net_send_q; - net_config.msg_handler = net_msg_handler; + net_config.handler = net_msg_handler; - _eos_net_init_gpio(&net_config); + /* Configuration for the SPI bus */ + net_spi_bus_cfg.mosi_io_num = SPI_GPIO_MOSI; + net_spi_bus_cfg.miso_io_num = SPI_GPIO_MISO; + net_spi_bus_cfg.sclk_io_num = SPI_GPIO_SCLK; + net_spi_bus_cfg.intr_flags = ESP_INTR_FLAG_IRAM; - if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { - gpio_hold_dis(net_config.gpio_cts); - } + /* Configuration for the SPI slave interface */ + net_spi_iface_cfg.mode = 0; + net_spi_iface_cfg.spics_io_num = SPI_GPIO_CS; + net_spi_iface_cfg.queue_size = 2; + net_spi_iface_cfg.flags = 0; + + _eos_net_init_gpio(&net_config); + eos_net_set_handler(EOS_NET_MTYPE_BRIDGE, net_bridge); ESP_LOGI(TAG, "INIT"); } @@ -378,57 +382,70 @@ void eos_net_run(void) { ESP_LOGI(TAG, "RUN"); } -unsigned char *_eos_net_alloc(NETConfig *config) { - unsigned char *ret; - +void _eos_net_alloc(NETConfig *config, EOSMessage *msg) { xSemaphoreTake(config->bufq_semaph, portMAX_DELAY); xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); - ret = eos_bufq_pop(config->buf_q); + msg->buffer = eos_bufq_pop(config->buf_q); + msg->size = EOS_NET_MTU; xSemaphoreGive(config->bufq_mutex); - - return ret; } -void _eos_net_free(NETConfig *config, unsigned char *buf) { +void _eos_net_free(NETConfig *config, EOSMessage *msg) { xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); - eos_bufq_push(config->buf_q, buf); + eos_bufq_push(config->buf_q, msg->buffer); xSemaphoreGive(config->bufq_semaph); xSemaphoreGive(config->bufq_mutex); } -unsigned char *eos_net_alloc(void) { - return _eos_net_alloc(&net_config); +void eos_net_alloc(EOSMessage *msg) { + _eos_net_alloc(&net_config, msg); } -void eos_net_free(unsigned char *buf) { - _eos_net_free(&net_config, buf); +void eos_net_free(EOSMessage *msg) { + _eos_net_free(&net_config, msg); } -int _eos_net_send(NETConfig *config, unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - int rv = EOS_OK; - int sleep; +int _eos_net_send(NETConfig *config, unsigned char mtype, EOSMessage *msg, uint16_t len) { + int wake, rv; + + wake = eos_msg_flags(msg) & EOS_MSG_FLAG_WAKE; + rv = EOS_OK; xSemaphoreTake(config->mutex, portMAX_DELAY); - sleep = config->sleep; - rv = eos_msgq_push(config->send_q, mtype, buffer, buf_len); - if (!rv && !sleep) gpio_set_level(config->gpio_rts, 0); + + if (!config->present) rv = EOS_ERR_NOTFOUND; + if (rv) goto net_send_fin; + + if (!wake && (config->sleep || config->sleep_req)) rv = EOS_ERR_BUSY; + if (rv) goto net_send_fin; + + rv = eos_msgq_push(config->send_q, mtype, msg, len); + if (rv) goto net_send_fin; + + /* we can't wake app module by pulling rts low */ + gpio_set_level(config->gpio_rts, 0); + +net_send_fin: xSemaphoreGive(config->mutex); - if (!rv && sleep) eos_power_wake(config->dev); - if (rv) _eos_net_free(config, buffer); + if (rv) _eos_net_free(config, msg); return rv; } -int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - return _eos_net_send(&net_config, mtype, buffer, buf_len); +int eos_net_send(unsigned char mtype, EOSMessage *msg, uint16_t len) { + return _eos_net_send(&net_config, mtype, msg, len); } -void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - buffer -= SPI_SIZE_HDR; +void eos_net_reply(unsigned char mtype, EOSMessage *msg, uint16_t len) { + unsigned char *buffer = msg->buffer - NET_SIZE_HDR; + + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) return; + if (eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REP) return; buffer[0] = mtype; - buffer[1] = buf_len >> 8; - buffer[2] = buf_len & 0xFF; + buffer[1] = len >> 8; + buffer[2] = len & 0xFF; + eos_msg_set_flags(msg, EOS_MSG_FLAG_RPLY_REP); } void _eos_net_sleep_req(NETConfig *config) { @@ -463,6 +480,14 @@ void _eos_net_wake(NETConfig *config) { } while (sleep); } +void _eos_net_deep_sleep(NETConfig *config) { + gpio_hold_en(config->gpio_cts); +} + +void _eos_net_deep_wake(NETConfig *config) { + gpio_hold_dis(config->gpio_cts); +} + void eos_net_sleep_req(void) { _eos_net_sleep_req(&net_config); } @@ -471,7 +496,15 @@ void eos_net_wake(void) { _eos_net_wake(&net_config); } +void eos_net_deep_sleep(void) { + _eos_net_deep_sleep(&net_config); +} + +void eos_net_deep_wake(void) { + _eos_net_deep_wake(&net_config); +} + void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler) { if (handler == NULL) handler = bad_handler; - if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler; + if (mtype < EOS_NET_MAX_MTYPE) net_handler[mtype] = handler; } |
