tplinkrouterc6u 5.13.0__py3-none-any.whl → 5.14.0__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.
@@ -2,7 +2,7 @@ from hashlib import md5
2
2
  from re import search
3
3
  from time import time, sleep
4
4
  from urllib.parse import quote
5
- from requests import Session
5
+ from requests import Session, Response
6
6
  from datetime import timedelta, datetime
7
7
  from macaddress import EUI48
8
8
  from ipaddress import IPv4Address
@@ -23,6 +23,7 @@ from tplinkrouterc6u.common.dataclass import (
23
23
  )
24
24
  from tplinkrouterc6u.common.exception import ClientException, ClientError
25
25
  from tplinkrouterc6u.client_abstract import AbstractRouter
26
+ from typing import List
26
27
 
27
28
 
28
29
  class TPLinkMRClientBase(AbstractRouter):
@@ -54,6 +55,10 @@ class TPLinkMRClientBase(AbstractRouter):
54
55
  Connection.GUEST_5G: '1,2,1,0,0,0',
55
56
  }
56
57
 
58
+ # Router name to be included in logs for example,
59
+ # or to be redefined by subclasses.
60
+ ROUTER_NAME = "TP Link Router MR"
61
+
57
62
  class ActItem:
58
63
  GET = 1
59
64
  SET = 2
@@ -65,7 +70,9 @@ class TPLinkMRClientBase(AbstractRouter):
65
70
  CGI = 8
66
71
 
67
72
  def __init__(self, type: int, oid: str, stack: str = '0,0,0,0,0,0', pstack: str = '0,0,0,0,0,0',
68
- attrs: list = []):
73
+ attrs=None):
74
+ if attrs is None:
75
+ attrs = []
69
76
  self.type = type
70
77
  self.oid = oid
71
78
  self.stack = stack
@@ -111,6 +118,10 @@ class TPLinkMRClientBase(AbstractRouter):
111
118
  self._token = self._req_token()
112
119
  self._authorized_at = datetime.now()
113
120
 
121
+ # Fake implementation of all abstract methods
122
+ def logout(self) -> None:
123
+ pass
124
+
114
125
  def reboot(self) -> None:
115
126
  acts = [
116
127
  self.ActItem(self.ActItem.OP, 'ACT_REBOOT')
@@ -215,9 +226,9 @@ class TPLinkMRClientBase(AbstractRouter):
215
226
 
216
227
  return status
217
228
 
218
- def get_ipv4_reservations(self) -> [IPv4Reservation]:
229
+ def get_ipv4_reservations(self) -> List[IPv4Reservation]:
219
230
  acts = [
220
- self.ActItem(self.ActItem.GL, 'LAN_DHCP_STATIC_ADDR', attrs=['enable', 'chaddr', 'yiaddr']),
231
+ self.ActItem(self.ActItem.GL, 'LAN_DHCP_STATIC_ADDR'),
221
232
  ]
222
233
  _, values = self.req_act(acts)
223
234
 
@@ -227,13 +238,13 @@ class TPLinkMRClientBase(AbstractRouter):
227
238
  IPv4Reservation(
228
239
  EUI48(item['chaddr']),
229
240
  IPv4Address(item['yiaddr']),
230
- '',
241
+ item.get('description', ''),
231
242
  bool(int(item['enable']))
232
243
  ))
233
244
 
234
245
  return ipv4_reservations
235
246
 
236
- def get_ipv4_dhcp_leases(self) -> [IPv4DHCPLease]:
247
+ def get_ipv4_dhcp_leases(self) -> List[IPv4DHCPLease]:
237
248
  acts = [
238
249
  self.ActItem(self.ActItem.GL, 'LAN_HOST_ENTRY', attrs=['IPAddress', 'MACAddress', 'hostName',
239
250
  'leaseTimeRemaining']),
@@ -324,12 +335,11 @@ class TPLinkMRClientBase(AbstractRouter):
324
335
 
325
336
  self.req_act(acts)
326
337
 
327
- def req_act(self, acts: list):
328
- '''
329
- Requests ACTs via the cgi_gdpr proxy
330
- '''
331
- act_types = []
332
- act_data = []
338
+ @staticmethod
339
+ def _fill_acts(acts: list) -> tuple[List[str], List[str]]:
340
+ # Fill the act lists, to refactor for other subclasses.
341
+ act_types: List[str] = []
342
+ act_data: List[str] = []
333
343
 
334
344
  for act in acts:
335
345
  act_types.append(str(act.type))
@@ -342,13 +352,18 @@ class TPLinkMRClientBase(AbstractRouter):
342
352
  '\r\n'.join(act.attrs)
343
353
  ))
344
354
 
355
+ return act_types, act_data
356
+
357
+ def req_act(self, acts: list):
358
+ act_types, act_data = self._fill_acts(acts)
359
+
345
360
  data = '&'.join(act_types) + '\r\n' + ''.join(act_data)
346
361
 
347
362
  url = self._get_url('cgi_gdpr')
348
363
  (code, response) = self._request(url, data_str=data, encrypt=True)
349
364
 
350
365
  if code != 200:
351
- error = 'TplinkRouter - MR - Response with error; Request {} - Response {}'.format(data, response)
366
+ error = self.ROUTER_NAME + ' - Response with error; Request {} - Response {}'.format(data, response)
352
367
  if self._logger:
353
368
  self._logger.debug(error)
354
369
  raise ClientError(error)
@@ -391,7 +406,11 @@ class TPLinkMRClientBase(AbstractRouter):
391
406
 
392
407
  return result if result else []
393
408
 
394
- def _get_url(self, endpoint: str, params: dict = {}, include_ts: bool = True) -> str:
409
+ def _get_url(self, endpoint: str, params: dict = None, include_ts: bool = True) -> str:
410
+ # check if there is any param
411
+ if params is None:
412
+ params = {}
413
+
395
414
  # add timestamp param
396
415
  if include_ts:
397
416
  params['_'] = str(round(time() * 1000))
@@ -410,14 +429,14 @@ class TPLinkMRClientBase(AbstractRouter):
410
429
  )
411
430
 
412
431
  def _req_token(self):
413
- '''
432
+ """
414
433
  Requests the TokenID, used for CGI authentication (together with cookies)
415
434
  - token is inlined as JS var in the index (/) html page
416
435
  e.g.: <script type="text/javascript">var token="086724f57013f16e042e012becf825";</script>
417
436
 
418
437
  Return value:
419
438
  TokenID string
420
- '''
439
+ """
421
440
  url = self._get_url('')
422
441
  (code, response) = self._request(url, method='GET')
423
442
  assert code == 200
@@ -430,12 +449,12 @@ class TPLinkMRClientBase(AbstractRouter):
430
449
  return result.group(1)
431
450
 
432
451
  def _req_rsa_key(self):
433
- '''
452
+ """
434
453
  Requests the RSA public key from the host
435
454
 
436
455
  Return value:
437
456
  ((n, e), seq) tuple
438
- '''
457
+ """
439
458
  response = ''
440
459
  try:
441
460
  url = self._get_url(self._url_rsa_key)
@@ -459,7 +478,7 @@ class TPLinkMRClientBase(AbstractRouter):
459
478
  assert seq.isnumeric()
460
479
 
461
480
  except Exception as e:
462
- error = ('TplinkRouter - {} - Unknown error rsa_key! Error - {}; Response - {}'
481
+ error = (self.ROUTER_NAME + '- {} - Unknown error rsa_key! Error - {}; Response - {}'
463
482
  .format(self.__class__.__name__, e, response))
464
483
  if self._logger:
465
484
  self._logger.debug(error)
@@ -468,7 +487,7 @@ class TPLinkMRClientBase(AbstractRouter):
468
487
  return nn, ee, int(seq)
469
488
 
470
489
  def _req_login(self) -> None:
471
- '''
490
+ """
472
491
  Authenticates to the host
473
492
  - sets the session token after successful login
474
493
  - data/signature is passed as a GET parameter, NOT as a raw request data
@@ -476,7 +495,7 @@ class TPLinkMRClientBase(AbstractRouter):
476
495
 
477
496
  Example session token (set as a cookie):
478
497
  {'JSESSIONID': '4d786fede0164d7613411c7b6ec61e'}
479
- '''
498
+ """
480
499
  # encrypt username + password
481
500
 
482
501
  sign, data = self._prepare_data(self.username + '\n' + self.password, True)
@@ -501,12 +520,12 @@ class TPLinkMRClientBase(AbstractRouter):
501
520
  info = search('var currAuthTimes=(.*);\nvar currForbidTime=(.*);', response)
502
521
  assert info is not None
503
522
 
504
- error = 'TplinkRouter - MR - Login failed, wrong password. Auth times: {}/5, Forbid time: {}'.format(
523
+ error = self.ROUTER_NAME + ' - Login failed, wrong password. Auth times: {}/5, Forbid time: {}'.format(
505
524
  info.group(1), info.group(2))
506
525
  elif ret_code == self.HTTP_ERR_USER_BAD_REQUEST:
507
- error = 'TplinkRouter - MR - Login failed. Generic error code: {}'.format(ret_code)
526
+ error = self.ROUTER_NAME + ' - Login failed. Generic error code: {}'.format(ret_code)
508
527
  elif ret_code != self.HTTP_RET_OK:
509
- error = 'TplinkRouter - MR - Login failed. Unknown error code: {}'.format(ret_code)
528
+ error = self.ROUTER_NAME + ' - Login failed. Unknown error code: {}'.format(ret_code)
510
529
 
511
530
  if error:
512
531
  if self._logger:
@@ -514,14 +533,14 @@ class TPLinkMRClientBase(AbstractRouter):
514
533
  raise ClientException(error)
515
534
 
516
535
  def _request(self, url, method='POST', data_str=None, encrypt=False, is_login=False):
517
- '''
536
+ """
518
537
  Prepares and sends an HTTP request to the host
519
538
  - sets up the headers, handles token auth
520
539
  - encrypts/decrypts the data, if needed
521
540
 
522
541
  Return value:
523
542
  (status_code, response_text) tuple
524
- '''
543
+ """
525
544
  headers = self.HEADERS
526
545
 
527
546
  # add referer to request headers,
@@ -541,6 +560,8 @@ class TPLinkMRClientBase(AbstractRouter):
541
560
  data = data_str
542
561
 
543
562
  retry = 0
563
+ r = Response()
564
+
544
565
  while retry < self.REQUEST_RETRIES:
545
566
  # send the request
546
567
  if method == 'POST':
@@ -566,12 +587,12 @@ class TPLinkMRClientBase(AbstractRouter):
566
587
  return r.status_code, r.text
567
588
 
568
589
  def _parse_ret_val(self, response_text):
569
- '''
590
+ """
570
591
  Parses $.ret value from the response text
571
592
 
572
593
  Return value:
573
594
  return code (int)
574
- '''
595
+ """
575
596
  result = search(r'\$\.ret=(.*);', response_text)
576
597
  assert result is not None
577
598
  assert result.group(1).isnumeric()
@@ -618,6 +639,8 @@ class TPLinkMRClientBaseGCM(TPLinkMRClientBase):
618
639
  data = data_str
619
640
 
620
641
  retry = 0
642
+ r = Response()
643
+
621
644
  while retry < self.REQUEST_RETRIES:
622
645
  # send the request
623
646
  if method == 'POST':
@@ -656,9 +679,9 @@ class TPLinkMRClientBaseGCM(TPLinkMRClientBase):
656
679
  class TPLinkMRClient(TPLinkMRClientBase):
657
680
 
658
681
  def logout(self) -> None:
659
- '''
682
+ """
660
683
  Logs out from the host
661
- '''
684
+ """
662
685
  if self._token is None:
663
686
  return
664
687
 
@@ -684,7 +707,7 @@ class TPLinkMRClient(TPLinkMRClientBase):
684
707
  ]
685
708
  self.req_act(acts)
686
709
 
687
- def get_sms(self) -> [SMS]:
710
+ def get_sms(self) -> List[SMS]:
688
711
  acts = [
689
712
  self.ActItem(
690
713
  self.ActItem.SET, 'LTE_SMS_RECVMSGBOX', attrs=['PageNumber=1']),
@@ -57,7 +57,10 @@ class TPLinkMR200Client(TPLinkMRClient):
57
57
  ]
58
58
  _, values = self.req_act(acts)
59
59
 
60
- status.ipsecvpn_enable = values.get('enable') == '1'
60
+ if len(values) == 0:
61
+ status.ipsecvpn_enable = False
62
+ else:
63
+ status.ipsecvpn_enable = values.get('enable') == '1'
61
64
 
62
65
  return status
63
66
 
@@ -0,0 +1,80 @@
1
+ """
2
+ TP-Link TL-MR6400 v7 Client
3
+
4
+ Based on reverse-engineering of network traffic.
5
+ Protocol is similar to MR series but with differences in:
6
+ 1. Login: Uses RSA encryption (PKCS1 v1.5) for both Username and Password
7
+ 2. Password must be Base64 encoded before encryption
8
+ 3. Actions: Uses /cgi endpoint with types in query string and plain text body
9
+ """
10
+
11
+ from logging import Logger
12
+
13
+ from tplinkrouterc6u.client.mr import TPLinkMRClient
14
+ from tplinkrouterc6u.common.exception import ClientException, ClientError
15
+
16
+ from json import loads
17
+
18
+
19
+ class TPLinkMR6400v7Client(TPLinkMRClient):
20
+ """Client for TP-Link MR6400 v7"""
21
+
22
+ def __init__(self, host: str, password: str, username: str = '', logger: Logger = None,
23
+ verify_ssl: bool = True, timeout: int = 30):
24
+ super().__init__(host, password, username, logger, verify_ssl, timeout)
25
+
26
+ def _req_rsa_key(self):
27
+ """
28
+ Requests the RSA public key from the host
29
+
30
+ Return value:
31
+ ((n, e), seq) tuple
32
+ """
33
+ response = ''
34
+ try:
35
+ url = self._get_url(self._url_rsa_key)
36
+ (code, response) = self._request(url)
37
+ assert code == 200
38
+
39
+ # assert return code
40
+ assert self._parse_ret_val(response) == self.HTTP_RET_OK
41
+
42
+ json_data = loads(response)
43
+
44
+ ee = json_data['ee']
45
+ nn = json_data['nn']
46
+ seq = json_data['seq']
47
+
48
+ assert ee and nn and seq
49
+ assert len(ee) == 6
50
+ assert len(nn) == 128
51
+
52
+ except Exception as e:
53
+ error = (self.ROUTER_NAME + '- {} - Unknown error rsa_key! Error - {}; Response - {}'
54
+ .format(self.__class__.__name__, e, response))
55
+ if self._logger:
56
+ self._logger.debug(error)
57
+ raise ClientException(error)
58
+
59
+ return nn, ee, int(seq)
60
+
61
+ def _parse_ret_val(self, response_text):
62
+ """
63
+ Parses $.ret value from the response text
64
+
65
+ Return value:
66
+ return code (int)
67
+ """
68
+ if '[error]0' in response_text or 'errorcode=0' in response_text:
69
+ return 0
70
+
71
+ try:
72
+ result = loads(response_text)
73
+
74
+ result = result['ret']
75
+ result = int(result)
76
+
77
+ return result
78
+
79
+ except ValueError:
80
+ raise ClientError(f"Error trying to convert response to JSON: {response_text}")
@@ -7,8 +7,10 @@ from tplinkrouterc6u.client.deco import TPLinkDecoClient
7
7
  from tplinkrouterc6u.client_abstract import AbstractRouter
8
8
  from tplinkrouterc6u.client.mr import TPLinkMRClient, TPLinkMRClientGCM
9
9
  from tplinkrouterc6u.client.mr200 import TPLinkMR200Client
10
+ from tplinkrouterc6u.client.mr6400v7 import TPLinkMR6400v7Client
10
11
  from tplinkrouterc6u.client.ex import TPLinkEXClient, TPLinkEXClientGCM
11
12
  from tplinkrouterc6u.client.c5400x import TplinkC5400XRouter
13
+ from tplinkrouterc6u.client.c3200 import TplinkC3200Router
12
14
  from tplinkrouterc6u.client.c1200 import TplinkC1200Router
13
15
  from tplinkrouterc6u.client.c80 import TplinkC80Router
14
16
  from tplinkrouterc6u.client.vr import TPLinkVRClient
@@ -30,6 +32,7 @@ class TplinkRouterProvider:
30
32
  TPLinkMRClientGCM,
31
33
  TPLinkMRClient,
32
34
  TPLinkMR200Client,
35
+ TPLinkMR6400v7Client,
33
36
  TPLinkVR400v2Client,
34
37
  TPLinkDecoClient,
35
38
  TPLinkXDRClient,
@@ -39,6 +42,7 @@ class TplinkRouterProvider:
39
42
  TplinkC80Router,
40
43
  TplinkWDRRouter,
41
44
  TplinkRE330Router,
45
+ TplinkC3200Router,
42
46
  ]:
43
47
  router = client(host, password, username, logger, verify_ssl, timeout)
44
48
  if router.supports():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tplinkrouterc6u
3
- Version: 5.13.0
3
+ Version: 5.14.0
4
4
  Summary: TP-Link Router API (supports also Mercusys Router)
5
5
  Home-page: https://github.com/AlexandrErohin/TP-Link-Archer-C6U
6
6
  Author: Alex Erohin
@@ -63,6 +63,7 @@ from tplinkrouterc6u import (
63
63
  TPLinkMRClient, # Class for MR series routers which supports old firmwares with AES cipher CBC mode
64
64
  TPLinkMRClientGCM, # Class for MR series routers which supports AES cipher GCM mode
65
65
  TPLinkMR200Client,
66
+ TPLinkMR6400v7Client,
66
67
  TPLinkVRClient,
67
68
  TPLinkVR400v2Client,
68
69
  TPLinkEXClient, # Class for EX series routers which supports old firmwares with AES cipher CBC mode
@@ -73,6 +74,7 @@ from tplinkrouterc6u import (
73
74
  TplinkC80Router,
74
75
  TplinkWDRRouter,
75
76
  TplinkRE330Router,
77
+ TplinkC3200Router,
76
78
  Connection
77
79
  )
78
80
  from logging import Logger
@@ -345,6 +347,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
345
347
  - Archer BE3600 1.6
346
348
  - Archer C1200 (v1.0, v2.0)
347
349
  - Archer C2300 (v1.0, v2.0)
350
+ - Archer C3200
348
351
  - Archer C6 (v2.0, v3.0, v3.20, 4.0)
349
352
  - Archer C6U v1.0
350
353
  - Archer C7 (v4.0, v5.0)
@@ -392,7 +395,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
392
395
  - TL-MR100-Outdoor v1.0
393
396
  - TL-MR110-Outdoor v1.0
394
397
  - TL-MR150 v2
395
- - TL-MR6400 (v5, v5.3)
398
+ - TL-MR6400 (v5, v5.3, v7)
396
399
  - TL-MR6500v
397
400
  - TL-R470GP-AC 4.0
398
401
  - TL-R488GPM-AC 2.0
@@ -1,29 +1,32 @@
1
1
  test/__init__.py,sha256=McQmUjeN3AwmwdS6QNfwGXXE77OKoPK852I2BM9XsrU,210
2
+ test/test_client_C3200.py,sha256=jQoGq3yasoOc2Da37RkZ8uT0uyFrKfX2OGGy7hq02A0,20932
2
3
  test/test_client_c1200.py,sha256=Sl-85JGqINNg-ckBZCIVqY0CC-V1UOc-yiIUljtePRM,7582
3
4
  test/test_client_c6u.py,sha256=GGYReY9RmnkJDgcaWtzbti-hTkab2D8JXxZCPt0wTfk,41662
4
5
  test/test_client_c6u_v1_11.py,sha256=FkpDRYk-LKC_YFNyrDUZUm7_x89REMnl4zquiEtyFB4,3343
5
6
  test/test_client_c80.py,sha256=RY_1SgRVcQQdN9h0_IXA0YW4_0flEB_uel05QvDDfws,42359
6
7
  test/test_client_deco.py,sha256=YPLKRD8GoyDYHfRgdXvCk8iVNw8zdMJW-AHVnNbpdTM,31719
7
- test/test_client_ex.py,sha256=ny7ube06QbI1h_UT0bAUllhLK2sqQ4Mb3WwtY8kDoRY,31374
8
- test/test_client_mr.py,sha256=lePxkmjcPzcrSFcaT8bT67L154cVJIOWrFlXMDOa8oY,33423
8
+ test/test_client_ex.py,sha256=_HvQhT2dG63fg6kJkgnZoPwa9qCgFDjWSAYQfjgVRA4,40480
9
+ test/test_client_mr.py,sha256=HYn39wynxeWKyWLGKpnBrutnb1Yq6k1tp6_vH-L_UKQ,33839
9
10
  test/test_client_mr_200.py,sha256=86yANn5SUhVW6Uc5q5s_aTNL7tDnREeXk378G61v_TM,1186
10
11
  test/test_client_r.py,sha256=AMZklBTLDmnlluNu8hyJfty-1lnN9YReIT522D2Bf9c,20565
11
12
  test/test_client_re330.py,sha256=MgefuvOzfZtZOujrcOsjiTDiGEAujfeFXshcq7gn32Q,17044
12
13
  test/test_client_vr400v2.py,sha256=J1MFUQKGX0czhYS2s8q1Fa8-aKAZ9RfWb0rE_yAxXmg,1813
13
14
  test/test_client_wdr.py,sha256=0ZnRNP57MbuMv2cxFS8iIoVyv8Q6gtY0Q03gtHp9AWY,13492
14
15
  test/test_client_xdr.py,sha256=o0d1mq5ev1wWcs7FvwYGMUKDSVZJREETZk__7Al5EtI,23640
15
- tplinkrouterc6u/__init__.py,sha256=1L-1-RMN0M9JoF2PhKuE-sKa5qdsU5Mw0JfjkE6kXrs,1295
16
+ tplinkrouterc6u/__init__.py,sha256=K5c8sBDldVKcD_OfMB83U3xfEkLyRfxdE3VAtbsMMAo,1419
16
17
  tplinkrouterc6u/client_abstract.py,sha256=3UYzmll774S_Gb5E0FTVO_rI3-XFM7PSklg1-V-2jls,1419
17
- tplinkrouterc6u/provider.py,sha256=VhMqts5OPDvFIScuDoGGqU5_PtNBTtqisi_QVfNvpaE,3013
18
+ tplinkrouterc6u/provider.py,sha256=XeUXzrpgo35DhFG7FvgcAtD0oZZlXl8OOyPfNAVfxMI,3224
18
19
  tplinkrouterc6u/client/__init__.py,sha256=KBy3fmtA9wgyFrb0Urh2x4CkKtWVnESdp-vxmuOvq0k,27
19
20
  tplinkrouterc6u/client/c1200.py,sha256=4XEYidEGmVIJk0YQLvmTnd0Gqa7glH2gUWvjreHpWrk,3178
21
+ tplinkrouterc6u/client/c3200.py,sha256=GjaOjcVoKlRiSjn19d1rEIfZbIP_6SWsqDlsd_BbC7I,7057
20
22
  tplinkrouterc6u/client/c5400x.py,sha256=ID9jC-kLUBBeETvOh8cxyQpKmJBIzdwNYR03DmvMN0s,4289
21
23
  tplinkrouterc6u/client/c6u.py,sha256=7OGRnAfc9S7-v2-CrM0rayqesYkhIPouK7LJUV2opno,23574
22
24
  tplinkrouterc6u/client/c80.py,sha256=efE0DEjEfzRFr35fjKA_hsv9YaWy_2dgLAaurDM-WQk,17665
23
25
  tplinkrouterc6u/client/deco.py,sha256=cpKRggKD2RvSmMZuD6tzsZmehAUCU9oLiTTHcZBW81Y,8898
24
- tplinkrouterc6u/client/ex.py,sha256=YzuKOkzCIXFhe1ggD8FP5d1fq1z2iWSmnXh0NTRiuy0,14880
25
- tplinkrouterc6u/client/mr.py,sha256=kNXk0bzBIIIM-4jMZOFp370vDPMJKwt2HmWGMjktguk,28954
26
- tplinkrouterc6u/client/mr200.py,sha256=febM1Eoc2_8NGJu-NrrAdj9zrlP_n7dOU6EVKktzMnw,5801
26
+ tplinkrouterc6u/client/ex.py,sha256=qqlVJi2BIlMLjL9A2_Yi-5AFk18A1Ts8zW6qRPQQWQM,15016
27
+ tplinkrouterc6u/client/mr.py,sha256=Yh7U0nWa_l5HKrUM5fDGewQlxHlyK-JcoPFXmSDgog4,29606
28
+ tplinkrouterc6u/client/mr200.py,sha256=Z02ew7ZLCEdNyGB7mcPHPP-oaAUwJyt7euc2ubiuEo4,5891
29
+ tplinkrouterc6u/client/mr6400v7.py,sha256=PR7dk4Q0OMqMwnuExpHFjanCYAcZ2gjnJ0XoMV-ex8I,2407
27
30
  tplinkrouterc6u/client/r.py,sha256=H-qArD60gasT07pEeY48n0_c6-yUbAKL7IRmQtr6jXk,7632
28
31
  tplinkrouterc6u/client/re330.py,sha256=9Wj4VpYJbVwZJUh9s3magdeL3Jl-B7qyrWfrVBxRk4A,17465
29
32
  tplinkrouterc6u/client/vr.py,sha256=7Tbu0IrWtr4HHtyrnLFXEJi1QctzhilciL7agtwQ0R8,5025
@@ -36,8 +39,8 @@ tplinkrouterc6u/common/encryption.py,sha256=EWfgGafOz0YgPilBndVaupnjw6JrzhVBdZkB
36
39
  tplinkrouterc6u/common/exception.py,sha256=_0G8ZvW5__CsGifHrsZeULdl8c6EUD071sDCQsQgrHY,140
37
40
  tplinkrouterc6u/common/helper.py,sha256=23b04fk9HuVinrZXMCS5R1rmF8uZ7eM-Cdnp7Br9NR0,572
38
41
  tplinkrouterc6u/common/package_enum.py,sha256=CMHVSgk4RSZyFoPi3499-sJDYg-nfnyJbz1iArFU9Hw,1644
39
- tplinkrouterc6u-5.13.0.dist-info/licenses/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
40
- tplinkrouterc6u-5.13.0.dist-info/METADATA,sha256=nPa1F-ywVtgS8vH5U6y5WL7-Mxa1l3cgaEbsg7nTxA0,17785
41
- tplinkrouterc6u-5.13.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
42
- tplinkrouterc6u-5.13.0.dist-info/top_level.txt,sha256=1iSCCIueqgEkrTxtQ-jiHe99jAB10zqrVdBcwvNfe_M,21
43
- tplinkrouterc6u-5.13.0.dist-info/RECORD,,
42
+ tplinkrouterc6u-5.14.0.dist-info/licenses/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
43
+ tplinkrouterc6u-5.14.0.dist-info/METADATA,sha256=9FKClNuCn3ur3yEcnUmUZ5G7eBBN-j1aCyfBQZGtxmY,17853
44
+ tplinkrouterc6u-5.14.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
45
+ tplinkrouterc6u-5.14.0.dist-info/top_level.txt,sha256=1iSCCIueqgEkrTxtQ-jiHe99jAB10zqrVdBcwvNfe_M,21
46
+ tplinkrouterc6u-5.14.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5