esp32: group tracking
authorAndy Green <andy@warmcat.com>
Tue, 16 May 2017 11:35:55 +0000 (19:35 +0800)
committerAndy Green <andy@warmcat.com>
Tue, 16 May 2017 11:35:55 +0000 (19:35 +0800)
lib/libwebsockets.h
lib/lws-plat-esp32.c
lib/parsers.c

index f2c67d1..4eb0cd0 100644 (file)
@@ -512,7 +512,7 @@ extern void esp32_uvtimer_cb(TimerHandle_t t);
 
 static inline void uv_timer_start(uv_timer_t *t, uv_cb_t *cb, int first, int rep)
 {
-       struct timer_mapping *tm = malloc(sizeof(*tm));
+       struct timer_mapping *tm = (struct timer_mapping *)malloc(sizeof(*tm));
 
        if (!tm)
                return;
@@ -563,10 +563,19 @@ struct lws_group_member {
        char model[16];
        char role[16];
        char host[32];
+       char mac[20];
+       int width, height;
        struct ip4_addr addr;
        struct ip6_addr addrv6;
+       uint8_t flags;
 };
 
+#define LWS_SYSTEM_GROUP_MEMBER_ADD            1
+#define LWS_SYSTEM_GROUP_MEMBER_CHANGE         2
+#define LWS_SYSTEM_GROUP_MEMBER_REMOVE         3
+
+#define LWS_GROUP_FLAG_SELF 1
+
 struct lws_esp32 {
        char sta_ip[16];
        char sta_mask[16];
@@ -581,6 +590,7 @@ struct lws_esp32 {
        char active_ssid[32];
        char access_pw[16];
        char hostname[32];
+       char mac[20];
        mdns_server_t *mdns;
                char region;
                char inet;
index 40e51f9..9c7a29a 100644 (file)
@@ -741,6 +741,50 @@ static void lws_esp32_scan_timer_cb(TimerHandle_t th)
 }
 
 #if !defined(CONFIG_LWS_IS_FACTORY_APPLICATION)
+
+void __attribute__(( weak ))
+lws_group_member_event(int e, void *p)
+{
+}
+
+void __attribute__(( weak ))
+lws_get_iframe_size(int *w, int *h)
+{
+       *w = 320;
+       *h = 160;
+}
+
+void lws_group_member_event_call(int e, void *p)
+{
+       lws_group_member_event(e, p);
+}
+
+static int
+get_txt_param(const char *txt, const char *param, char *result, int len)
+{
+       const char *p;
+
+again:
+       p = strstr(txt, param);
+       if (!p) {
+               *result = '\0';
+               return 1;
+       }
+
+       p += strlen(param);
+       if (*p != '=') {
+               txt = p;
+               goto again;
+       }
+       p++;
+       while (*p && *p != '&' && --len)
+               *result++ = *p++;
+
+       *result = '\0';
+
+       return 0;
+}
+
 static void lws_esp32_mdns_timer_cb(TimerHandle_t th)
 {
        uint64_t now = time_in_microseconds(); 
@@ -751,41 +795,67 @@ static void lws_esp32_mdns_timer_cb(TimerHandle_t th)
        if (!lws_esp32.mdns)
                return;
        n = mdns_query_end(lws_esp32.mdns);
-       lwsl_notice("%s: %d results\n", __func__, n);
 
        for (m = 0; m < n; m++) {
+               char ch = 0, group[16];
+
                r = mdns_result_get(lws_esp32.mdns, m);
-               lwsl_notice("found %s / %s / %s\n", r->host, r->instance, r->txt);
+
+               get_txt_param(r->txt, "group", group, sizeof(group));
+               if (strcmp(group, lws_esp32.group)) /* not our group */ {
+                       lwsl_notice("group %s vs %s  %s\n",
+                                       group, lws_esp32.group, r->txt);
+                       continue;
+               }
+
                p = lws_esp32.first;
                while (p) {
-                       if (strcmp(r->host, p->host)) {
-                               lwsl_notice("%s vs %s\n", r->host, p->host);
+                       if (strcmp(r->host, p->host))
                                goto next;
-                       }
-                       if (memcmp(&r->addr, &p->addr, sizeof(r->addr))) {
-                               lwsl_notice("0x%x vs 0x%x\n", *((unsigned int *)&r->addr),
-                                               *((unsigned int *)&p->addr));
+                       if (memcmp(&r->addr, &p->addr, sizeof(r->addr)))
                                goto next;
-                       }
-                       lwsl_notice("updating existing group member\n");
+
                        p->last_seen = now;
                        break;
 next:
                        p = p->next;
                }
                if (!p) { /* did not find */
-                       lwsl_notice("creating new group member\n");
+                       char temp[8];
                        p = malloc(sizeof(*p));
                        if (!p)
                                continue;
                        strncpy(p->host, r->host, sizeof(p->host) - 1);
                        p->host[sizeof(p->host) - 1] = '\0';
+
+                       get_txt_param(r->txt, "model", p->model, sizeof(p->model));
+                       get_txt_param(r->txt, "role", p->role, sizeof(p->role));
+                       get_txt_param(r->txt, "mac", p->mac, sizeof(p->mac));
+                       get_txt_param(r->txt, "width", temp, sizeof(temp));
+                       p->width = atoi(temp);
+                       get_txt_param(r->txt, "height", temp, sizeof(temp));
+                       p->height = atoi(temp);
+
                        memcpy(&p->addr, &r->addr, sizeof(p->addr));
                        memcpy(&p->addrv6, &r->addrv6, sizeof(p->addrv6));
                        p->last_seen = now;
+                       p->flags = 0;
                        p->next = lws_esp32.first;
                        lws_esp32.first = p;
                        lws_esp32.extant_group_members++;
+
+                       lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_ADD, p);
+               } else {
+                       if (memcmp(&p->addr, &r->addr, sizeof(p->addr))) {
+                               memcpy(&p->addr, &r->addr, sizeof(p->addr));
+                               ch = 1;
+                       }
+                       if (memcmp(&p->addrv6, &r->addrv6, sizeof(p->addrv6))) {
+                               memcpy(&p->addrv6, &r->addrv6, sizeof(p->addrv6));
+                               ch = 1;
+                       }
+                       if (ch)
+                               lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_CHANGE, p);
                }
        }
 
@@ -795,10 +865,12 @@ next:
        p1 = &lws_esp32.first;
        while (*p1) {
                p = *p1;
-               if (now - p->last_seen > 60000000) {
-                       lwsl_notice("timing out group member\n");
+               if (!(p->flags & LWS_GROUP_FLAG_SELF) &&
+                               now - p->last_seen > 60000000) {
                        lws_esp32.extant_group_members--;
                        *p1 = p->next;
+
+                       lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_REMOVE, p);
                        free(p);
                        continue;
                }
@@ -907,18 +979,20 @@ passthru:
        if (lws_esp32.scan_consumer)
                lws_esp32.scan_consumer(count_ap_records, ap_records, lws_esp32.scan_consumer_arg);
 
-}      
+}
+
 
 esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event)
 {
-       char slot[8];
-       nvs_handle nvh;
-       uint32_t use;
 #if !defined(CONFIG_LWS_IS_FACTORY_APPLICATION)
+       struct lws_group_member *mem;
        int n;
 #endif
+       char slot[8];
+       nvs_handle nvh;
+       uint32_t use;
 
-       switch(event->event_id) {
+       switch((int)event->event_id) {
        case SYSTEM_EVENT_STA_START:
                //esp_wifi_connect();
 //             break;
@@ -932,6 +1006,7 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event)
                lws_gapss_to(LWS_GAPSS_SCAN);
                if (lws_esp32.mdns)
                        mdns_service_remove_all(lws_esp32.mdns);
+               mdns_free(lws_esp32.mdns);
                lws_esp32.mdns = NULL;
                start_scan();
                esp_wifi_connect();
@@ -961,14 +1036,15 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event)
 #if !defined(CONFIG_LWS_IS_FACTORY_APPLICATION)
                n = mdns_init(TCPIP_ADAPTER_IF_STA, &lws_esp32.mdns);
                if (!n) {
-                       static char *txta[4];
+                       static char *txta[6];
+                       int w, h;
 
                        mdns_set_hostname(lws_esp32.mdns, lws_esp32.hostname);
                        mdns_set_instance(lws_esp32.mdns, lws_esp32.group);
                        mdns_service_add(lws_esp32.mdns, "_lwsgrmem", "_tcp", 443);
                        if (txta[0])
                                free(txta[0]);
-                       txta[0] = malloc(32 * 4);
+                       txta[0] = malloc(32 * ARRAY_SIZE(txta));
                        if (!txta[0]) {
                                lwsl_notice("mdns OOM\n");
                                break;
@@ -976,13 +1052,55 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event)
                        txta[1] = &txta[0][32];
                        txta[2] = &txta[1][32];
                        txta[3] = &txta[2][32];
+                       txta[4] = &txta[3][32];
+                       txta[5] = &txta[4][32];
+
+                       lws_get_iframe_size(&w, &h);
 
                        lws_snprintf(txta[0], 31, "model=%s", lws_esp32.model);
                        lws_snprintf(txta[1], 31, "group=%s", lws_esp32.group);
                        lws_snprintf(txta[2], 31, "role=%s", lws_esp32.role);
-                       lws_snprintf(txta[3], 31, "role=%s", lws_esp32.role);
+                       lws_snprintf(txta[3], 31, "mac=%s", lws_esp32.mac);
+                       lws_snprintf(txta[4], 31, "width=%d", w);
+                       lws_snprintf(txta[5], 31, "height=%d", h);
+
+                       mem = lws_esp32.first;
+                       while (mem) {
+                               if (mem->flags & 1)
+                                       break;
+                               mem = mem->next;
+                       }
+
+                       if (!mem) {
+                               struct lws_group_member *mem = malloc(sizeof(*mem));
+                               if (mem) {
+                                       mem->last_seen = ~(uint64_t)0;
+                                       strcpy(mem->model, lws_esp32.model);
+                                       strcpy(mem->role, lws_esp32.role);
+                                       strcpy(mem->host, lws_esp32.hostname);
+                                       strcpy(mem->mac, lws_esp32.mac);
+                                       mem->flags = LWS_GROUP_FLAG_SELF;
+                                       lws_get_iframe_size(&mem->width, &mem->height);
+                                       memcpy(&mem->addr, &event->event_info.got_ip.ip_info.ip,
+                                                       sizeof(mem->addr));
+                                       memcpy(&mem->addrv6, &event->event_info.got_ip6.ip6_info.ip,
+                                                       sizeof(mem->addrv6));
+                                       mem->next = lws_esp32.first;
+                                       lws_esp32.first = mem;
+                                       lws_esp32.extant_group_members++;
+
+                                       lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_ADD, mem);
+                               }
+                       } else { /* update our IP */
+                                       memcpy(&mem->addr, &event->event_info.got_ip.ip_info.ip,
+                                                       sizeof(mem->addr));
+                                       memcpy(&mem->addrv6, &event->event_info.got_ip6.ip6_info.ip,
+                                                       sizeof(mem->addrv6));
+                                       lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_CHANGE, mem);
+                       }
+
 
-                       if (mdns_service_txt_set(lws_esp32.mdns, "_lwsgrmem", "_tcp", 4,
+                       if (mdns_service_txt_set(lws_esp32.mdns, "_lwsgrmem", "_tcp", ARRAY_SIZE(txta),
                                                 (const char **)txta))
                                lwsl_notice("txt set failed\n");
                } else
@@ -999,6 +1117,7 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event)
                lwsl_notice("SYSTEM_EVENT_SCAN_DONE\n");
                end_scan();
                break;
+
        default:
                break;
        }
@@ -1110,6 +1229,8 @@ lws_esp32_wlan_nvs_get(int retry)
        esp_efuse_mac_get_default(mac);
        mac[5] |= 1; /* match the AP MAC */
        snprintf(lws_esp32.serial, sizeof(lws_esp32.serial) - 1, "%02X%02X%02X", mac[3], mac[4], mac[5]);
+       snprintf(lws_esp32.mac, sizeof(lws_esp32.mac) - 1, "%02X%02X%02X%02X%02X%02X", mac[0],
+                       mac[1], mac[2], mac[3], mac[4], mac[5]);
 
        ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh));
 
index c283448..1140b4d 100644 (file)
@@ -181,7 +181,7 @@ lws_header_table_attach(struct lws *wsi, int autoservice)
 
        _lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa);
 
-       lwsl_notice("%s: did attach wsi %p: ah %p: count %d (on exit)\n", __func__,
+       lwsl_info("%s: did attach wsi %p: ah %p: count %d (on exit)\n", __func__,
                  (void *)wsi, (void *)wsi->u.hdr.ah, pt->ah_count_in_use);
 
        lws_pt_unlock(pt);