• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #include "private-lib-core.h"
26 
27 #include "romfs.h"
28 #include <esp_ota_ops.h>
29 #include <tcpip_adapter.h>
30 #include <esp_image_format.h>
31 #include <esp_task_wdt.h>
32 #include "soc/ledc_reg.h"
33 #include "driver/ledc.h"
34 
35 struct lws_esp32 lws_esp32 = {
36 	.model = CONFIG_LWS_MODEL_NAME,
37 	.serial = "unknown",
38 };
39 
40 /*
41  * Group AP / Station State
42  */
43 
44 enum lws_gapss {
45 	LWS_GAPSS_INITIAL,	/* just started up, init and move to
46 				 * LWS_GAPSS_SCAN */
47 	LWS_GAPSS_SCAN,		/*
48 				 * Unconnected, scanning: AP known in one of the
49 				 * config slots -> configure it, start timeout +
50 				 * LWS_GAPSS_STAT, if no AP already up in same
51 				 * group with lower MAC, after a random period
52 				 * start up our AP (LWS_GAPSS_AP)
53 				 */
54 	LWS_GAPSS_AP,		/*
55 				 * Trying to be the group AP... periodically do
56 				 * a scan LWS_GAPSS_AP_SCAN, faster and then
57 				 * slower
58        				 */
59 	LWS_GAPSS_AP_SCAN,	/*
60 				 * doing a scan while trying to be the group
61 				 * AP... if we see a lower MAC being the AP for
62 				 * the same group AP, abandon being an AP and
63 				 * join that AP as a station
64 				 */
65 	LWS_GAPSS_STAT_GRP_AP,	/*
66 				 * We have decided to join another group member
67 				 * who is being the AP, as its MAC is lower than
68 				 * ours.  This is a stable state, but we still
69 				 * do periodic scans LWS_GAPSS_STAT_GRP_AP_SCAN
70 				 * and will always prefer an AP configured in a
71 				 * slot.
72 				 */
73 	LWS_GAPSS_STAT_GRP_AP_SCAN,
74 				/*
75 				 * We have joined a group member who is doing
76 				 * the AP job... we want to check every now and
77 				 * then if a configured AP has appeared that we
78 				 * should better use instead.  Otherwise stay in
79 				 * LWS_GAPSS_STAT_GRP_AP
80 				 */
81 	LWS_GAPSS_STAT,		/*
82 				 * trying to connect to another non-group AP.
83 				 * If we don't get an IP within a timeout and
84 				 * retries, blacklist it and go back
85 				 */
86 	LWS_GAPSS_STAT_HAPPY,
87 };
88 
89 static const char *gapss_str[] = {
90 	"LWS_GAPSS_INITIAL",
91         "LWS_GAPSS_SCAN",
92         "LWS_GAPSS_AP",
93         "LWS_GAPSS_AP_SCAN",
94         "LWS_GAPSS_STAT_GRP_AP",
95         "LWS_GAPSS_STAT_GRP_AP_SCAN",
96         "LWS_GAPSS_STAT",
97 	"LWS_GAPSS_STAT_HAPPY",
98 };
99 
100 static romfs_t lws_esp32_romfs;
101 static TimerHandle_t leds_timer, scan_timer, debounce_timer, association_timer
102 #if !defined(CONFIG_LWS_IS_FACTORY_APPLICATION)
103 , mdns_timer
104 #endif
105 ;
106 static enum lws_gapss gapss = LWS_GAPSS_INITIAL;
107 #if !defined(CONFIG_LWS_IS_FACTORY_APPLICATION)
108 static mdns_result_t *mdns_results_head;
109 #endif
110 
111 #define GPIO_SW 14
112 
113 struct esp32_file {
114 	const struct inode *i;
115 };
116 
lws_gapss_to(enum lws_gapss to)117 static void lws_gapss_to(enum lws_gapss to)
118 {
119 	lwsl_notice("gapss from %s to %s\n", gapss_str[gapss], gapss_str[to]);
120 	gapss = to;
121 }
122 
lws_esp32_get_reboot_type(void)123 uint32_t lws_esp32_get_reboot_type(void)
124 {
125 	uint32_t *p = (uint32_t *)LWS_MAGIC_REBOOT_TYPE_ADS, val = *p;
126 	nvs_handle nvh;
127 	size_t s = 0;
128 	int n = 0;
129 
130 	ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh));
131 	if (nvs_get_blob(nvh, "ssl-pub.pem", NULL, &s) == ESP_OK)
132 		n = 1;
133 	if (nvs_get_blob(nvh, "ssl-pri.pem", NULL, &s) == ESP_OK)
134 		n |= 2;
135 	nvs_close(nvh);
136 
137 	/*
138 	 * in the case the SSL certs are not there, don't require
139 	 * the button to be down to access all features.
140 	 */
141 	if (n != 3)
142 		val = LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON;
143 
144 	return val;
145 }
146 
render_ip(char * dest,int len,uint8_t * ip)147 static void render_ip(char *dest, int len, uint8_t *ip)
148 {
149 	snprintf(dest, len, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
150 }
151 
lws_esp32_restart_guided(uint32_t type)152 void lws_esp32_restart_guided(uint32_t type)
153 {
154         uint32_t *p_force_factory_magic = (uint32_t *)LWS_MAGIC_REBOOT_TYPE_ADS;
155 
156 	lwsl_notice("%s: %x\n", __func__, type);
157         *p_force_factory_magic = type;
158 
159 	esp_restart();
160 }
161 
162 /*
163  * esp-idf goes crazy with zero length str nvs.  Use this as a workaround
164  * to delete the key in that case.
165  */
166 
lws_nvs_set_str(nvs_handle handle,const char * key,const char * value)167 esp_err_t lws_nvs_set_str(nvs_handle handle, const char* key, const char* value)
168 {
169 	if (*value)
170 		return nvs_set_str(handle, key, value);
171 
172 	return nvs_erase_key(handle, key);
173 }
174 
175 static wifi_scan_config_t scan_config = {
176         .ssid = 0,
177         .bssid = 0,
178         .channel = 0,
179         .show_hidden = true
180 };
181 
182 static char scan_ongoing = 0, scan_timer_exists = 0;
183 static int try_slot = -1;
184 
185 static wifi_config_t config = {
186 	.ap = {
187 	    .channel = 6,
188 	    .authmode = WIFI_AUTH_OPEN,
189 	    .max_connection = 1,
190 	} }, sta_config = {
191 	.sta = {
192 		.bssid_set = 0,
193 	} };
194 
lws_esp32_scan_timer_cb(TimerHandle_t th)195 static void lws_esp32_scan_timer_cb(TimerHandle_t th)
196 {
197 	int n;
198 
199 	lwsl_notice("%s\n", __func__);
200 	scan_ongoing = 0;
201 	n = esp_wifi_scan_start(&scan_config, false);
202 	if (n != ESP_OK)
203 		lwsl_err("scan start failed %d\n", n);
204 }
205 
lws_esp32_assoc_timer_cb(TimerHandle_t th)206 static void lws_esp32_assoc_timer_cb(TimerHandle_t th)
207 {
208 	int n;
209 
210 	xTimerStop(association_timer, 0);
211 
212 	if (gapss == LWS_GAPSS_STAT_HAPPY) {
213 		lwsl_debug("%s: saw we were happy\n", __func__);
214 
215 		return;
216 	}
217 
218 	lwsl_notice("%s: forcing rescan\n", __func__);
219 
220 	lws_gapss_to(LWS_GAPSS_SCAN);
221 	scan_ongoing = 0;
222 	n = esp_wifi_scan_start(&scan_config, false);
223 	if (n != ESP_OK)
224 		lwsl_err("scan start failed %d\n", n);
225 }
226 
227 
228 #if !defined(CONFIG_LWS_IS_FACTORY_APPLICATION)
229 
230 void __attribute__(( weak ))
lws_group_member_event(int e,void * p)231 lws_group_member_event(int e, void *p)
232 {
233 }
234 
235 void __attribute__(( weak ))
lws_get_iframe_size(int * w,int * h)236 lws_get_iframe_size(int *w, int *h)
237 {
238 	*w = 320;
239 	*h = 160;
240 }
241 
lws_group_member_event_call(int e,void * p)242 void lws_group_member_event_call(int e, void *p)
243 {
244 	lws_group_member_event(e, p);
245 }
246 
247 static int
get_txt_param(const mdns_result_t * mr,const char * param,char * result,int len)248 get_txt_param(const mdns_result_t *mr, const char *param, char *result, int len)
249 {
250 	const char *p;
251 
252 	*result = '\0';
253 
254 	p = strstr(mr->txt->key, param);
255 	if (!p) {
256 		*result = '\0';
257 		return 1;
258 	}
259 
260 	lws_strncpy(result, mr->txt->value, len);
261 
262 	return 0;
263 }
264 
lws_esp32_mdns_timer_cb(TimerHandle_t th)265 static void lws_esp32_mdns_timer_cb(TimerHandle_t th)
266 {
267 	uint64_t now = lws_now_usecs();
268 	struct lws_group_member *p, **p1;
269 	const mdns_result_t *r = mdns_results_head;
270 
271 	while (r) {
272 		char ch = 0, group[16];
273 
274 		get_txt_param(r, "group", group, sizeof(group));
275 		if (strcmp(group, lws_esp32.group)) /* not our group */ {
276 			lwsl_notice("group %s vs %s  %s\n",
277 					group, lws_esp32.group, r->txt->value);
278 			continue;
279 		}
280 
281 		p = lws_esp32.first;
282 		while (p) {
283 			if (strcmp(r->hostname, p->host))
284 				goto next;
285 			if (memcmp(&r->addr, &p->addr, sizeof(r->addr)))
286 				goto next;
287 
288 			p->last_seen = now;
289 			break;
290 next:
291 			p = p->next;
292 		}
293 		if (!p) { /* did not find */
294 			char temp[8];
295 
296 			p = lws_malloc(sizeof(*p), "group");
297 			if (!p)
298 				continue;
299 			lws_strncpy(p->host, r->hostname, sizeof(p->host));
300 
301 			get_txt_param(r, "model", p->model, sizeof(p->model));
302 			get_txt_param(r, "role", p->role, sizeof(p->role));
303 			get_txt_param(r, "mac", p->mac, sizeof(p->mac));
304 			get_txt_param(r, "width", temp, sizeof(temp));
305 			p->width = atoi(temp);
306 			get_txt_param(r, "height", temp, sizeof(temp));
307 			p->height = atoi(temp);
308 
309 			memcpy(&p->addr, &r->addr, sizeof(p->addr));
310 //			memcpy(&p->addrv6, &r->addrv6, sizeof(p->addrv6));
311 			p->last_seen = now;
312 			p->flags = 0;
313 			p->next = lws_esp32.first;
314 			lws_esp32.first = p;
315 			lws_esp32.extant_group_members++;
316 
317 			lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_ADD, p);
318 		} else {
319 			if (memcmp(&p->addr, &r->addr, sizeof(p->addr))) {
320 				memcpy(&p->addr, &r->addr, sizeof(p->addr));
321 				ch = 1;
322 			}
323 /*			if (memcmp(&p->addrv6, &r->addrv6, sizeof(p->addrv6))) {
324 				memcpy(&p->addrv6, &r->addrv6, sizeof(p->addrv6));
325 				ch = 1;
326 			} */
327 			if (ch)
328 				lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_CHANGE, p);
329 		}
330 	}
331 
332 	mdns_query_results_free(mdns_results_head);
333 
334 	/* garbage-collect group members not seen for too long */
335 	p1 = &lws_esp32.first;
336 	while (*p1) {
337 		p = *p1;
338 		if (!(p->flags & LWS_GROUP_FLAG_SELF) &&
339 				now - p->last_seen > 60000000) {
340 			lws_esp32.extant_group_members--;
341 			*p1 = p->next;
342 
343 			lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_REMOVE, p);
344 			lws_free(p);
345 			continue;
346 		}
347 		p1 = &(*p1)->next;
348 	}
349 
350 	mdns_query_txt(lws_esp32.group, "_lwsgrmem", "_tcp", 0,
351 			       &mdns_results_head);
352 	xTimerStart(mdns_timer, 0);
353 }
354 #endif
355 
356 void __attribute__(( weak ))
lws_esp32_button(int down)357 lws_esp32_button(int down)
358 {
359 }
360 
361 void IRAM_ATTR
gpio_irq(void * arg)362 gpio_irq(void *arg)
363 {
364 	gpio_set_intr_type(GPIO_SW, GPIO_INTR_DISABLE);
365 	xTimerStart(debounce_timer, 0);
366 }
367 
lws_esp32_debounce_timer_cb(TimerHandle_t th)368 static void lws_esp32_debounce_timer_cb(TimerHandle_t th)
369 {
370 	if (lws_esp32.button_is_down)
371 		gpio_set_intr_type(GPIO_SW, GPIO_INTR_POSEDGE);
372 	else
373 		gpio_set_intr_type(GPIO_SW, GPIO_INTR_NEGEDGE);
374 
375 	lws_esp32.button_is_down = gpio_get_level(GPIO_SW);
376 
377 	lws_esp32_button(lws_esp32.button_is_down);
378 }
379 
380 
381 static int
start_scan()382 start_scan()
383 {
384 	/* if no APs configured, no point... */
385 
386 	if (!lws_esp32.ssid[0][0] &&
387 	    !lws_esp32.ssid[1][0] &&
388 	    !lws_esp32.ssid[2][0] &&
389 	    !lws_esp32.ssid[3][0])
390 		return 0;
391 
392 	if (scan_timer_exists && !scan_ongoing) {
393 		// lwsl_notice("Starting scan timer...\n");
394 		scan_ongoing = 1;
395 		xTimerStart(scan_timer, 0);
396 	}
397 
398 	return 0;
399 }
400 
401 
402 
403 static void
end_scan()404 end_scan()
405 {
406 	wifi_ap_record_t ap_records[10];
407 	uint16_t count_ap_records;
408 	int n, m;
409 
410 	count_ap_records = LWS_ARRAY_SIZE(ap_records);
411 	if (esp_wifi_scan_get_ap_records(&count_ap_records, ap_records)) {
412 		lwsl_err("%s: failed\n", __func__);
413 		return;
414 	}
415 
416 	if (!count_ap_records)
417 		goto passthru;
418 
419 	if (gapss != LWS_GAPSS_SCAN) {
420 		lwsl_info("ignoring scan as gapss %s\n", gapss_str[gapss]);
421 		goto passthru;
422 	}
423 
424 	/* no point if no APs set up */
425 	if (!lws_esp32.ssid[0][0] &&
426 	    !lws_esp32.ssid[1][0] &&
427 	    !lws_esp32.ssid[2][0] &&
428 	    !lws_esp32.ssid[3][0])
429 		goto passthru;
430 
431 	lwsl_info("checking %d scan records\n", count_ap_records);
432 
433 	for (n = 0; n < 4; n++) {
434 
435 		if (!lws_esp32.ssid[(n + try_slot + 1) & 3][0])
436 			continue;
437 
438 		lwsl_debug("looking for %s\n",
439 			    lws_esp32.ssid[(n + try_slot + 1) & 3]);
440 
441 		/* this ssid appears in scan results? */
442 
443 		for (m = 0; m < count_ap_records; m++) {
444 			// lwsl_notice("  %s\n", ap_records[m].ssid);
445 			if (!strcmp((char *)ap_records[m].ssid,
446 				    lws_esp32.ssid[(n + try_slot + 1) & 3]))
447 				goto hit;
448 		}
449 
450 		continue;
451 
452 hit:
453 		m = (n + try_slot + 1) & 3;
454 		try_slot = m;
455 		lwsl_info("Attempting connection with slot %d: %s:\n", m,
456 				lws_esp32.ssid[m]);
457 		/* set the ssid we last tried to connect to */
458 		lws_strncpy(lws_esp32.active_ssid, lws_esp32.ssid[m],
459 				sizeof(lws_esp32.active_ssid));
460 
461 		lws_strncpy((char *)sta_config.sta.ssid, lws_esp32.ssid[m],
462 			sizeof(sta_config.sta.ssid));
463 		lws_strncpy((char *)sta_config.sta.password, lws_esp32.password[m],
464 			sizeof(sta_config.sta.password));
465 
466 		tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA,
467 					   (const char *)&config.ap.ssid[7]);
468 		lws_gapss_to(LWS_GAPSS_STAT);
469 		xTimerStop(association_timer, 0);
470 		xTimerStart(association_timer, 0);
471 
472 		esp_wifi_set_config(WIFI_IF_STA, &sta_config);
473 		esp_wifi_connect();
474 		break;
475 	}
476 
477 	if (n == 4)
478 		start_scan();
479 
480 passthru:
481 	if (lws_esp32.scan_consumer)
482 		lws_esp32.scan_consumer(count_ap_records, ap_records,
483 					lws_esp32.scan_consumer_arg);
484 
485 }
486 
487 static void
lws_set_genled(int n)488 lws_set_genled(int n)
489 {
490 	lws_esp32.genled_t = lws_now_usecs();
491 	lws_esp32.genled = n;
492 }
493 
494 int
lws_esp32_leds_network_indication(void)495 lws_esp32_leds_network_indication(void)
496 {
497 	uint64_t us, r;
498 	int n, fadein = 100, speed = 1199, div = 1, base = 0;
499 
500 	r = lws_now_usecs();
501 	us = r - lws_esp32.genled_t;
502 
503 	switch (lws_esp32.genled) {
504 	case LWSESP32_GENLED__INIT:
505 		lws_esp32.genled = LWSESP32_GENLED__LOST_NETWORK;
506 		/* fallthru */
507 	case LWSESP32_GENLED__LOST_NETWORK:
508 		fadein = us / 10000; /* 100 steps in 1s */
509 		if (fadein > 100) {
510 			fadein = 100;
511 			lws_esp32.genled = LWSESP32_GENLED__NO_NETWORK;
512 		}
513 		/* fallthru */
514 	case LWSESP32_GENLED__NO_NETWORK:
515 		break;
516 	case LWSESP32_GENLED__CONN_AP:
517 		base = 4096;
518 		speed = 933;
519 		div = 2;
520 		break;
521 	case LWSESP32_GENLED__GOT_IP:
522 		fadein = us / 10000; /* 100 steps in 1s */
523 		if (fadein > 100) {
524 			fadein = 100;
525 			lws_esp32.genled = LWSESP32_GENLED__OK;
526 		}
527 		fadein = 100 - fadein; /* we are fading out */
528 		/* fallthru */
529 	case LWSESP32_GENLED__OK:
530 		if (lws_esp32.genled == LWSESP32_GENLED__OK)
531 			return 0;
532 
533 		base = 4096;
534 		speed = 766;
535 		div = 3;
536 		break;
537 	}
538 
539 	n = base + (lws_esp32_sine_interp(r / speed) / div);
540 	return (n * fadein) / 100;
541 }
542 
lws_esp32_event_passthru(void * ctx,system_event_t * event)543 esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event)
544 {
545 #if !defined(CONFIG_LWS_IS_FACTORY_APPLICATION)
546 	struct lws_group_member *mem;
547 	int n;
548 #endif
549 	nvs_handle nvh;
550 	uint32_t use;
551 
552 	switch((int)event->event_id) {
553 	case SYSTEM_EVENT_STA_START:
554 		//esp_wifi_connect();
555 //		break;
556 		/* fallthru */
557 	case SYSTEM_EVENT_STA_DISCONNECTED:
558 		lwsl_notice("SYSTEM_EVENT_STA_DISCONNECTED\n");
559 		if (sntp_enabled())
560 			sntp_stop();
561 		lws_esp32.conn_ap = 0;
562 		lws_esp32.inet = 0;
563 		lws_esp32.sta_ip[0] = '\0';
564 		lws_esp32.sta_mask[0] = '\0';
565 		lws_esp32.sta_gw[0] = '\0';
566 		lws_gapss_to(LWS_GAPSS_SCAN);
567 		mdns_free();
568 		lws_set_genled(LWSESP32_GENLED__LOST_NETWORK);
569 		start_scan();
570 		esp_wifi_connect();
571 		break;
572 
573 	case SYSTEM_EVENT_STA_CONNECTED:
574 		lws_esp32.conn_ap = 1;
575 		lws_set_genled(LWSESP32_GENLED__CONN_AP);
576 		break;
577 
578 	case SYSTEM_EVENT_STA_GOT_IP:
579 		lwsl_notice("SYSTEM_EVENT_STA_GOT_IP\n");
580 
581 		lws_esp32.inet = 1;
582 		lws_set_genled(LWSESP32_GENLED__GOT_IP);
583 
584 		render_ip(lws_esp32.sta_ip, sizeof(lws_esp32.sta_ip) - 1,
585 				(uint8_t *)&event->event_info.got_ip.ip_info.ip);
586 		render_ip(lws_esp32.sta_mask, sizeof(lws_esp32.sta_mask) - 1,
587 				(uint8_t *)&event->event_info.got_ip.ip_info.netmask);
588 		render_ip(lws_esp32.sta_gw, sizeof(lws_esp32.sta_gw) - 1,
589 				(uint8_t *)&event->event_info.got_ip.ip_info.gw);
590 
591 		if (!nvs_open("lws-station", NVS_READWRITE, &nvh)) {
592 			char slot[8];
593 
594 			lws_snprintf(slot, sizeof(slot) - 1, "%duse", try_slot);
595 			use = 0;
596 			nvs_get_u32(nvh, slot, &use);
597 			nvs_set_u32(nvh, slot, use + 1);
598 			nvs_commit(nvh);
599 			nvs_close(nvh);
600 		}
601 
602 		lws_gapss_to(LWS_GAPSS_STAT_HAPPY);
603 
604 #if !defined(CONFIG_LWS_IS_FACTORY_APPLICATION)
605 		n = mdns_init();
606 		if (!n) {
607 			static mdns_txt_item_t txta[6];
608 			static char wh[2][6];
609 			int w, h;
610 
611 			mdns_hostname_set(lws_esp32.hostname);
612 			mdns_instance_name_set(lws_esp32.group);
613 
614 			lws_get_iframe_size(&w, &h);
615 
616 			txta[0].key = "model";
617 			txta[1].key = "group";
618 			txta[2].key = "role";
619 			txta[3].key = "mac";
620 			txta[4].key = "width";
621 			txta[5].key = "height";
622 
623 			txta[0].value = lws_esp32.model;
624 			txta[1].value = lws_esp32.group;
625 			txta[2].value = lws_esp32.role;
626 			txta[3].value = lws_esp32.mac;
627 			txta[4].value = wh[0];
628 			txta[5].value = wh[1];
629 
630 			lws_snprintf(wh[0], 6, "%d", w);
631 			lws_snprintf(wh[1], 6, "%d", h);
632 
633 			mdns_service_add(lws_esp32.group,
634 					 "_lwsgrmem", "_tcp", 443, txta,
635 					 LWS_ARRAY_SIZE(txta));
636 
637 			mem = lws_esp32.first;
638 			while (mem) {
639 				if (mem->flags & 1)
640 					break;
641 				mem = mem->next;
642 			}
643 
644 			if (!mem) {
645 				struct lws_group_member *mem =
646 					      lws_malloc(sizeof(*mem), "group");
647 				if (mem) {
648 					mem->last_seen = ~(uint64_t)0;
649 					strcpy(mem->model, lws_esp32.model);
650 					strcpy(mem->role, lws_esp32.role);
651 					strcpy(mem->host, lws_esp32.hostname);
652 					strcpy(mem->mac, lws_esp32.mac);
653 					mem->flags = LWS_GROUP_FLAG_SELF;
654 					lws_get_iframe_size(&mem->width,
655 							    &mem->height);
656 					memcpy(&mem->addr,
657 					       &event->event_info.got_ip.ip_info.ip,
658 					       sizeof(mem->addr));
659 					memcpy(&mem->addrv6,
660 					       &event->event_info.got_ip6.ip6_info.ip,
661 					       sizeof(mem->addrv6));
662 					mem->next = lws_esp32.first;
663 					lws_esp32.first = mem;
664 					lws_esp32.extant_group_members++;
665 
666 					lws_group_member_event_call(
667 					      LWS_SYSTEM_GROUP_MEMBER_ADD, mem);
668 				}
669 			} else { /* update our IP */
670 				memcpy(&mem->addr,
671 				       &event->event_info.got_ip.ip_info.ip,
672 				       sizeof(mem->addr));
673 				memcpy(&mem->addrv6,
674 				       &event->event_info.got_ip6.ip6_info.ip,
675 				       sizeof(mem->addrv6));
676 				lws_group_member_event_call(
677 					   LWS_SYSTEM_GROUP_MEMBER_CHANGE, mem);
678 			}
679 
680 		} else
681 			lwsl_err("unable to init mdns on STA: %d\n", n);
682 
683 		mdns_query_txt(lws_esp32.group, "_lwsgrmem", "_tcp", 0,
684 			       &mdns_results_head);
685 		xTimerStart(mdns_timer, 0);
686 #endif
687 
688 		lwsl_notice(" --- Got IP %s\n", lws_esp32.sta_ip);
689 		if (!sntp_enabled()) {
690 			sntp_setoperatingmode(SNTP_OPMODE_POLL);
691 			sntp_setservername(0, "pool.ntp.org");
692 			sntp_init();
693 		}
694 		break;
695 
696 	case SYSTEM_EVENT_SCAN_DONE:
697 		lwsl_notice("SYSTEM_EVENT_SCAN_DONE\n");
698 		end_scan();
699 		break;
700 
701 	default:
702 		break;
703 	}
704 
705 	return ESP_OK;
706 }
707 
708 #if defined(LWS_WITH_FILE_OPS)
709 static lws_fop_fd_t IRAM_ATTR
esp32_lws_fops_open(const struct lws_plat_file_ops * fops,const char * filename,const char * vfs_path,lws_fop_flags_t * flags)710 esp32_lws_fops_open(const struct lws_plat_file_ops *fops, const char *filename,
711                     const char *vfs_path, lws_fop_flags_t *flags)
712 {
713 	struct esp32_file *f = malloc(sizeof(*f));
714 	lws_fop_fd_t fop_fd;
715 	size_t len, csum;
716 
717 	lwsl_notice("%s: %s\n", __func__, filename);
718 
719 	if (!f)
720 		return NULL;
721 	f->i = romfs_get_info(lws_esp32_romfs, filename, &len, &csum);
722 	if (!f->i)
723 		goto bail;
724 
725         fop_fd = malloc(sizeof(*fop_fd));
726         if (!fop_fd)
727                 goto bail;
728 
729         fop_fd->fops = fops;
730         fop_fd->filesystem_priv = f;
731 	fop_fd->mod_time = csum;
732 	*flags |= LWS_FOP_FLAG_MOD_TIME_VALID;
733 	fop_fd->flags = *flags;
734 
735 	fop_fd->len = len;
736 	fop_fd->pos = 0;
737 
738 	return fop_fd;
739 
740 bail:
741 	free(f);
742 
743 	return NULL;
744 }
745 
746 static int IRAM_ATTR
esp32_lws_fops_close(lws_fop_fd_t * fop_fd)747 esp32_lws_fops_close(lws_fop_fd_t *fop_fd)
748 {
749 	free((*fop_fd)->filesystem_priv);
750 	free(*fop_fd);
751 
752 	*fop_fd = NULL;
753 
754 	return 0;
755 }
756 static lws_fileofs_t IRAM_ATTR
esp32_lws_fops_seek_cur(lws_fop_fd_t fop_fd,lws_fileofs_t offset_from_cur_pos)757 esp32_lws_fops_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset_from_cur_pos)
758 {
759 	fop_fd->pos += offset_from_cur_pos;
760 
761 	if (fop_fd->pos > fop_fd->len)
762 		fop_fd->pos = fop_fd->len;
763 
764        return 0;
765 }
766 
767 static int IRAM_ATTR
esp32_lws_fops_read(lws_fop_fd_t fop_fd,lws_filepos_t * amount,uint8_t * buf,lws_filepos_t len)768 esp32_lws_fops_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, uint8_t *buf,
769                    lws_filepos_t len)
770 {
771        struct esp32_file *f = fop_fd->filesystem_priv;
772 #if 0
773        if ((long)buf & 3) {
774                lwsl_err("misaligned buf\n");
775 
776                return -1;
777        }
778 #endif
779        if (fop_fd->pos >= fop_fd->len)
780                return 0;
781 
782        if (len > fop_fd->len - fop_fd->pos)
783                len = fop_fd->len - fop_fd->pos;
784 
785        spi_flash_read((uint32_t)(char *)f->i + fop_fd->pos, buf, len);
786 
787        *amount = len;
788        fop_fd->pos += len;
789 
790        return 0;
791 }
792 
793 static const struct lws_plat_file_ops fops = {
794 	.next = &fops_zip,
795 	.LWS_FOP_OPEN = esp32_lws_fops_open,
796 	.LWS_FOP_CLOSE = esp32_lws_fops_close,
797 	.LWS_FOP_READ = esp32_lws_fops_read,
798 	.LWS_FOP_SEEK_CUR = esp32_lws_fops_seek_cur,
799 };
800 #endif
801 
802 int
lws_esp32_wlan_nvs_get(int retry)803 lws_esp32_wlan_nvs_get(int retry)
804 {
805 	nvs_handle nvh;
806 	char lws_esp32_force_ap = 0, slot[12];
807 	size_t s;
808 	uint8_t mac[6];
809 	int n;
810 
811 	esp_efuse_mac_get_default(mac);
812 	mac[5] |= 1; /* match the AP MAC */
813 	snprintf(lws_esp32.serial, sizeof(lws_esp32.serial) - 1,
814 		 "%02X%02X%02X", mac[3], mac[4], mac[5]);
815 	snprintf(lws_esp32.mac, sizeof(lws_esp32.mac) - 1,
816 		 "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3],
817 		 mac[4], mac[5]);
818 
819 	ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh));
820 
821 	config.sta.ssid[0] = '\0';
822 	config.sta.password[0] = '\0';
823 
824 	for (n = 0; n < 4; n++) {
825 		lws_snprintf(slot, sizeof(slot) - 1, "%dssid", n);
826 		s = sizeof(lws_esp32.ssid[0]) - 1;
827 		lws_esp32.ssid[n][0] = '\0';
828 		nvs_get_str(nvh, slot, lws_esp32.ssid[n], &s);
829 
830 		lws_snprintf(slot, sizeof(slot) - 1, "%dpassword", n);
831 		s = sizeof(lws_esp32.password[0]) - 1;
832 		lws_esp32.password[n][0] = '\0';
833 		nvs_get_str(nvh, slot, lws_esp32.password[n], &s);
834 	}
835 
836 	s = sizeof(lws_esp32.serial) - 1;
837 	if (nvs_get_str(nvh, "serial", lws_esp32.serial, &s) != ESP_OK)
838 		lws_esp32_force_ap = 1;
839 	else
840 		snprintf((char *)config.ap.ssid, sizeof(config.ap.ssid) - 1,
841 			 "config-%s-%s", lws_esp32.model, lws_esp32.serial);
842 	s = sizeof(lws_esp32.opts) - 1;
843 	if (nvs_get_str(nvh, "opts", lws_esp32.opts, &s) != ESP_OK)
844 		lws_esp32_force_ap = 1;
845 
846 	lws_esp32.access_pw[0] = '\0';
847 	nvs_get_str(nvh, "access_pw", lws_esp32.access_pw, &s);
848 
849 	lws_esp32.group[0] = '\0';
850 	s = sizeof(lws_esp32.group);
851 	nvs_get_str(nvh, "group", lws_esp32.group, &s);
852 
853 	lws_esp32.role[0] = '\0';
854 	s = sizeof(lws_esp32.role);
855 	nvs_get_str(nvh, "role", lws_esp32.role, &s);
856 
857 	/* if group and role defined: group-role */
858 	if (lws_esp32.group[0] && lws_esp32.role[0])
859 		lws_snprintf(lws_esp32.hostname, sizeof(lws_esp32.hostname) - 1,
860 				"%s-%s", lws_esp32.group, lws_esp32.role);
861 	else /* otherwise model-serial */
862 		lws_snprintf(lws_esp32.hostname, sizeof(lws_esp32.hostname) - 1,
863 				"%s-%s", lws_esp32.model, lws_esp32.serial);
864 
865 	nvs_close(nvh);
866 
867 	lws_gapss_to(LWS_GAPSS_SCAN);
868 	start_scan();
869 
870 	return lws_esp32_force_ap;
871 }
872 
873 
874 void
lws_esp32_wlan_config(void)875 lws_esp32_wlan_config(void)
876 {
877 	ledc_timer_config_t ledc_timer = {
878 	        .bit_num = LEDC_TIMER_13_BIT,
879 	        .freq_hz = 5000,
880 	        .speed_mode = LEDC_HIGH_SPEED_MODE,
881 	        .timer_num = LEDC_TIMER_0
882 	};
883 	int n;
884 
885 	lwsl_debug("%s\n", __func__);
886 
887 	ledc_timer_config(&ledc_timer);
888 
889 	lws_set_genled(LWSESP32_GENLED__INIT);
890 
891 	/* user code needs to provide lws_esp32_leds_timer_cb */
892 
893         leds_timer = xTimerCreate("lws_leds", pdMS_TO_TICKS(25), 1, NULL,
894                           (TimerCallbackFunction_t)lws_esp32_leds_timer_cb);
895         scan_timer = xTimerCreate("lws_scan", pdMS_TO_TICKS(10000), 0, NULL,
896                           (TimerCallbackFunction_t)lws_esp32_scan_timer_cb);
897         debounce_timer = xTimerCreate("lws_db", pdMS_TO_TICKS(100), 0, NULL,
898                           (TimerCallbackFunction_t)lws_esp32_debounce_timer_cb);
899         association_timer = xTimerCreate("lws_assoc", pdMS_TO_TICKS(10000), 0, NULL,
900                           (TimerCallbackFunction_t)lws_esp32_assoc_timer_cb);
901 
902 #if !defined(CONFIG_LWS_IS_FACTORY_APPLICATION)
903         mdns_timer = xTimerCreate("lws_mdns", pdMS_TO_TICKS(5000), 0, NULL,
904                           (TimerCallbackFunction_t)lws_esp32_mdns_timer_cb);
905 #endif
906 	scan_timer_exists = 1;
907         xTimerStart(leds_timer, 0);
908 
909 	*(volatile uint32_t *)PERIPHS_IO_MUX_MTMS_U = FUNC_MTMS_GPIO14;
910 
911 	gpio_output_set(0, 0, 0, (1 << GPIO_SW));
912 
913 	n = gpio_install_isr_service(0);
914 	if (!n) {
915 		gpio_config_t c;
916 
917 		c.intr_type = GPIO_INTR_NEGEDGE;
918 		c.mode = GPIO_MODE_INPUT;
919 		c.pin_bit_mask = 1 << GPIO_SW;
920 		c.pull_down_en = 0;
921 		c.pull_up_en = 0;
922 		gpio_config(&c);
923 
924 		if (gpio_isr_handler_add(GPIO_SW, gpio_irq, NULL))
925 			lwsl_notice("isr handler add for 14 failed\n");
926 	} else
927 		lwsl_notice("failed to install gpio isr service: %d\n", n);
928 
929 	lws_esp32_wlan_nvs_get(0);
930 	tcpip_adapter_init();
931 }
932 
933 void
lws_esp32_wlan_start_ap(void)934 lws_esp32_wlan_start_ap(void)
935 {
936 	wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
937 
938 	ESP_ERROR_CHECK( esp_wifi_init(&cfg));
939 	ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM));
940 
941 	ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_APSTA) );
942 	ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_AP, &config) );
943 	ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config));
944 	ESP_ERROR_CHECK( esp_wifi_start());
945 
946 	esp_wifi_scan_start(&scan_config, false);
947 
948 	if (sta_config.sta.ssid[0]) {
949 		tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA,
950 					   (const char *)&config.ap.ssid[7]);
951 		// esp_wifi_set_auto_connect(1);
952 		ESP_ERROR_CHECK( esp_wifi_connect());
953 		ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config));
954 		ESP_ERROR_CHECK( esp_wifi_connect());
955 	}
956 }
957 
958 void
lws_esp32_wlan_start_station(void)959 lws_esp32_wlan_start_station(void)
960 {
961 	wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
962 
963 	ESP_ERROR_CHECK( esp_wifi_init(&cfg));
964 	ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM));
965 
966 	ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA));
967 	ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config));
968 
969 	ESP_ERROR_CHECK( esp_wifi_start());
970 
971 	tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA,
972 				   (const char *)&config.ap.ssid[7]);
973 	//esp_wifi_set_auto_connect(1);
974 	//ESP_ERROR_CHECK( esp_wifi_connect());
975 
976 	lws_esp32_scan_timer_cb(NULL);
977 }
978 
979 const esp_partition_t *
lws_esp_ota_get_boot_partition(void)980 lws_esp_ota_get_boot_partition(void)
981 {
982 	const esp_partition_t *part = esp_ota_get_boot_partition(),
983 			      *factory_part, *ota;
984 	esp_image_header_t eih, ota_eih;
985 	uint32_t *p_force_factory_magic = (uint32_t *)LWS_MAGIC_REBOOT_TYPE_ADS;
986 
987 	/* confirm what we are told is the boot part is sane */
988 	spi_flash_read(part->address , &eih, sizeof(eih));
989 	factory_part = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
990 			ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
991  	ota = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
992 			ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL);
993 	spi_flash_read(ota->address , &ota_eih, sizeof(ota_eih));
994 
995 	if (eih.spi_mode == 0xff ||
996 	    *p_force_factory_magic == LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY ||
997 	    *p_force_factory_magic == LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON
998 	) {
999 		/*
1000 		 * we believed we were going to boot OTA, but we fell
1001 		 * back to FACTORY in the bootloader when we saw it
1002 		 * had been erased.  esp_ota_get_boot_partition() still
1003 		 * says the OTA partition then even if we are in the
1004 		 * factory partition right now.
1005 		 */
1006 		part = factory_part;
1007 	}
1008 
1009 #ifdef CONFIG_LWS_IS_FACTORY_APPLICATION
1010 	else
1011 		if (ota_eih.spi_mode != 0xff &&
1012 		    part->address != factory_part->address) {
1013 			uint8_t buf[4096];
1014 			uint32_t n;
1015 			/*
1016 			 * we are a FACTORY image running in an OTA slot...
1017 			 * it means we were just written and need to copy
1018 			 * ourselves into the FACTORY slot.
1019 			 */
1020 			lwsl_notice("Copying FACTORY update into place "
1021 				    "0x%x len 0x%x\n", factory_part->address,
1022 				    factory_part->size);
1023 			esp_task_wdt_reset();
1024 			if (spi_flash_erase_range(factory_part->address,
1025 						  factory_part->size)) {
1026 	               	        lwsl_err("spi: Failed to erase\n");
1027 	               	        goto retry;
1028 	               	}
1029 
1030 			for (n = 0; n < factory_part->size; n += sizeof(buf)) {
1031 				esp_task_wdt_reset();
1032 				spi_flash_read(part->address + n , buf,
1033 					       sizeof(buf));
1034 				if (spi_flash_write(factory_part->address + n,
1035 						    buf, sizeof(buf))) {
1036 	                	        lwsl_err("spi: Failed to write\n");
1037 	                	        goto retry;
1038 	                	}
1039 			}
1040 
1041 			/*
1042 			 * We send a message to the bootloader to erase the OTA header, we will come back up in
1043 			 * factory where the user can reload the OTA image
1044 			 */
1045 			lwsl_notice("  FACTORY copy successful, rebooting\n");
1046 			lws_esp32_restart_guided(LWS_MAGIC_REBOOT_TYPE_REQ_FACTORY_ERASE_OTA);
1047 retry:
1048 			esp_restart();
1049 		}
1050 #endif
1051 
1052 	return part;
1053 }
1054 
1055 
1056 void
lws_esp32_set_creation_defaults(struct lws_context_creation_info * info)1057 lws_esp32_set_creation_defaults(struct lws_context_creation_info *info)
1058 {
1059 	const esp_partition_t *part;
1060 
1061 	memset(info, 0, sizeof(*info));
1062 
1063 	lws_set_log_level(63, lwsl_emit_syslog);
1064 
1065 	part = lws_esp_ota_get_boot_partition();
1066 	(void)part;
1067 
1068 	info->vhost_name = "default";
1069 	info->port = 443;
1070 	info->fd_limit_per_thread = 16;
1071 	info->max_http_header_pool = 5;
1072 	info->max_http_header_data = 1024;
1073 	info->pt_serv_buf_size = 4096;
1074 	info->keepalive_timeout = 30;
1075 	info->timeout_secs = 30;
1076 	info->simultaneous_ssl_restriction = 2;
1077 	info->options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
1078 		        LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
1079 }
1080 
1081 int
lws_esp32_get_image_info(const esp_partition_t * part,struct lws_esp32_image * i,char * json,int json_len)1082 lws_esp32_get_image_info(const esp_partition_t *part, struct lws_esp32_image *i,
1083 			 char *json, int json_len)
1084 {
1085 	esp_image_segment_header_t eis;
1086 	esp_image_header_t eih;
1087 	uint32_t hdr;
1088 
1089 	spi_flash_read(part->address , &eih, sizeof(eih));
1090 	hdr = part->address + sizeof(eih);
1091 
1092 	if (eih.magic != ESP_IMAGE_HEADER_MAGIC) {
1093 		lwsl_notice("%s: bad image header magic\n", __func__);
1094 		return 1;
1095 	}
1096 
1097 	eis.data_len = 0;
1098 	while (eih.segment_count-- && eis.data_len != 0xffffffff) {
1099 		spi_flash_read(hdr, &eis, sizeof(eis));
1100 		hdr += sizeof(eis) + eis.data_len;
1101 	}
1102 	hdr += (~hdr & 15) + 1;
1103 
1104 	if (eih.hash_appended)
1105 		hdr += 0x20;
1106 
1107 //	lwsl_notice("romfs estimated at 0x%x\n", hdr);
1108 
1109 	i->romfs = hdr + 0x4;
1110 	spi_flash_read(hdr, &i->romfs_len, sizeof(i->romfs_len));
1111 	i->json = i->romfs + i->romfs_len + 4;
1112 	spi_flash_read(i->json - 4, &i->json_len, sizeof(i->json_len));
1113 
1114 	if (i->json_len < json_len - 1)
1115 		json_len = i->json_len;
1116 	spi_flash_read(i->json, json, json_len);
1117 	json[json_len] = '\0';
1118 
1119 	return 0;
1120 }
1121 
1122 static int
_rngf(void * context,unsigned char * buf,size_t len)1123 _rngf(void *context, unsigned char *buf, size_t len)
1124 {
1125 	if (lws_get_random(context, buf, len) == len)
1126 		return 0;
1127 
1128 	return -1;
1129 }
1130 
1131 int
lws_esp32_selfsigned(struct lws_vhost * vhost)1132 lws_esp32_selfsigned(struct lws_vhost *vhost)
1133 {
1134 	mbedtls_x509write_cert crt;
1135 	char subject[200];
1136 	mbedtls_pk_context mpk;
1137 	int buf_size = 4096, n;
1138 	uint8_t *buf = malloc(buf_size); /* malloc because given to user code */
1139 	mbedtls_mpi mpi;
1140 	nvs_handle nvh;
1141 	size_t s;
1142 
1143 	lwsl_notice("%s: %s\n", __func__, vhost->name);
1144 
1145 	if (!buf)
1146 		return -1;
1147 
1148 	if (nvs_open("lws-station", NVS_READWRITE, &nvh)) {
1149 		lwsl_notice("%s: can't open nvs\n", __func__);
1150 		free(buf);
1151 		return 1;
1152 	}
1153 
1154 	n = 0;
1155 	if (!nvs_get_blob(nvh, vhost->tls.alloc_cert_path, NULL, &s))
1156 		n |= 1;
1157 	if (!nvs_get_blob(nvh, vhost->tls.key_path, NULL, &s))
1158 		n |= 2;
1159 
1160 	nvs_close(nvh);
1161 	if (n == 3) {
1162 		lwsl_notice("%s: certs exist\n", __func__);
1163 		free(buf);
1164 		return 0; /* certs already exist */
1165 	}
1166 
1167 	lwsl_notice("%s: creating selfsigned initial certs\n", __func__);
1168 
1169 	mbedtls_x509write_crt_init(&crt);
1170 
1171 	mbedtls_pk_init(&mpk);
1172 	if (mbedtls_pk_setup(&mpk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA))) {
1173 		lwsl_notice("%s: pk_setup failed\n", __func__);
1174 		goto fail;
1175 	}
1176 	lwsl_notice("%s: generating 2048-bit RSA keypair... "
1177 		    "this may take a minute or so...\n", __func__);
1178 	n = mbedtls_rsa_gen_key(mbedtls_pk_rsa(mpk), _rngf, vhost->context,
1179 				2048, 65537);
1180 	if (n) {
1181 		lwsl_notice("%s: failed to generate keys\n", __func__);
1182 		goto fail1;
1183 	}
1184 	lwsl_notice("%s: keys done\n", __func__);
1185 
1186 	/* subject must be formatted like "C=TW,O=warmcat,CN=myserver" */
1187 
1188 	lws_snprintf(subject, sizeof(subject) - 1,
1189 		     "C=TW,ST=New Taipei City,L=Taipei,O=warmcat,CN=%s",
1190 		     lws_esp32.hostname);
1191 
1192 	if (mbedtls_x509write_crt_set_subject_name(&crt, subject)) {
1193 		lwsl_notice("set SN failed\n");
1194 		goto fail1;
1195 	}
1196 	mbedtls_x509write_crt_set_subject_key(&crt, &mpk);
1197 	if (mbedtls_x509write_crt_set_issuer_name(&crt, subject)) {
1198 		lwsl_notice("set IN failed\n");
1199 		goto fail1;
1200 	}
1201 	mbedtls_x509write_crt_set_issuer_key(&crt, &mpk);
1202 
1203 	lws_get_random(vhost->context, &n, sizeof(n));
1204 	lws_snprintf(subject, sizeof(subject), "%d", n);
1205 
1206 	mbedtls_mpi_init(&mpi);
1207 	mbedtls_mpi_read_string(&mpi, 10, subject);
1208 	mbedtls_x509write_crt_set_serial(&crt, &mpi);
1209 	mbedtls_mpi_free(&mpi);
1210 
1211 	mbedtls_x509write_crt_set_validity(&crt, "20171105235959",
1212 					   "20491231235959");
1213 
1214 	mbedtls_x509write_crt_set_key_usage(&crt,
1215 					    MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
1216 					    MBEDTLS_X509_KU_KEY_ENCIPHERMENT);
1217 
1218 
1219 	mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256);
1220 
1221 	n = mbedtls_x509write_crt_pem(&crt, buf, buf_size, _rngf,
1222 				      vhost->context);
1223 	if (n < 0) {
1224 		lwsl_notice("%s: write crt der failed\n", __func__);
1225 		goto fail1;
1226 	}
1227 
1228 	lws_plat_write_cert(vhost, 0, 0, buf, strlen((const char *)buf));
1229 
1230 	if (mbedtls_pk_write_key_pem(&mpk, buf, buf_size)) {
1231 		lwsl_notice("write key pem failed\n");
1232 		goto fail1;
1233 	}
1234 
1235 	lws_plat_write_cert(vhost, 1, 0, buf, strlen((const char *)buf));
1236 
1237 	mbedtls_pk_free(&mpk);
1238 	mbedtls_x509write_crt_free(&crt);
1239 
1240 	lwsl_notice("%s: cert creation complete\n", __func__);
1241 
1242 	return n;
1243 
1244 fail1:
1245 	mbedtls_pk_free(&mpk);
1246 fail:
1247 	mbedtls_x509write_crt_free(&crt);
1248 	free(buf);
1249 
1250 	nvs_close(nvh);
1251 
1252 	return -1;
1253 }
1254 
1255 void
lws_esp32_update_acme_info(void)1256 lws_esp32_update_acme_info(void)
1257 {
1258         int n;
1259 
1260 	n = lws_plat_read_file("acme-email", lws_esp32.le_email,
1261 			       sizeof(lws_esp32.le_email) - 1);
1262 	if (n >= 0)
1263 		lws_esp32.le_email[n] = '\0';
1264 
1265 	n = lws_plat_read_file("acme-cn", lws_esp32.le_dns,
1266 			       sizeof(lws_esp32.le_dns) - 1);
1267 	if (n >= 0)
1268 		lws_esp32.le_dns[n] = '\0';
1269 }
1270 
1271 struct lws_context *
lws_esp32_init(struct lws_context_creation_info * info,struct lws_vhost ** pvh)1272 lws_esp32_init(struct lws_context_creation_info *info, struct lws_vhost **pvh)
1273 {
1274 	const esp_partition_t *part = lws_esp_ota_get_boot_partition();
1275 	struct lws_context *context;
1276 	struct lws_esp32_image i;
1277 	struct lws_vhost *vhost;
1278 	struct lws wsi;
1279 	char buf[512];
1280 
1281 	context = lws_create_context(info);
1282 	if (context == NULL) {
1283 		lwsl_err("Failed to create context\n");
1284 		return NULL;
1285 	}
1286 
1287 	lws_esp32_get_image_info(part, &i, buf, sizeof(buf) - 1);
1288 
1289 	lws_esp32_romfs = (romfs_t)i.romfs;
1290 	if (!romfs_mount_check(lws_esp32_romfs)) {
1291 		lwsl_err("mount error on ROMFS at %p 0x%x\n", lws_esp32_romfs,
1292 			 i.romfs);
1293 		return NULL;
1294 	}
1295 
1296 	lwsl_notice("ROMFS length %uKiB\n", i.romfs_len >> 10);
1297 
1298 	puts(buf);
1299 
1300 	/* set the lws vfs to use our romfs */
1301 #if defined(LWS_WITH_FILE_OPS)
1302 	lws_set_fops(context, &fops);
1303 #endif
1304 
1305 	info->options |= LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX |
1306 			 LWS_SERVER_OPTION_IGNORE_MISSING_CERT;
1307 
1308 	vhost = lws_create_vhost(context, info);
1309 	if (!vhost) {
1310 		lwsl_err("Failed to create vhost\n");
1311 		return NULL;
1312 	}
1313 
1314 	lws_esp32_update_acme_info();
1315 
1316 	lws_esp32_selfsigned(vhost);
1317 	wsi.context = vhost->context;
1318 	wsi.vhost = vhost;
1319 
1320 	lws_tls_server_certs_load(vhost, &wsi, info->ssl_cert_filepath,
1321 			info->ssl_private_key_filepath, NULL, 0, NULL, 0);
1322 
1323 	lws_init_vhost_client_ssl(info, vhost);
1324 
1325 	if (pvh)
1326 		*pvh = vhost;
1327 
1328 	if (lws_protocol_init(context))
1329 		return NULL;
1330 
1331 	return context;
1332 }
1333 
1334 static const uint16_t sineq16[] = {
1335         0x0000, 0x0191, 0x031e, 0x04a4, 0x061e, 0x0789, 0x08e2, 0x0a24,
1336         0x0b4e, 0x0c5c, 0x0d4b, 0x0e1a, 0x0ec6, 0x0f4d, 0x0faf, 0x0fea,
1337 };
1338 
sine_lu(int n)1339 static uint16_t sine_lu(int n)
1340 {
1341         switch ((n >> 4) & 3) {
1342         case 1:
1343                 return 4096 + sineq16[n & 15];
1344         case 2:
1345                 return 4096 + sineq16[15 - (n & 15)];
1346         case 3:
1347                 return 4096 - sineq16[n & 15];
1348         default:
1349                 return  4096 - sineq16[15 - (n & 15)];
1350         }
1351 }
1352 
1353 /* useful for sine led fade patterns */
1354 
lws_esp32_sine_interp(int n)1355 uint16_t lws_esp32_sine_interp(int n)
1356 {
1357         /*
1358          * 2: quadrant
1359          * 4: table entry in quadrant
1360          * 4: interp (LSB)
1361          *
1362          * total 10 bits / 1024 steps per cycle
1363 	 *
1364 	 * +   0: 0
1365 	 * + 256: 4096
1366 	 * + 512: 8192
1367 	 * + 768: 4096
1368 	 * +1023: 0
1369          */
1370 
1371         return (sine_lu(n >> 4) * (15 - (n & 15)) +
1372                 sine_lu((n >> 4) + 1) * (n & 15)) / 15;
1373 }
1374