tplinkrouterc6u 5.13.0__py3-none-any.whl → 5.14.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
test/test_client_ex.py CHANGED
@@ -284,6 +284,125 @@ class TestTPLinkEXClient(TestCase):
284
284
  self.assertEqual(status.devices[1].packets_sent, None) # TODO
285
285
  self.assertEqual(status.devices[1].packets_received, None) # TODO
286
286
 
287
+ def test_get_status_M8550(self) -> None:
288
+ DEV2_ADT_LAN = ('{"data":[{"MACAddress":"a0:28:84:de:dd:5c","IPAddress":"192.168.4.1","stack":"1,0,0,0,0,0"}],'
289
+ '"operation":"gl","oid":"DEV2_ADT_LAN","success":true}')
290
+ DEV2_ADT_WAN = ('{"data":[{"enable":"1","MACAddr":"","connIPv4Address":"","connIPv4Gateway":""'
291
+ ',"stack":"1,0,0,0,0,0"}],"operation":"gl","oid":"DEV2_ADT_WAN","success":true}')
292
+ DEV2_ADT_WIFI_COMMON = ('{"data": [{"band": "2.4GHz","standard": "bgnax","bandwidth": "Auto",'
293
+ '"currentBandwidth": "20MHz","autoChannel": "1","channel": "1","transmitPower": "100",'
294
+ '"beaconInterval": "100","RTSThreshold": "2346","DTIMPeriod": "1",'
295
+ '"fragmentThreshold": "2346","regulatoryDomain": "DE ","guardInterval": "400nsec",'
296
+ '"primaryEnable": "1","primaryBSSID": "b8:7a:96:53:db:e2","primaryStatus": "Enabled",'
297
+ '"primarySSID": "JustAnotherWiFi","primarySSIDAdvertise": "1",'
298
+ '"primaryModeEnabled": "WPA2-Personal","primaryWPAWPA2EncryptionMode": "AES",'
299
+ '"primaryPSK": "","primaryGroupKeyUpdateInterval": "0","primaryRadiusServerIP": "",'
300
+ '"primaryRadiusServerPort": "1812","primaryRadiusServerSecret": "",'
301
+ '"primaryIsolationEnable": "0","primaryWMMEnable": "1","primaryTWTEnable": "0",'
302
+ '"PSCEnable": "0","WPSEnable": "0","WPSDevicePassword": "","WPSAPPinLock": "0",'
303
+ '"WPSPeerPassword": "0","WPSState": "Idle","WPSStartWPS": "0","WPSSetupLock": "1",'
304
+ '"ACLEnable": "0","ACLRule": "","X_TP_LteCoex": "0","DMSaveOnly": "0",'
305
+ '"stack": "1,0,0,0,0,0"}, {"band": "5GHz","standard": "anacax","bandwidth": "Auto",'
306
+ '"currentBandwidth": "80MHz","autoChannel": "1","channel": "44","transmitPower": "100",'
307
+ '"beaconInterval": "100","RTSThreshold": "2346","DTIMPeriod": "1",'
308
+ '"fragmentThreshold": "2346","regulatoryDomain": "DE ","guardInterval": "400nsec",'
309
+ '"primaryEnable": "1","primaryBSSID": "b8:7a:96:53:db:e2","primaryStatus": "Enabled",'
310
+ '"primarySSID": "JustAnotherWiFi","primarySSIDAdvertise": "1",'
311
+ '"primaryModeEnabled": "WPA2-Personal","primaryWPAWPA2EncryptionMode": "AES",'
312
+ '"primaryPSK": "","primaryGroupKeyUpdateInterval": "0","primaryRadiusServerIP": "",'
313
+ '"primaryRadiusServerPort": "1812","primaryRadiusServerSecret": "",'
314
+ '"primaryIsolationEnable": "0","primaryWMMEnable": "1","primaryTWTEnable": "0",'
315
+ '"PSCEnable": "0","WPSEnable": "0","WPSDevicePassword": "","WPSAPPinLock": "0",'
316
+ '"WPSPeerPassword": "0","WPSState": "Idle","WPSStartWPS": "0","WPSSetupLock": "1",'
317
+ '"ACLEnable": "0","ACLRule": "","X_TP_LteCoex": "0","DMSaveOnly": "0",'
318
+ '"stack": "2,0,0,0,0,0"}, {"band": "6GHz","standard": "ax","bandwidth": "Auto",'
319
+ '"currentBandwidth": "","autoChannel": "1","channel": "37","transmitPower": "100",'
320
+ '"beaconInterval": "100","RTSThreshold": "2346","DTIMPeriod": "1",'
321
+ '"fragmentThreshold": "2346","regulatoryDomain": "DE ","guardInterval": "400nsec",'
322
+ '"primaryEnable": "0","primaryBSSID": "b8:7a:96:53:db:e2","primaryStatus": "Disabled",'
323
+ '"primarySSID": "JustAnotherWiFi","primarySSIDAdvertise": "1",'
324
+ '"primaryModeEnabled": "WPA3-Personal","primaryWPAWPA2EncryptionMode": "AES",'
325
+ '"primaryPSK": "","primaryGroupKeyUpdateInterval": "0","primaryRadiusServerIP": "",'
326
+ '"primaryRadiusServerPort": "1812","primaryRadiusServerSecret": "",'
327
+ '"primaryIsolationEnable": "0","primaryWMMEnable": "1","primaryTWTEnable": "0",'
328
+ '"PSCEnable": "1","WPSEnable": "0","WPSDevicePassword": "0","WPSAPPinLock": "0",'
329
+ '"WPSPeerPassword": "0","WPSState": "","WPSStartWPS": "0","WPSSetupLock": "0",'
330
+ '"ACLEnable": "0","ACLRule": "","X_TP_LteCoex": "0","DMSaveOnly": "0",'
331
+ '"stack": "3,0,0,0,0,0"}],"operation": "gl","oid": "DEV2_ADT_WIFI_COMMON",'
332
+ '"success": true}')
333
+ DEV2_HOST_ENTRY = ('{"data":[{"active":"1","X_TP_LanConnType":"1","physAddress":"66-E2-02-BD-B5-1B",'
334
+ '"IPAddress":"192.168.30.10","hostName":"host1","stack":"1,0,0,0,0,0"},'
335
+ '{"active":"1","X_TP_LanConnType":"1","physAddress":"F4-A3-86-2D-41-B5",'
336
+ '"IPAddress":"192.168.30.11","hostName":"host2","stack":"2,0,0,0,0,0"}],"operation":"gl",'
337
+ '"oid":"DEV2_HOST_ENTRY","success":true}')
338
+ DEV2_MEM_STATUS = ('{"data":{"total":"192780","free":"78400","stack":"0,0,0,0,0,0"},"operation":"go",'
339
+ '"oid":"DEV2_MEM_STATUS","success":true}')
340
+ DEV2_PROC_STATUS = ('{"data":{"CPUUsage":"69","stack":"0,0,0,0,0,0"},"operation":"go",'
341
+ '"oid":"DEV2_PROC_STATUS","success":true}')
342
+
343
+ class TPLinkEXClientTest(TPLinkEXClient):
344
+ self._token = True
345
+
346
+ def _request(self, url, method='POST', data_str=None, encrypt=False):
347
+ if 'DEV2_ADT_LAN' in data_str:
348
+ return 200, DEV2_ADT_LAN
349
+ elif 'DEV2_ADT_WAN' in data_str:
350
+ return 200, DEV2_ADT_WAN
351
+ elif 'DEV2_ADT_WIFI_COMMON' in data_str:
352
+ return 200, DEV2_ADT_WIFI_COMMON
353
+ elif 'DEV2_HOST_ENTRY' in data_str:
354
+ return 200, DEV2_HOST_ENTRY
355
+ elif 'DEV2_MEM_STATUS' in data_str:
356
+ return 200, DEV2_MEM_STATUS
357
+ elif 'DEV2_PROC_STATUS' in data_str:
358
+ return 200, DEV2_PROC_STATUS
359
+ raise ClientException()
360
+
361
+ client = TPLinkEXClientTest('', '')
362
+ status = client.get_status()
363
+
364
+ self.assertIsInstance(status, Status)
365
+ self.assertEqual(status.wan_macaddr, None)
366
+ self.assertEqual(status.lan_macaddr, 'A0-28-84-DE-DD-5C')
367
+ self.assertIsInstance(status.lan_macaddress, EUI48)
368
+ self.assertEqual(status.wan_ipv4_addr, None)
369
+ self.assertEqual(status.lan_ipv4_addr, '192.168.4.1')
370
+ self.assertEqual(status.wan_ipv4_gateway, None)
371
+ self.assertEqual(status.wired_total, 0)
372
+ self.assertEqual(status.wifi_clients_total, 2)
373
+ self.assertEqual(status.guest_clients_total, 0)
374
+ self.assertEqual(status.clients_total, 2)
375
+ self.assertEqual(status.guest_2g_enable, None)
376
+ self.assertEqual(status.guest_5g_enable, None)
377
+ self.assertEqual(status.iot_2g_enable, None)
378
+ self.assertEqual(status.iot_5g_enable, None)
379
+ self.assertEqual(status.wifi_2g_enable, True)
380
+ self.assertEqual(status.wifi_5g_enable, True)
381
+ self.assertEqual(status.wan_ipv4_uptime, None)
382
+ self.assertGreaterEqual(status.mem_usage, 0)
383
+ self.assertLessEqual(status.mem_usage, 1)
384
+ self.assertGreaterEqual(status.cpu_usage, 0)
385
+ self.assertLessEqual(status.cpu_usage, 1)
386
+ self.assertEqual(len(status.devices), 2)
387
+ self.assertIsInstance(status.devices[0], Device)
388
+ self.assertEqual(status.devices[0].type, Connection.HOST_2G)
389
+ self.assertEqual(status.devices[0].macaddr, '66-E2-02-BD-B5-1B')
390
+ self.assertIsInstance(status.devices[0].macaddress, EUI48)
391
+ self.assertEqual(status.devices[0].ipaddr, '192.168.30.10')
392
+ self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
393
+ self.assertEqual(status.devices[0].hostname, 'host1')
394
+ self.assertEqual(status.devices[0].packets_sent, None)
395
+ self.assertEqual(status.devices[0].packets_received, None)
396
+ self.assertIsInstance(status.devices[1], Device)
397
+ self.assertEqual(status.devices[1].type, Connection.HOST_2G)
398
+ self.assertEqual(status.devices[1].macaddr, 'F4-A3-86-2D-41-B5')
399
+ self.assertIsInstance(status.devices[1].macaddress, EUI48)
400
+ self.assertEqual(status.devices[1].ipaddr, '192.168.30.11')
401
+ self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
402
+ self.assertEqual(status.devices[1].hostname, 'host2')
403
+ self.assertEqual(status.devices[1].packets_sent, None) # TODO
404
+ self.assertEqual(status.devices[1].packets_received, None) # TODO
405
+
287
406
  def test_get_ipv4_reservations(self) -> None:
288
407
 
289
408
  response = ('{"data":[{"enable":"1","chaddr":"bf:75:44:4c:dc:9e","yiaddr":"192.168.8.21",'
test/test_client_mr.py CHANGED
@@ -93,7 +93,7 @@ softwareVersion=1.1
93
93
  '''
94
94
 
95
95
  class TPLinkMRClientTest(TPLinkMRClient):
96
- def _request(self, url, method='POST', data_str=None, encrypt=False):
96
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
97
97
  return 200, response
98
98
 
99
99
  client = TPLinkMRClientTest('', '')
@@ -158,7 +158,7 @@ X_TP_TotalPacketsReceived=467
158
158
  '''
159
159
 
160
160
  class TPLinkMRClientTest(TPLinkMRClient):
161
- def _request(self, url, method='POST', data_str=None, encrypt=False):
161
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
162
162
  return 200, response
163
163
 
164
164
  client = TPLinkMRClientTest('', '')
@@ -236,7 +236,7 @@ active=1
236
236
  '''
237
237
 
238
238
  class TPLinkMRClientTest(TPLinkMRClient):
239
- def _request(self, url, method='POST', data_str=None, encrypt=False):
239
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
240
240
  return 200, response
241
241
 
242
242
  client = TPLinkMRClientTest('', '')
@@ -299,7 +299,7 @@ X_TP_TotalPacketsReceived=467
299
299
  '''
300
300
 
301
301
  class TPLinkMRClientTest(TPLinkMRClient):
302
- def _request(self, url, method='POST', data_str=None, encrypt=False):
302
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
303
303
  return 200, response
304
304
 
305
305
  client = TPLinkMRClientTest('', '')
@@ -356,7 +356,7 @@ name=wlan1
356
356
  '''
357
357
 
358
358
  class TPLinkMRClientTest(TPLinkMRClient):
359
- def _request(self, url, method='POST', data_str=None, encrypt=False):
359
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
360
360
  return 200, response
361
361
 
362
362
  client = TPLinkMRClientTest('', '')
@@ -407,7 +407,7 @@ name=wlan1
407
407
  '''
408
408
 
409
409
  class TPLinkMRClientTest(TPLinkMRClient):
410
- def _request(self, url, method='POST', data_str=None, encrypt=False):
410
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
411
411
  return 200, response
412
412
 
413
413
  client = TPLinkMRClientTest('', '')
@@ -450,7 +450,7 @@ yiaddr=192.168.8.21
450
450
  '''
451
451
 
452
452
  class TPLinkMRClientTest(TPLinkMRClient):
453
- def _request(self, url, method='POST', data_str=None, encrypt=False):
453
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
454
454
  return 200, response
455
455
 
456
456
  client = TPLinkMRClientTest('', '')
@@ -470,7 +470,7 @@ yiaddr=192.168.8.21
470
470
  '''
471
471
 
472
472
  class TPLinkMRClientTest(TPLinkMRClient):
473
- def _request(self, url, method='POST', data_str=None, encrypt=False):
473
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
474
474
  return 200, response
475
475
 
476
476
  client = TPLinkMRClientTest('', '')
@@ -485,7 +485,7 @@ yiaddr=192.168.8.21
485
485
  '''
486
486
 
487
487
  class TPLinkMRClientTest(TPLinkMRClient):
488
- def _request(self, url, method='POST', data_str=None, encrypt=False):
488
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
489
489
  return 200, response
490
490
 
491
491
  client = TPLinkMRClientTest('', '')
@@ -505,7 +505,7 @@ leaseTimeRemaining=85841
505
505
  '''
506
506
 
507
507
  class TPLinkMRClientTest(TPLinkMRClient):
508
- def _request(self, url, method='POST', data_str=None, encrypt=False):
508
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
509
509
  return 200, response
510
510
 
511
511
  client = TPLinkMRClientTest('', '')
@@ -535,7 +535,7 @@ leaseTimeRemaining=86372
535
535
  '''
536
536
 
537
537
  class TPLinkMRClientTest(TPLinkMRClient):
538
- def _request(self, url, method='POST', data_str=None, encrypt=False):
538
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
539
539
  return 200, response
540
540
 
541
541
  client = TPLinkMRClientTest('', '')
@@ -580,7 +580,7 @@ DNSServers=7.7.7.7,2.2.2.2
580
580
  '''
581
581
 
582
582
  class TPLinkMRClientTest(TPLinkMRClient):
583
- def _request(self, url, method='POST', data_str=None, encrypt=False):
583
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
584
584
  return 200, response
585
585
 
586
586
  client = TPLinkMRClientTest('', '')
@@ -611,7 +611,7 @@ DNSServers=7.7.7.7,2.2.2.2
611
611
  '''
612
612
 
613
613
  class TPLinkMRClientTest(TPLinkMRClient):
614
- def _request(self, url, method='POST', data_str=None, encrypt=False):
614
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
615
615
  return 200, response
616
616
 
617
617
  client = TPLinkMRClientTest('', '')
@@ -645,7 +645,7 @@ DNSServers=0.0.0.0,0.0.0.0
645
645
  '''
646
646
 
647
647
  class TPLinkMRClientTest(TPLinkMRClient):
648
- def _request(self, url, method='POST', data_str=None, encrypt=False):
648
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
649
649
  return 200, response
650
650
 
651
651
  client = TPLinkMRClientTest('', '')
@@ -675,7 +675,7 @@ DNSServers=0.0.0.0,0.0.0.0
675
675
  check_data = ''
676
676
 
677
677
  class TPLinkMRClientTest(TPLinkMRClient):
678
- def _request(self, url, method='POST', data_str=None, encrypt=False):
678
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
679
679
  nonlocal check_url, check_data
680
680
  check_url = url
681
681
  check_data = data_str
@@ -697,7 +697,7 @@ DNSServers=0.0.0.0,0.0.0.0
697
697
  check_data = ''
698
698
 
699
699
  class TPLinkMRClientTest(TPLinkMRClient):
700
- def _request(self, url, method='POST', data_str=None, encrypt=False):
700
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
701
701
  nonlocal check_url, check_data
702
702
  check_url = url
703
703
  check_data = data_str
@@ -733,7 +733,7 @@ ussdStatus=1
733
733
  check_data = []
734
734
 
735
735
  class TPLinkMRClientTest(TPLinkMRClient):
736
- def _request(self, url, method='POST', data_str=None, encrypt=False):
736
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
737
737
  check_url.append(url)
738
738
  check_data.append(data_str)
739
739
  return 200, responses.pop(0)
@@ -774,7 +774,7 @@ ussdStatus=2
774
774
  check_data = []
775
775
 
776
776
  class TPLinkMRClientTest(TPLinkMRClient):
777
- def _request(self, url, method='POST', data_str=None, encrypt=False):
777
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
778
778
  check_url.append(url)
779
779
  check_data.append(data_str)
780
780
  return 200, responses.pop(0)
@@ -812,7 +812,7 @@ unread=0
812
812
  '''
813
813
 
814
814
  class TPLinkMRClientTest(TPLinkMRClient):
815
- def _request(self, url, method='POST', data_str=None, encrypt=False):
815
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
816
816
  return 200, response
817
817
 
818
818
  client = TPLinkMRClientTest('', '')
@@ -838,7 +838,7 @@ unread=0
838
838
  '''
839
839
 
840
840
  class TPLinkMRClientTest(TPLinkMRClient):
841
- def _request(self, url, method='POST', data_str=None, encrypt=False):
841
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
842
842
  return 200, response
843
843
 
844
844
  client = TPLinkMRClientTest('', '')
@@ -856,7 +856,7 @@ unread=0
856
856
  check_data = ''
857
857
 
858
858
  class TPLinkMRClientTest(TPLinkMRClient):
859
- def _request(self, url, method='POST', data_str=None, encrypt=False):
859
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
860
860
  nonlocal check_url, check_data
861
861
  check_url = url
862
862
  check_data = data_str
@@ -878,7 +878,7 @@ unread=0
878
878
  check_data = ''
879
879
 
880
880
  class TPLinkMRClientTest(TPLinkMRClient):
881
- def _request(self, url, method='POST', data_str=None, encrypt=False):
881
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
882
882
  nonlocal check_url, check_data
883
883
  check_url = url
884
884
  check_data = data_str
@@ -922,7 +922,7 @@ ispName=Name
922
922
  '''
923
923
 
924
924
  class TPLinkMRClientTest(TPLinkMRClient):
925
- def _request(self, url, method='POST', data_str=None, encrypt=False):
925
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
926
926
  return 200, response
927
927
 
928
928
  client = TPLinkMRClientTest('', '')
@@ -975,7 +975,7 @@ ispName=Name
975
975
  '''
976
976
 
977
977
  class TPLinkMRClientTest(TPLinkMRClient):
978
- def _request(self, url, method='POST', data_str=None, encrypt=False):
978
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
979
979
  return 200, response
980
980
 
981
981
  client = TPLinkMRClientTest('', '')
@@ -1033,7 +1033,7 @@ connAct=0
1033
1033
  '''
1034
1034
 
1035
1035
  class TPLinkMRClientTest(TPLinkMRClient):
1036
- def _request(self, url, method='POST', data_str=None, encrypt=False):
1036
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
1037
1037
  return 200, response
1038
1038
 
1039
1039
  client = TPLinkMRClientTest('', '')
@@ -1055,7 +1055,7 @@ connAct=0
1055
1055
  check_data = ''
1056
1056
 
1057
1057
  class TPLinkMRClientTest(TPLinkMRClient):
1058
- def _request(self, url, method='POST', data_str=None, encrypt=False):
1058
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
1059
1059
  nonlocal check_url, check_data
1060
1060
  check_url = url
1061
1061
  check_data = data_str
@@ -3,11 +3,13 @@ from tplinkrouterc6u.client.deco import TPLinkDecoClient
3
3
  from tplinkrouterc6u.client_abstract import AbstractRouter
4
4
  from tplinkrouterc6u.client.mr import TPLinkMRClient, TPLinkMRClientGCM
5
5
  from tplinkrouterc6u.client.mr200 import TPLinkMR200Client
6
+ from tplinkrouterc6u.client.mr6400v7 import TPLinkMR6400v7Client
6
7
  from tplinkrouterc6u.client.ex import TPLinkEXClient, TPLinkEXClientGCM
7
8
  from tplinkrouterc6u.client.vr import TPLinkVRClient
8
9
  from tplinkrouterc6u.client.vr400v2 import TPLinkVR400v2Client
9
10
  from tplinkrouterc6u.client.c80 import TplinkC80Router
10
11
  from tplinkrouterc6u.client.c5400x import TplinkC5400XRouter
12
+ from tplinkrouterc6u.client.c3200 import TplinkC3200Router
11
13
  from tplinkrouterc6u.client.c1200 import TplinkC1200Router
12
14
  from tplinkrouterc6u.client.xdr import TPLinkXDRClient
13
15
  from tplinkrouterc6u.client.wdr import TplinkWDRRouter
@@ -0,0 +1,198 @@
1
+ import base64
2
+ import re
3
+ from time import sleep
4
+ from urllib.parse import urlparse
5
+
6
+ import requests
7
+ from requests import Response
8
+
9
+ from tplinkrouterc6u.client.mr200 import TPLinkMR200Client
10
+ from tplinkrouterc6u.common.package_enum import VPN
11
+ from tplinkrouterc6u.common.dataclass import (
12
+ LTEStatus,
13
+ )
14
+ from tplinkrouterc6u.common.exception import ClientException, ClientError
15
+ from tplinkrouterc6u.common.package_enum import Connection
16
+
17
+
18
+ class TplinkC3200Router(TPLinkMR200Client):
19
+ # This is a session variable that will contain everything needed as soon as the router is connected.
20
+ # - The "Referer" header which allows to be accepted by the CGI module.
21
+ # - the Authentification cookie
22
+ SESSION: requests.Session
23
+
24
+ # Possible retries limit
25
+ REQUEST_RETRIES = 1
26
+
27
+ # Router name to be included in logs for example,
28
+ # or to be redefined by subclasses.
29
+ ROUTER_NAME = "TP Link Router C3200"
30
+
31
+ # Connection method
32
+ def supports(self) -> bool:
33
+ if len(self.password) > 125:
34
+ return False
35
+
36
+ try:
37
+ # This method checks if we can recognize the router type.
38
+ welcome_page = requests.get(self.host, timeout=5)
39
+ if welcome_page and welcome_page.status_code == 200 and re.search("Archer", welcome_page.text):
40
+ return True
41
+ except ClientException:
42
+ pass
43
+
44
+ return False
45
+
46
+ def authorize(self) -> None:
47
+
48
+ # ———————————————————————————————————————————
49
+ # Create the SESSION object and the authorization cookie
50
+ # ———————————————————————————————————————————
51
+ self.SESSION = requests.Session()
52
+
53
+ if self._logger:
54
+ self._logger.debug("!")
55
+ # We need to extract the domain form the host to fill the cookie.
56
+ router_host = urlparse(self.host).hostname
57
+ if not router_host:
58
+ raise ValueError(self.host & " must contain a valid host, ex. http://192.168.168.1")
59
+
60
+ """Return the string "Basic <base64(username:password)>"."""
61
+ token_bytes = f"{self.username}:{self.password}".encode()
62
+ encoded = base64.b64encode(token_bytes).decode()
63
+ auth_cookie_value = f"Basic {encoded}"
64
+
65
+ self.SESSION.cookies.set(
66
+ name="Authorization",
67
+ value=auth_cookie_value,
68
+ domain=router_host,
69
+ path="/",
70
+ )
71
+
72
+ self.SESSION.headers = {"Referer": f"{self.host}/", "Origin": self.host}
73
+
74
+ login_url = '{}/'.format(self.host)
75
+ response = Response()
76
+
77
+ try:
78
+ response = self.SESSION.post(login_url, timeout=10)
79
+ except Exception as e:
80
+ error = self.ROUTER_NAME + " - Cannot authorize! Error - {}; Response - {}".format(e, response.text)
81
+ if self._logger:
82
+ self._logger.debug(error)
83
+ raise ClientException(error)
84
+
85
+ def logout(self) -> None:
86
+ self.SESSION.cookies.clear(domain=urlparse(self.host).hostname, path="/")
87
+
88
+ def get_lte_status(self) -> LTEStatus:
89
+ pass
90
+
91
+ def _get_params(self, retry=False) -> None:
92
+ pass
93
+
94
+ def set_vpn(self, vpn: VPN, enable: bool) -> None:
95
+ # Unable to test it on my C3200
96
+ pass
97
+
98
+ def req_act(self, acts: list):
99
+ act_types, act_data = self._fill_acts(acts)
100
+
101
+ url = f"{self.host}/cgi?" + '&'.join(act_types)
102
+ data_str = ''.join(act_data)
103
+ (code, response) = self._request(url, data_str=data_str)
104
+
105
+ if code != 200:
106
+ error = self.ROUTER_NAME + ' - Response with error; Request {} - Response {}'.format(data_str, response)
107
+ if self._logger:
108
+ self._logger.debug(error)
109
+ raise ClientError(error)
110
+
111
+ result = self._merge_response(response)
112
+
113
+ return response, result.get('0') if len(result) == 1 and result.get('0') else result
114
+
115
+ def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
116
+ r = Response()
117
+
118
+ retry = 0
119
+ while retry < self.REQUEST_RETRIES:
120
+ # send the request
121
+ if method == 'POST':
122
+ r = self.SESSION.post(url, data=data_str)
123
+ elif method == 'GET':
124
+ r = self.SESSION.get(url, data=data_str)
125
+ else:
126
+ raise Exception('Unsupported method ' + str(method))
127
+
128
+ # sometimes we get 500 here, not sure why... just retry the request
129
+ if (r.status_code not in [500, 406]
130
+ and '<title>500 Internal Server Error</title>' not in r.text
131
+ and '<title>406 Not Acceptable</title>' not in r.text):
132
+ break
133
+
134
+ sleep(0.1)
135
+ retry += 1
136
+
137
+ return r.status_code, r.text
138
+
139
+ # Overriding the method since we have two 5G bands in the rooter.
140
+ # We manage both as one.
141
+ def set_wifi(self, wifi: Connection, enable: bool) -> None:
142
+ acts = []
143
+
144
+ match wifi:
145
+ case Connection.HOST_2G:
146
+ acts = [
147
+ self.ActItem(
148
+ self.ActItem.SET,
149
+ 'LAN_WLAN',
150
+ '1,1,0,0,0,0',
151
+ attrs=['enable={}'.format(int(enable))]),
152
+ ]
153
+ case Connection.HOST_5G:
154
+ # We activate both 5G bands
155
+ acts = [
156
+ self.ActItem(
157
+ self.ActItem.SET,
158
+ 'LAN_WLAN',
159
+ '1,2,0,0,0,0',
160
+ attrs=['enable={}'.format(int(enable))]),
161
+ self.ActItem(
162
+ self.ActItem.SET,
163
+ 'LAN_WLAN',
164
+ '1,3,0,0,0,0',
165
+ attrs=['enable={}'.format(int(enable))]),
166
+ ]
167
+ case Connection.GUEST_2G:
168
+ acts = [
169
+ self.ActItem(
170
+ self.ActItem.SET,
171
+ 'LAN_WLAN_MSSIDENTRY',
172
+ '1,1,1,0,0,0',
173
+ attrs=['enable={}'.format(int(enable))]),
174
+ ]
175
+ case Connection.GUEST_5G:
176
+ acts = [
177
+ self.ActItem(
178
+ self.ActItem.SET,
179
+ 'LAN_WLAN_MSSIDENTRY',
180
+ '1,2,1,0,0,0',
181
+ attrs=['enable={}'.format(int(enable))]),
182
+ self.ActItem(
183
+ self.ActItem.SET,
184
+ 'LAN_WLAN_MSSIDENTRY',
185
+ '1,3,1,0,0,0',
186
+ attrs=['enable={}'.format(int(enable))]),
187
+ ]
188
+ self.req_act(acts)
189
+
190
+ def reboot(self) -> None:
191
+ # CGI 7 et [ACT_REBOOT#0,0,0,0,0,0#0,0,0,0,0,0]0,0
192
+
193
+ acts = [
194
+ self.ActItem(self.ActItem.OP, 'ACT_REBOOT'),
195
+ ]
196
+ _, values = self.req_act(acts)
197
+
198
+ # print(values.keys())
@@ -514,7 +514,10 @@ class TplinkRouterV1_11(TplinkBaseRouter):
514
514
  try:
515
515
  self._request_pwd()
516
516
  # V1_11 uses 2048-bit RSA = 512 hex chars, older firmware uses 1024-bit = 256 chars
517
- return len(self._pwdNN) >= 512
517
+ if len(self._pwdNN) >= 512:
518
+ self.authorize()
519
+ self.logout()
520
+ return True
518
521
  except Exception:
519
522
  return False
520
523
 
@@ -534,7 +537,7 @@ class TplinkRouterV1_11(TplinkBaseRouter):
534
537
  self._pwdNN = data[self._data_block]['password'][0]
535
538
  self._pwdEE = data[self._data_block]['password'][1]
536
539
  except Exception as e:
537
- error = ('TplinkRouter - {} - Failed to get encryption keys! Error - {}; Response - {}'
540
+ error = ('TplinkRouterV1_11 - {} - Failed to get encryption keys! Error - {}; Response - {}'
538
541
  .format(self.__class__.__name__, e, response.text))
539
542
  if self._logger:
540
543
  self._logger.debug(error)
@@ -563,7 +566,7 @@ class TplinkRouterV1_11(TplinkBaseRouter):
563
566
  if not data.get('success'):
564
567
  error_info = data.get(self._data_block, {})
565
568
  raise ClientException(
566
- 'TplinkRouter - {} - Login failed: {}'.format(
569
+ 'TplinkRouterV1_11 - {} - Login failed: {}'.format(
567
570
  self.__class__.__name__,
568
571
  error_info.get('errorcode', 'unknown error')
569
572
  )
@@ -582,7 +585,7 @@ class TplinkRouterV1_11(TplinkBaseRouter):
582
585
  except ClientException:
583
586
  raise
584
587
  except Exception as e:
585
- error = ('TplinkRouter - {} - Cannot authorize! Error - {}; Response - {}'
588
+ error = ('TplinkRouterV1_11 - {} - Cannot authorize! Error - {}; Response - {}'
586
589
  .format(self.__class__.__name__, e, response.text))
587
590
  if self._logger:
588
591
  self._logger.debug(error)
@@ -92,7 +92,7 @@ class TPLinkEXClient(TPLinkMRClientBase):
92
92
  self.ActItem(self.ActItem.GL, 'DEV2_ADT_LAN', attrs=['MACAddress', 'IPAddress']),
93
93
  self.ActItem(self.ActItem.GL, 'DEV2_ADT_WAN',
94
94
  attrs=['enable', 'MACAddr', 'connIPv4Address', 'connIPv4Gateway']),
95
- self.ActItem(self.ActItem.GL, 'DEV2_ADT_WIFI_COMMON', attrs=['primaryEnable', 'guestEnable']),
95
+ self.ActItem(self.ActItem.GL, 'DEV2_ADT_WIFI_COMMON'),
96
96
  self.ActItem(self.ActItem.GL, 'DEV2_HOST_ENTRY',
97
97
  attrs=['active', 'X_TP_LanConnType', 'physAddress', 'IPAddress', 'hostName']),
98
98
  self.ActItem(self.ActItem.GO, 'DEV2_MEM_STATUS', attrs=['total', 'free']),
@@ -117,12 +117,14 @@ class TPLinkEXClient(TPLinkMRClientBase):
117
117
  if values[2]:
118
118
  if values[2].__class__ != list:
119
119
  status.wifi_2g_enable = bool(int(values[2]['primaryEnable']))
120
- status.guest_2g_enable = bool(int(values[2]['guestEnable']))
120
+ status.guest_2g_enable = bool(int(values[2]['guestEnable'])) if values[2].get('guestEnable') else None
121
121
  else:
122
122
  status.wifi_2g_enable = bool(int(values[2][0]['primaryEnable']))
123
123
  status.wifi_5g_enable = bool(int(values[2][1]['primaryEnable']))
124
- status.guest_2g_enable = bool(int(values[2][0]['guestEnable']))
125
- status.guest_5g_enable = bool(int(values[2][1]['guestEnable']))
124
+ status.guest_2g_enable = bool(int(values[2][0]['guestEnable'])) \
125
+ if values[2][0].get('guestEnable') else None
126
+ status.guest_5g_enable = bool(int(values[2][1]['guestEnable'])) \
127
+ if values[2][1].get('guestEnable') else None
126
128
 
127
129
  devices = {}
128
130
  for val in self._to_list(values[3]):