@@ -127,7 +127,7 @@ struct SSDPTimer {
127127
128128SSDPClass::SSDPClass () :
129129 _server(0 ),
130- _timer(new SSDPTimer ),
130+ _timer(0 ),
131131 _port(80 ),
132132 _ttl(SSDP_MULTICAST_TTL),
133133 _respondToPort(0 ),
@@ -150,27 +150,26 @@ SSDPClass::SSDPClass() :
150150}
151151
152152SSDPClass::~SSDPClass () {
153- delete _timer ;
153+ end () ;
154154}
155155
156156bool SSDPClass::begin () {
157+ end ();
158+
157159 _pending = false ;
158160 if (strcmp (_uuid," " ) == 0 ) {
159161 uint32_t chipId = ESP.getChipId ();
160162 sprintf (_uuid, " 38323636-4558-4dda-9188-cda0e6%02x%02x%02x" ,
161163 (uint16_t ) ((chipId >> 16 ) & 0xff ),
162164 (uint16_t ) ((chipId >> 8 ) & 0xff ),
163- (uint16_t ) chipId & 0xff );
165+ (uint16_t ) chipId & 0xff );
164166 }
165167
166168#ifdef DEBUG_SSDP
167169 DEBUG_SSDP.printf (" SSDP UUID: %s\n " , (char *)_uuid);
168170#endif
169171
170- if (_server) {
171- _server->unref ();
172- _server = 0 ;
173- }
172+ assert (NULL == _server);
174173
175174 _server = new UdpContext;
176175 _server->ref ();
@@ -199,6 +198,34 @@ bool SSDPClass::begin() {
199198 return true ;
200199}
201200
201+ void SSDPClass::end () {
202+ if (!_server)
203+ return ; // object is zeroed already, nothing to do
204+
205+ #ifdef DEBUG_SSDP
206+ DEBUG_SSDP.printf_P (PSTR (" SSDP end ... " ));
207+ #endif
208+ // undo all initializations done in begin(), in reverse order
209+ _stopTimer ();
210+
211+ _server->disconnect ();
212+
213+ IPAddress local = WiFi.localIP ();
214+ IPAddress mcast (SSDP_MULTICAST_ADDR);
215+
216+ if (igmp_leavegroup (local, mcast) != ERR_OK ) {
217+ #ifdef DEBUG_SSDP
218+ DEBUG_SSDP.printf_P (PSTR (" SSDP failed to leave igmp group\n " ));
219+ #endif
220+ }
221+
222+ _server->unref ();
223+ _server = 0 ;
224+
225+ #ifdef DEBUG_SSDP
226+ DEBUG_SSDP.printf_P (PSTR (" ok\n " ));
227+ #endif
228+ }
202229void SSDPClass::_send (ssdp_method_t method) {
203230 char buffer[1460 ];
204231 IPAddress ip = WiFi.localIP ();
@@ -461,13 +488,25 @@ void SSDPClass::_onTimerStatic(SSDPClass* self) {
461488}
462489
463490void SSDPClass::_startTimer () {
491+ _stopTimer ();
492+ _timer = new SSDPTimer ();
464493 ETSTimer* tm = &(_timer->timer );
465494 const int interval = 1000 ;
466495 os_timer_disarm (tm);
467496 os_timer_setfn (tm, reinterpret_cast <ETSTimerFunc*>(&SSDPClass::_onTimerStatic), reinterpret_cast <void *>(this ));
468497 os_timer_arm (tm, interval, 1 /* repeat */ );
469498}
470499
500+ void SSDPClass::_stopTimer () {
501+ if (!_timer)
502+ return ;
503+
504+ ETSTimer* tm = &(_timer->timer );
505+ os_timer_disarm (tm);
506+ delete _timer;
507+ _timer = NULL ;
508+ }
509+
471510#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SSDP)
472511SSDPClass SSDP;
473512#endif
0 commit comments