]> granicus.if.org Git - esp-idf/blob - components/esp32/event_loop.c
Merge branch 'feature/esp-wrover-kit-v4_1' into 'master'
[esp-idf] / components / esp32 / event_loop.c
1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <stddef.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "esp_err.h"
20 #include "esp_wifi.h"
21 #include "esp_event.h"
22 #include "esp_event_loop.h"
23 #include "esp_task.h"
24 #include "esp_mesh.h"
25
26 #include "freertos/FreeRTOS.h"
27 #include "freertos/task.h"
28 #include "freertos/queue.h"
29 #include "freertos/semphr.h"
30
31 #include "esp_log.h"
32 #include "sdkconfig.h"
33
34
35 static const char* TAG = "event";
36 static bool s_event_init_flag = false;
37 static QueueHandle_t s_event_queue = NULL;
38 static system_event_cb_t s_event_handler_cb = NULL;
39 static void *s_event_ctx = NULL;
40
41 static esp_err_t esp_event_post_to_user(system_event_t *event)
42 {
43     if (s_event_handler_cb) {
44         return (*s_event_handler_cb)(s_event_ctx, event);
45     }
46     return ESP_OK;
47 }
48
49 static void esp_event_loop_task(void *pvParameters)
50 {
51     while (1) {
52         system_event_t evt;
53         if (xQueueReceive(s_event_queue, &evt, portMAX_DELAY) == pdPASS) {
54             esp_err_t ret = esp_event_process_default(&evt);
55             if (ret != ESP_OK) {
56                 ESP_LOGE(TAG, "default event handler failed!");
57             }
58             ret = esp_event_post_to_user(&evt);
59             if (ret != ESP_OK) {
60                 ESP_LOGE(TAG, "post event to user fail!");
61             }
62         }
63     }
64 }
65
66 system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx)
67 {
68     system_event_cb_t old_cb = s_event_handler_cb;
69     s_event_handler_cb = cb;
70     s_event_ctx = ctx;
71     return old_cb;
72 }
73
74 esp_err_t esp_event_send(system_event_t *event)
75 {
76     if (s_event_queue == NULL) {
77         ESP_LOGE(TAG, "Event loop not initialized via esp_event_loop_init, but esp_event_send called");
78         return ESP_ERR_INVALID_STATE;
79     }
80
81     if (event->event_id == SYSTEM_EVENT_STA_GOT_IP || event->event_id == SYSTEM_EVENT_STA_LOST_IP) {
82         if (g_mesh_event_cb) {
83             mesh_event_t mevent;
84             if (event->event_id == SYSTEM_EVENT_STA_GOT_IP) {
85                 mevent.id = MESH_EVENT_ROOT_GOT_IP;
86                 memcpy(&mevent.info.got_ip, &event->event_info.got_ip, sizeof(system_event_sta_got_ip_t));
87             } else {
88                 mevent.id = MESH_EVENT_ROOT_LOST_IP;
89             }
90             g_mesh_event_cb(mevent);
91         }
92     }
93
94     portBASE_TYPE ret = xQueueSendToBack(s_event_queue, event, 0);
95     if (ret != pdPASS) {
96         if (event) {
97             ESP_LOGE(TAG, "e=%d f", event->event_id);
98         } else {
99             ESP_LOGE(TAG, "e null");
100         }
101         return ESP_FAIL;
102     }
103     return ESP_OK;
104 }
105
106 QueueHandle_t esp_event_loop_get_queue(void)
107 {
108     return s_event_queue;
109 }
110
111 esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx)
112 {
113     if (s_event_init_flag) {
114         return ESP_FAIL;
115     }
116     s_event_handler_cb = cb;
117     s_event_ctx = ctx;
118     s_event_queue = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t));
119
120     xTaskCreatePinnedToCore(esp_event_loop_task, "eventTask",
121             ESP_TASKD_EVENT_STACK, NULL, ESP_TASKD_EVENT_PRIO, NULL, 0);
122
123     s_event_init_flag = true;
124     return ESP_OK;
125 }
126