@@ -62,7 +62,8 @@ static struct mg_connection *s_conn = NULL;
62
62
static bool s_connected = false;
63
63
static mgos_mqtt_connect_fn_t s_connect_fn = NULL ;
64
64
static void * s_connect_fn_arg = NULL ;
65
- static struct mgos_config_mqtt * s_cfg = NULL ;
65
+ static const struct mgos_config_mqtt * s_cfg = NULL ;
66
+ static int s_max_qos = -1 ;
66
67
67
68
SLIST_HEAD (topic_handlers , topic_handler ) s_topic_handlers ;
68
69
SLIST_HEAD (global_handlers , global_handler ) s_global_handlers ;
@@ -72,11 +73,14 @@ static void mqtt_global_reconnect(void);
72
73
void mgos_mqtt_set_max_qos (int qos ) {
73
74
if (s_cfg == NULL || s_cfg -> max_qos == qos ) return ;
74
75
LOG (LL_INFO , ("Setting max MQTT QOS to %d" , qos ));
75
- s_cfg -> max_qos = qos ;
76
+ s_max_qos = qos ;
76
77
}
77
78
78
79
static int adjust_qos (int qos ) {
79
- return s_cfg != NULL && s_cfg -> max_qos < qos ? s_cfg -> max_qos : qos ;
80
+ int max_qos = s_max_qos ;
81
+ if (max_qos < 0 && s_cfg != NULL ) max_qos = s_cfg -> max_qos ;
82
+ if (max_qos < 0 ) return qos ;
83
+ return MIN (qos , max_qos );
80
84
}
81
85
82
86
uint16_t mgos_mqtt_get_packet_id (void ) {
@@ -123,10 +127,13 @@ static void do_subscribe(struct topic_handler *th) {
123
127
124
128
static void mgos_mqtt_ev (struct mg_connection * nc , int ev , void * ev_data ,
125
129
void * user_data ) {
130
+ if (nc != s_conn ) {
131
+ nc -> flags |= MG_F_CLOSE_IMMEDIATELY ;
132
+ return ;
133
+ }
126
134
if (ev > MG_MQTT_EVENT_BASE ) {
127
135
LOG (LL_DEBUG , ("MQTT event: %d" , ev ));
128
136
}
129
-
130
137
switch (ev ) {
131
138
case MG_EV_CONNECT : {
132
139
int status = * ((int * ) ev_data );
@@ -279,6 +286,7 @@ static void mgos_mqtt_free_config(struct mgos_config_mqtt *cfg) {
279
286
free (cfg -> will_topic );
280
287
free (cfg -> will_message );
281
288
memset (cfg , 0 , sizeof (* cfg ));
289
+ free (cfg );
282
290
}
283
291
284
292
bool mgos_mqtt_set_config (const struct mgos_config_mqtt * cfg ) {
@@ -295,13 +303,7 @@ bool mgos_mqtt_set_config(const struct mgos_config_mqtt *cfg) {
295
303
new_cfg = (struct mgos_config_mqtt * ) calloc (1 , sizeof (* new_cfg ));
296
304
if (new_cfg == NULL ) goto out ;
297
305
new_cfg -> enable = cfg -> enable ;
298
- if (strchr (cfg -> server , ':' ) == NULL ) {
299
- int port = (cfg -> ssl_ca_cert != NULL ? 8883 : 1883 );
300
- mg_asprintf (& new_cfg -> server , 0 , "%s:%d" , cfg -> server , port );
301
- if (new_cfg -> server == NULL ) goto out ;
302
- } else {
303
- new_cfg -> server = strdup (cfg -> server );
304
- }
306
+ new_cfg -> server = strdup (cfg -> server );
305
307
if (cfg -> client_id ) new_cfg -> client_id = strdup (cfg -> client_id );
306
308
if (cfg -> user ) new_cfg -> user = strdup (cfg -> user );
307
309
if (cfg -> pass ) new_cfg -> pass = strdup (cfg -> pass );
@@ -310,10 +312,12 @@ bool mgos_mqtt_set_config(const struct mgos_config_mqtt *cfg) {
310
312
if (cfg -> ssl_cert ) new_cfg -> ssl_cert = strdup (cfg -> ssl_cert );
311
313
if (cfg -> ssl_key ) new_cfg -> ssl_key = strdup (cfg -> ssl_key );
312
314
if (cfg -> ssl_ca_cert ) new_cfg -> ssl_ca_cert = strdup (cfg -> ssl_ca_cert );
313
- if (cfg -> ssl_cipher_suites )
315
+ if (cfg -> ssl_cipher_suites ) {
314
316
new_cfg -> ssl_cipher_suites = strdup (cfg -> ssl_cipher_suites );
315
- if (cfg -> ssl_psk_identity )
317
+ }
318
+ if (cfg -> ssl_psk_identity ) {
316
319
new_cfg -> ssl_psk_identity = strdup (cfg -> ssl_psk_identity );
320
+ }
317
321
if (cfg -> ssl_psk_key ) new_cfg -> ssl_psk_key = strdup (cfg -> ssl_psk_key );
318
322
new_cfg -> clean_session = cfg -> clean_session ;
319
323
new_cfg -> keep_alive = cfg -> keep_alive ;
@@ -326,14 +330,20 @@ bool mgos_mqtt_set_config(const struct mgos_config_mqtt *cfg) {
326
330
327
331
out :
328
332
if (ret ) {
333
+ const struct mgos_config_mqtt * old_cfg = s_cfg ;
329
334
s_cfg = new_cfg ;
330
335
if (s_conn != NULL ) {
331
336
s_conn -> flags |= MG_F_CLOSE_IMMEDIATELY ;
332
337
s_conn = NULL ;
333
338
}
339
+ const struct mgos_config_mqtt * cfg0 = mgos_sys_config_get_mqtt ();
340
+ const struct mgos_config_mqtt * cfg1 =
341
+ (const struct mgos_config_mqtt * ) mgos_sys_config_get_mqtt1 ();
342
+ if (old_cfg != NULL && old_cfg != cfg0 && old_cfg != cfg1 ) {
343
+ mgos_mqtt_free_config ((struct mgos_config_mqtt * ) old_cfg );
344
+ }
334
345
} else {
335
346
mgos_mqtt_free_config (new_cfg );
336
- free (new_cfg );
337
347
}
338
348
return ret ;
339
349
}
@@ -355,15 +365,19 @@ bool mgos_mqtt_init(void) {
355
365
mgos_event_add_group_handler (MGOS_EVENT_GRP_NET , mgos_mqtt_net_ev , NULL );
356
366
mgos_event_add_handler (MGOS_EVENT_LOG , s_debug_write_cb , NULL );
357
367
358
- return mgos_mqtt_set_config (mgos_sys_config_get_mqtt ());
368
+ s_cfg = mgos_sys_config_get_mqtt ();
369
+ return true;
359
370
}
360
371
361
372
bool mgos_mqtt_global_connect (void ) {
362
373
bool ret = true;
374
+ char * server = NULL ;
363
375
struct mg_mgr * mgr = mgos_get_mgr ();
364
376
struct mg_connect_opts opts ;
365
377
366
- if (s_cfg == NULL || !s_cfg -> enable ) return false;
378
+ if (s_cfg == NULL || !s_cfg -> enable || s_cfg -> server == NULL ) {
379
+ return false;
380
+ }
367
381
368
382
/* If we're already connected, do nothing */
369
383
if (s_conn != NULL ) return true;
@@ -377,17 +391,25 @@ bool mgos_mqtt_global_connect(void) {
377
391
opts .ssl_psk_identity = s_cfg -> ssl_psk_identity ;
378
392
opts .ssl_psk_key = s_cfg -> ssl_psk_key ;
379
393
#endif
380
- LOG (LL_INFO , ("MQTT connecting to %s" , s_cfg -> server ));
394
+ if (strchr (s_cfg -> server , ':' ) == NULL ) {
395
+ int port = (s_cfg -> ssl_ca_cert != NULL ? 8883 : 1883 );
396
+ mg_asprintf (& server , 0 , "%s:%d" , s_cfg -> server , port );
397
+ if (server == NULL ) return false;
398
+ } else {
399
+ server = strdup (s_cfg -> server );
400
+ }
401
+ LOG (LL_INFO , ("MQTT connecting to %s" , server ));
381
402
382
403
s_connected = false;
383
- s_conn = mg_connect_opt (mgr , s_cfg -> server , mgos_mqtt_ev , NULL , opts );
404
+ s_conn = mg_connect_opt (mgr , server , mgos_mqtt_ev , NULL , opts );
384
405
if (s_conn != NULL ) {
385
406
mg_set_protocol_mqtt (s_conn );
386
407
s_conn -> recv_mbuf_limit = s_cfg -> recv_mbuf_limit ;
387
408
} else {
388
409
mqtt_global_reconnect ();
389
410
ret = false;
390
411
}
412
+ free (server );
391
413
return ret ;
392
414
}
393
415
@@ -397,11 +419,35 @@ static void reconnect_timer_cb(void *user_data) {
397
419
(void ) user_data ;
398
420
}
399
421
422
+ static void mqtt_switch_config (void ) {
423
+ const struct mgos_config_mqtt * cfg0 = mgos_sys_config_get_mqtt ();
424
+ const struct mgos_config_mqtt * cfg1 =
425
+ (const struct mgos_config_mqtt * ) mgos_sys_config_get_mqtt1 ();
426
+ const struct mgos_config_mqtt * cfg ;
427
+ if (s_cfg == cfg0 ) {
428
+ cfg = cfg1 ;
429
+ } else if (s_cfg == cfg1 ) {
430
+ cfg = cfg0 ;
431
+ } else {
432
+ /* User set a custom config - don't mess with it. */
433
+ return ;
434
+ }
435
+ if (cfg -> enable ) {
436
+ s_cfg = cfg ;
437
+ s_reconnect_timeout_ms = s_cfg -> reconnect_timeout_min * 1000 ;
438
+ }
439
+ }
440
+
400
441
static void mqtt_global_reconnect (void ) {
401
442
int rt_ms ;
402
443
if (s_cfg == NULL || s_cfg -> server == NULL ) return ;
403
444
404
- if (s_reconnect_timeout_ms <= 0 ) s_reconnect_timeout_ms = 1 ;
445
+ if (s_reconnect_timeout_ms >= s_cfg -> reconnect_timeout_max * 1000 ) {
446
+ mqtt_switch_config ();
447
+ }
448
+
449
+ if (s_reconnect_timeout_ms <= 0 ) s_reconnect_timeout_ms = 1000 ;
450
+
405
451
rt_ms = s_reconnect_timeout_ms * 2 ;
406
452
407
453
if (rt_ms < s_cfg -> reconnect_timeout_min * 1000 ) {
@@ -410,13 +456,11 @@ static void mqtt_global_reconnect(void) {
410
456
if (rt_ms > s_cfg -> reconnect_timeout_max * 1000 ) {
411
457
rt_ms = s_cfg -> reconnect_timeout_max * 1000 ;
412
458
}
459
+ s_reconnect_timeout_ms = rt_ms ;
413
460
/* Fuzz the time a little. */
414
461
rt_ms = (int ) mgos_rand_range (rt_ms * 0.9 , rt_ms * 1.1 );
415
462
LOG (LL_INFO , ("MQTT connecting after %d ms" , rt_ms ));
416
- s_reconnect_timeout_ms = rt_ms ;
417
- if (s_reconnect_timer_id != MGOS_INVALID_TIMER_ID ) {
418
- mgos_clear_timer (s_reconnect_timer_id );
419
- }
463
+ mgos_clear_timer (s_reconnect_timer_id );
420
464
s_reconnect_timer_id = mgos_set_timer (rt_ms , 0 , reconnect_timer_cb , NULL );
421
465
}
422
466
0 commit comments