tplinkrouterc6u 5.0.3__py3-none-any.whl → 5.2.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.
- test/{test_client.py → test_client_c6u.py} +2 -1
- test/test_client_ex.py +339 -0
- test/test_client_mr.py +365 -0
- test/test_client_xdr.py +536 -0
- tplinkrouterc6u/__init__.py +16 -12
- tplinkrouterc6u/client/__init__.py +1 -0
- tplinkrouterc6u/client/c1200.py +102 -0
- tplinkrouterc6u/client/c5400x.py +109 -0
- tplinkrouterc6u/client/c6u.py +436 -0
- tplinkrouterc6u/client/c6v4.py +38 -0
- tplinkrouterc6u/client/deco.py +177 -0
- tplinkrouterc6u/client/ex.py +295 -0
- tplinkrouterc6u/client/mr.py +712 -0
- tplinkrouterc6u/client/xdr.py +263 -0
- tplinkrouterc6u/client_abstract.py +48 -0
- tplinkrouterc6u/common/__init__.py +1 -0
- tplinkrouterc6u/{dataclass.py → common/dataclass.py} +40 -1
- tplinkrouterc6u/{package_enum.py → common/package_enum.py} +5 -0
- tplinkrouterc6u/provider.py +39 -0
- {tplinkrouterc6u-5.0.3.dist-info → tplinkrouterc6u-5.2.0.dist-info}/METADATA +52 -2
- tplinkrouterc6u-5.2.0.dist-info/RECORD +30 -0
- {tplinkrouterc6u-5.0.3.dist-info → tplinkrouterc6u-5.2.0.dist-info}/WHEEL +1 -1
- tplinkrouterc6u/client.py +0 -1451
- tplinkrouterc6u-5.0.3.dist-info/RECORD +0 -17
- /tplinkrouterc6u/{encryption.py → common/encryption.py} +0 -0
- /tplinkrouterc6u/{exception.py → common/exception.py} +0 -0
- /tplinkrouterc6u/{helper.py → common/helper.py} +0 -0
- {tplinkrouterc6u-5.0.3.dist-info → tplinkrouterc6u-5.2.0.dist-info}/LICENSE +0 -0
- {tplinkrouterc6u-5.0.3.dist-info → tplinkrouterc6u-5.2.0.dist-info}/top_level.txt +0 -0
test/test_client_xdr.py
ADDED
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from ipaddress import IPv4Address
|
|
3
|
+
from unittest import TestCase, main
|
|
4
|
+
|
|
5
|
+
from macaddress import EUI48
|
|
6
|
+
|
|
7
|
+
from tplinkrouterc6u import IPv4Status
|
|
8
|
+
from tplinkrouterc6u.client.xdr import TPLinkXDRClient
|
|
9
|
+
from tplinkrouterc6u.common.dataclass import (Device, Firmware, IPv4DHCPLease,
|
|
10
|
+
IPv4Reservation, Status)
|
|
11
|
+
from tplinkrouterc6u.common.helper import get_ip, get_mac
|
|
12
|
+
from tplinkrouterc6u.common.package_enum import Connection
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TestTPLinkXDRClient(TestCase):
|
|
16
|
+
def test_logout(self) -> None:
|
|
17
|
+
mock_data = json.loads('''{"error_code":0}''')
|
|
18
|
+
check_payload = {}
|
|
19
|
+
|
|
20
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
21
|
+
def _request(self, payload: dict) -> dict:
|
|
22
|
+
nonlocal check_payload
|
|
23
|
+
check_payload = payload
|
|
24
|
+
return mock_data
|
|
25
|
+
|
|
26
|
+
client = TPLinkXDRClientTest('', '')
|
|
27
|
+
client.logout()
|
|
28
|
+
|
|
29
|
+
self.assertEqual(check_payload['method'], 'do')
|
|
30
|
+
self.assertIn('system', check_payload)
|
|
31
|
+
self.assertIn('logout', check_payload['system'])
|
|
32
|
+
self.assertEqual(check_payload['system']['logout'], None)
|
|
33
|
+
|
|
34
|
+
def test_get_firmware(self) -> None:
|
|
35
|
+
mock_data = json.loads('''
|
|
36
|
+
{
|
|
37
|
+
"device_info": {
|
|
38
|
+
"info": {
|
|
39
|
+
"sys_software_revision": "1342242834",
|
|
40
|
+
"sys_software_revision_minor": "0",
|
|
41
|
+
"device_name": "TP-LINK Wireless Router TL-XDR3010\u6613\u5c55\u7248",
|
|
42
|
+
"device_info": "XDR3010\u6613\u5c55\u7248V2 Wireless Router",
|
|
43
|
+
"device_model": "TL-XDR3010\u6613\u5c55\u7248",
|
|
44
|
+
"hw_version": "TL-XDR3010\u6613\u5c55\u7248 2.0",
|
|
45
|
+
"domain_name": "tplogin.cn",
|
|
46
|
+
"language": "CN",
|
|
47
|
+
"product_id": "806395938",
|
|
48
|
+
"vendor_id": "0",
|
|
49
|
+
"sw_version": "1.0.18 Build 220711 Rel.56168n",
|
|
50
|
+
"enable_dns": "1"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"error_code": 0
|
|
54
|
+
}''')
|
|
55
|
+
check_payload = {}
|
|
56
|
+
|
|
57
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
58
|
+
def _request(self, payload: dict) -> dict:
|
|
59
|
+
nonlocal check_payload
|
|
60
|
+
check_payload = payload
|
|
61
|
+
return mock_data
|
|
62
|
+
|
|
63
|
+
client = TPLinkXDRClientTest('', '')
|
|
64
|
+
firmware = client.get_firmware()
|
|
65
|
+
|
|
66
|
+
self.assertEqual(check_payload['method'], 'get')
|
|
67
|
+
self.assertIn('device_info', check_payload)
|
|
68
|
+
self.assertIn('name', check_payload['device_info'])
|
|
69
|
+
self.assertEqual(check_payload['device_info']['name'], 'info')
|
|
70
|
+
|
|
71
|
+
self.assertIsInstance(firmware, Firmware)
|
|
72
|
+
self.assertEqual(firmware.firmware_version, '1.0.18 Build 220711 Rel.56168n')
|
|
73
|
+
self.assertEqual(firmware.hardware_version, 'TL-XDR3010易展版 2.0')
|
|
74
|
+
self.assertEqual(firmware.model, 'TL-XDR3010易展版')
|
|
75
|
+
|
|
76
|
+
def test_get_status(self) -> None:
|
|
77
|
+
mock_data = json.loads('''{
|
|
78
|
+
"hosts_info": {
|
|
79
|
+
"host_info": [
|
|
80
|
+
{
|
|
81
|
+
"host_info_5": {
|
|
82
|
+
"mac": "b8-27-eb-0e-87-eb",
|
|
83
|
+
"parent_mac": "ec-60-73-2b-0b-ee",
|
|
84
|
+
"is_mesh": "0",
|
|
85
|
+
"wifi_mode": "0",
|
|
86
|
+
"type": "0",
|
|
87
|
+
"blocked": "0",
|
|
88
|
+
"ip": "192.168.1.200",
|
|
89
|
+
"hostname": "raspberrypi",
|
|
90
|
+
"up_speed": "0",
|
|
91
|
+
"down_speed": "0",
|
|
92
|
+
"up_limit": "0",
|
|
93
|
+
"down_limit": "0",
|
|
94
|
+
"is_cur_host": "1",
|
|
95
|
+
"ssid": "",
|
|
96
|
+
"forbid_domain": "",
|
|
97
|
+
"limit_time": "",
|
|
98
|
+
"plan_rule": []
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"host_info_3": {
|
|
103
|
+
"mac": "24-59-e5-d0-21-8c",
|
|
104
|
+
"parent_mac": "ec-60-73-2b-0b-ee",
|
|
105
|
+
"is_mesh": "0",
|
|
106
|
+
"wifi_mode": "0",
|
|
107
|
+
"type": "1",
|
|
108
|
+
"blocked": "0",
|
|
109
|
+
"ip": "192.168.1.201",
|
|
110
|
+
"hostname": "midea%5Fac%5F0361",
|
|
111
|
+
"up_speed": "0",
|
|
112
|
+
"down_speed": "0",
|
|
113
|
+
"up_limit": "0",
|
|
114
|
+
"down_limit": "0",
|
|
115
|
+
"is_cur_host": "0",
|
|
116
|
+
"ssid": "",
|
|
117
|
+
"forbid_domain": "",
|
|
118
|
+
"limit_time": "",
|
|
119
|
+
"plan_rule": []
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
"network": {
|
|
125
|
+
"wan_status": {
|
|
126
|
+
"ipaddr": "0.0.0.0",
|
|
127
|
+
"netmask": "0.0.0.0",
|
|
128
|
+
"gateway": "0.0.0.0",
|
|
129
|
+
"pri_dns": "0.0.0.0",
|
|
130
|
+
"snd_dns": "0.0.0.0",
|
|
131
|
+
"link_status": 0,
|
|
132
|
+
"error_code": 4,
|
|
133
|
+
"proto": "dhcp",
|
|
134
|
+
"up_time": 0,
|
|
135
|
+
"up_speed": 0,
|
|
136
|
+
"down_speed": 0,
|
|
137
|
+
"phy_status": 0
|
|
138
|
+
},
|
|
139
|
+
"lan": {
|
|
140
|
+
"ipaddr": "192.168.1.100",
|
|
141
|
+
"netmask": "255.255.255.0",
|
|
142
|
+
"ip_mode": "dynamic",
|
|
143
|
+
"fac_ipaddr": "192.168.1.1",
|
|
144
|
+
"fac_netmask": "255.255.255.0",
|
|
145
|
+
"macaddr": "ec-60-73-2b-0b-ee"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"wireless": {
|
|
149
|
+
"wlan_bs": {
|
|
150
|
+
"wifi_enable": "1",
|
|
151
|
+
"bs_enable": "1",
|
|
152
|
+
"ssid": "tx",
|
|
153
|
+
"ssidbrd": "1",
|
|
154
|
+
"encryption": "1",
|
|
155
|
+
"key": "123654789a.",
|
|
156
|
+
"auth": "0",
|
|
157
|
+
"cipher": "1"
|
|
158
|
+
},
|
|
159
|
+
"wlan_host_2g": {
|
|
160
|
+
"enable": "1",
|
|
161
|
+
"ssid": "tx",
|
|
162
|
+
"ssidbrd": "1",
|
|
163
|
+
"encryption": "1",
|
|
164
|
+
"key": "123654789a.",
|
|
165
|
+
"channel": "0",
|
|
166
|
+
"mode": "9",
|
|
167
|
+
"bandwidth": "1",
|
|
168
|
+
"power": "0",
|
|
169
|
+
"isolate": "0",
|
|
170
|
+
"turboon": "0",
|
|
171
|
+
"auth": "0",
|
|
172
|
+
"cipher": "1",
|
|
173
|
+
"twt": "0",
|
|
174
|
+
"ofdma": "1"
|
|
175
|
+
},
|
|
176
|
+
"wlan_wds_2g": {
|
|
177
|
+
"enable": "0",
|
|
178
|
+
"ssid": "",
|
|
179
|
+
"bssid": "00-00-00-00-00-00",
|
|
180
|
+
"encryption": "0",
|
|
181
|
+
"key": "",
|
|
182
|
+
"address_form": "0",
|
|
183
|
+
"in_wizard": "0"
|
|
184
|
+
},
|
|
185
|
+
"wlan_host_5g": {
|
|
186
|
+
"enable": "0",
|
|
187
|
+
"ssid": "TP-LINK_5G_0BEE",
|
|
188
|
+
"ssidbrd": "1",
|
|
189
|
+
"encryption": "0",
|
|
190
|
+
"key": "",
|
|
191
|
+
"channel": "0",
|
|
192
|
+
"mode": "10",
|
|
193
|
+
"bandwidth": "0",
|
|
194
|
+
"power": "0",
|
|
195
|
+
"isolate": "0",
|
|
196
|
+
"turboon": "0",
|
|
197
|
+
"auth": "0",
|
|
198
|
+
"cipher": "1",
|
|
199
|
+
"twt": "1",
|
|
200
|
+
"ofdma": "1"
|
|
201
|
+
},
|
|
202
|
+
"wlan_wds_5g": {
|
|
203
|
+
"enable": "0",
|
|
204
|
+
"ssid": "",
|
|
205
|
+
"bssid": "00-00-00-00-00-00",
|
|
206
|
+
"encryption": "0",
|
|
207
|
+
"key": "",
|
|
208
|
+
"address_form": "0",
|
|
209
|
+
"in_wizard": "0"
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
"guest_network": {
|
|
213
|
+
"guest_2g": {
|
|
214
|
+
"ssid": "TPGuest%5F0BEE",
|
|
215
|
+
"encrypt": "0",
|
|
216
|
+
"key": "",
|
|
217
|
+
"enable": "0",
|
|
218
|
+
"accright": "0",
|
|
219
|
+
"upload": "0",
|
|
220
|
+
"download": "0",
|
|
221
|
+
"time_limit": "0",
|
|
222
|
+
"limit_type": "timeout",
|
|
223
|
+
"duration": "0",
|
|
224
|
+
"auth": "0",
|
|
225
|
+
"cipher": "1"
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"error_code": 0
|
|
229
|
+
}''')
|
|
230
|
+
check_payload = {}
|
|
231
|
+
|
|
232
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
233
|
+
def _request(self, payload: dict) -> dict:
|
|
234
|
+
nonlocal check_payload
|
|
235
|
+
check_payload = payload
|
|
236
|
+
return mock_data
|
|
237
|
+
|
|
238
|
+
client = TPLinkXDRClientTest('', '')
|
|
239
|
+
status = client.get_status()
|
|
240
|
+
|
|
241
|
+
self.assertEqual(check_payload['method'], 'get')
|
|
242
|
+
self.assertEqual(check_payload['hosts_info']['table'], 'host_info')
|
|
243
|
+
self.assertIn('network', check_payload)
|
|
244
|
+
self.assertIn('name', check_payload['network'])
|
|
245
|
+
self.assertEqual(check_payload['network']['name'], ['wan_status', 'lan'])
|
|
246
|
+
self.assertIn('wireless', check_payload)
|
|
247
|
+
self.assertIn('name', check_payload['wireless'])
|
|
248
|
+
self.assertEqual(check_payload['wireless']['name'], [
|
|
249
|
+
'wlan_bs',
|
|
250
|
+
'wlan_host_2g',
|
|
251
|
+
'wlan_wds_2g',
|
|
252
|
+
'wlan_host_5g',
|
|
253
|
+
'wlan_wds_5g',
|
|
254
|
+
])
|
|
255
|
+
self.assertIn('guest_network', check_payload)
|
|
256
|
+
self.assertIn('name', check_payload['guest_network'])
|
|
257
|
+
self.assertEqual(check_payload['guest_network']['name'], ['guest_2g'])
|
|
258
|
+
|
|
259
|
+
self.assertIsInstance(status, Status)
|
|
260
|
+
self.assertEqual(status.lan_ipv4_addr, '192.168.1.100')
|
|
261
|
+
self.assertIsInstance(status.lan_ipv4_address, IPv4Address)
|
|
262
|
+
self.assertEqual(status.lan_macaddr, 'EC-60-73-2B-0B-EE')
|
|
263
|
+
self.assertIsInstance(status.lan_macaddress, EUI48)
|
|
264
|
+
self.assertEqual(status.wan_ipv4_addr, '0.0.0.0')
|
|
265
|
+
self.assertIsInstance(status.wan_ipv4_address, IPv4Address)
|
|
266
|
+
self.assertTrue(status.wifi_2g_enable)
|
|
267
|
+
self.assertTrue(status.wifi_5g_enable)
|
|
268
|
+
self.assertEqual(len(status.devices), 2)
|
|
269
|
+
self.assertIsInstance(status.devices[0], Device)
|
|
270
|
+
self.assertEqual(status.devices[0].type, Connection.WIRED)
|
|
271
|
+
self.assertEqual(status.devices[0].macaddr, 'B8-27-EB-0E-87-EB')
|
|
272
|
+
self.assertIsInstance(status.devices[0].macaddress, EUI48)
|
|
273
|
+
self.assertEqual(status.devices[0].ipaddr, '192.168.1.200')
|
|
274
|
+
self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
|
|
275
|
+
self.assertEqual(status.devices[0].hostname, 'raspberrypi')
|
|
276
|
+
self.assertIsInstance(status.devices[1], Device)
|
|
277
|
+
self.assertEqual(status.devices[1].type, Connection.HOST_2G)
|
|
278
|
+
self.assertEqual(status.devices[1].macaddr, '24-59-E5-D0-21-8C')
|
|
279
|
+
self.assertIsInstance(status.devices[1].macaddress, EUI48)
|
|
280
|
+
self.assertEqual(status.devices[1].ipaddr, '192.168.1.201')
|
|
281
|
+
self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
|
|
282
|
+
self.assertEqual(status.devices[1].hostname, 'midea_ac_0361')
|
|
283
|
+
|
|
284
|
+
def test_reboot(self) -> None:
|
|
285
|
+
mock_data = json.loads('''{"error_code":0}''')
|
|
286
|
+
check_payload = {}
|
|
287
|
+
|
|
288
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
289
|
+
def _request(self, payload: dict) -> dict:
|
|
290
|
+
nonlocal check_payload
|
|
291
|
+
check_payload = payload
|
|
292
|
+
return mock_data
|
|
293
|
+
|
|
294
|
+
client = TPLinkXDRClientTest('', '')
|
|
295
|
+
client.reboot()
|
|
296
|
+
|
|
297
|
+
self.assertEqual(check_payload['method'], 'do')
|
|
298
|
+
self.assertIn('system', check_payload)
|
|
299
|
+
self.assertIn('reboot', check_payload['system'])
|
|
300
|
+
self.assertEqual(check_payload['system']['reboot'], None)
|
|
301
|
+
|
|
302
|
+
def test_set_wifi_enable_guest_2g(self) -> None:
|
|
303
|
+
mock_data = json.loads('''{"error_code":0}''')
|
|
304
|
+
check_payload = {}
|
|
305
|
+
|
|
306
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
307
|
+
def _request(self, payload: dict) -> dict:
|
|
308
|
+
nonlocal check_payload
|
|
309
|
+
check_payload = payload
|
|
310
|
+
return mock_data
|
|
311
|
+
|
|
312
|
+
client = TPLinkXDRClientTest('', '')
|
|
313
|
+
client.set_wifi(Connection.GUEST_2G, True)
|
|
314
|
+
|
|
315
|
+
self.assertEqual(check_payload['method'], 'set')
|
|
316
|
+
self.assertIn('guest_network', check_payload)
|
|
317
|
+
self.assertIn('guest_2g', check_payload['guest_network'])
|
|
318
|
+
self.assertEqual(check_payload['guest_network']['guest_2g']['enable'], '1')
|
|
319
|
+
|
|
320
|
+
def test_set_wifi_enable_host_2g(self) -> None:
|
|
321
|
+
mock_data = json.loads('''{"error_code":0}''')
|
|
322
|
+
check_payload = {}
|
|
323
|
+
|
|
324
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
325
|
+
def _request(self, payload: dict) -> dict:
|
|
326
|
+
nonlocal check_payload
|
|
327
|
+
check_payload = payload
|
|
328
|
+
return mock_data
|
|
329
|
+
|
|
330
|
+
client = TPLinkXDRClientTest('', '')
|
|
331
|
+
client.set_wifi(Connection.HOST_2G, True)
|
|
332
|
+
|
|
333
|
+
self.assertEqual(check_payload['method'], 'set')
|
|
334
|
+
self.assertIn('wireless', check_payload)
|
|
335
|
+
self.assertIn('wlan_host_2g', check_payload['wireless'])
|
|
336
|
+
self.assertEqual(check_payload['wireless']['wlan_host_2g']['enable'], 1)
|
|
337
|
+
|
|
338
|
+
def test_set_wifi_disable_host_5g(self) -> None:
|
|
339
|
+
mock_data = json.loads('''{"error_code":0}''')
|
|
340
|
+
check_payload = {}
|
|
341
|
+
|
|
342
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
343
|
+
def _request(self, payload: dict) -> dict:
|
|
344
|
+
nonlocal check_payload
|
|
345
|
+
check_payload = payload
|
|
346
|
+
return mock_data
|
|
347
|
+
|
|
348
|
+
client = TPLinkXDRClientTest('', '')
|
|
349
|
+
client.set_wifi(Connection.HOST_5G, False)
|
|
350
|
+
|
|
351
|
+
self.assertEqual(check_payload['method'], 'set')
|
|
352
|
+
self.assertIn('wireless', check_payload)
|
|
353
|
+
self.assertIn('wlan_host_5g', check_payload['wireless'])
|
|
354
|
+
self.assertEqual(check_payload['wireless']['wlan_host_5g']['enable'], 0)
|
|
355
|
+
|
|
356
|
+
def test_get_ipv4_reservations(self):
|
|
357
|
+
mock_data = json.loads('''{
|
|
358
|
+
"ip_mac_bind": {
|
|
359
|
+
"user_bind": [{"user_bind_3": {"mac": "24-59-E5-D0-21-8C", "ip": "192.168.2.202", "hostname": "midea_ac_0361"}}]
|
|
360
|
+
},
|
|
361
|
+
"error_code": 0}
|
|
362
|
+
''')
|
|
363
|
+
check_payload = {}
|
|
364
|
+
|
|
365
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
366
|
+
def _request(self, payload: dict) -> dict:
|
|
367
|
+
nonlocal check_payload
|
|
368
|
+
check_payload = payload
|
|
369
|
+
return mock_data
|
|
370
|
+
|
|
371
|
+
client = TPLinkXDRClientTest('', '')
|
|
372
|
+
reservations = client.get_ipv4_reservations()
|
|
373
|
+
|
|
374
|
+
self.assertEqual(check_payload['method'], 'get')
|
|
375
|
+
self.assertIsInstance(check_payload['ip_mac_bind'], dict)
|
|
376
|
+
self.assertEqual(check_payload['ip_mac_bind']['table'], 'user_bind')
|
|
377
|
+
|
|
378
|
+
self.assertEqual(len(reservations), 1)
|
|
379
|
+
self.assertIsInstance(reservations[0], IPv4Reservation)
|
|
380
|
+
self.assertEqual(reservations[0].macaddr, '24-59-E5-D0-21-8C')
|
|
381
|
+
self.assertIsInstance(reservations[0].macaddress, EUI48)
|
|
382
|
+
self.assertEqual(reservations[0].macaddress, get_mac('24-59-E5-D0-21-8C'))
|
|
383
|
+
self.assertEqual(reservations[0].ipaddr, '192.168.2.202')
|
|
384
|
+
self.assertIsInstance(reservations[0].ipaddress, IPv4Address)
|
|
385
|
+
self.assertEqual(reservations[0].ipaddress, get_ip('192.168.2.202'))
|
|
386
|
+
self.assertEqual(reservations[0].hostname, 'midea_ac_0361')
|
|
387
|
+
|
|
388
|
+
def test_get_ipv4_dhcp_leases(self):
|
|
389
|
+
mock_data = json.loads('''
|
|
390
|
+
{
|
|
391
|
+
"dhcpd": {
|
|
392
|
+
"dhcp_clients": [
|
|
393
|
+
{
|
|
394
|
+
"dhcp_client_1": {
|
|
395
|
+
"mac": "24-59-e5-d0-21-8c",
|
|
396
|
+
"ip": "192.168.2.202",
|
|
397
|
+
"hostname": "midea_ac_0361",
|
|
398
|
+
"expires": "4294967295"
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"dhcp_client_2": {
|
|
403
|
+
"mac": "b8-27-eb-0e-87-eb",
|
|
404
|
+
"ip": "192.168.2.200",
|
|
405
|
+
"hostname": "raspberrypi",
|
|
406
|
+
"expires": "3200"
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
]
|
|
410
|
+
},
|
|
411
|
+
"error_code": 0
|
|
412
|
+
}''')
|
|
413
|
+
check_payload = {}
|
|
414
|
+
|
|
415
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
416
|
+
def _request(self, payload: dict) -> dict:
|
|
417
|
+
nonlocal check_payload
|
|
418
|
+
check_payload = payload
|
|
419
|
+
return mock_data
|
|
420
|
+
|
|
421
|
+
client = TPLinkXDRClientTest('', '')
|
|
422
|
+
dhcp_leases = client.get_ipv4_dhcp_leases()
|
|
423
|
+
|
|
424
|
+
self.assertEqual(check_payload['method'], 'get')
|
|
425
|
+
self.assertIsInstance(check_payload['dhcpd'], dict)
|
|
426
|
+
self.assertEqual(check_payload['dhcpd']['table'], 'dhcp_clients')
|
|
427
|
+
|
|
428
|
+
self.assertEqual(len(dhcp_leases), 2)
|
|
429
|
+
self.assertIsInstance(dhcp_leases[0], IPv4DHCPLease)
|
|
430
|
+
self.assertEqual(dhcp_leases[0].macaddr, '24-59-E5-D0-21-8C')
|
|
431
|
+
self.assertIsInstance(dhcp_leases[0].macaddress, EUI48)
|
|
432
|
+
self.assertEqual(dhcp_leases[0].macaddress, get_mac('24-59-e5-d0-21-8c'))
|
|
433
|
+
self.assertEqual(dhcp_leases[0].ipaddr, '192.168.2.202')
|
|
434
|
+
self.assertIsInstance(dhcp_leases[0].ipaddress, IPv4Address)
|
|
435
|
+
self.assertEqual(dhcp_leases[0].ipaddress, get_ip('192.168.2.202'))
|
|
436
|
+
self.assertEqual(dhcp_leases[0].hostname, 'midea_ac_0361')
|
|
437
|
+
self.assertEqual(dhcp_leases[0].lease_time, 'Permanent')
|
|
438
|
+
self.assertIsInstance(dhcp_leases[1], IPv4DHCPLease)
|
|
439
|
+
self.assertEqual(dhcp_leases[1].macaddr, 'B8-27-EB-0E-87-EB')
|
|
440
|
+
self.assertIsInstance(dhcp_leases[1].macaddress, EUI48)
|
|
441
|
+
self.assertEqual(dhcp_leases[1].macaddress, get_mac('b8-27-eb-0e-87-eb'))
|
|
442
|
+
self.assertEqual(dhcp_leases[1].ipaddr, '192.168.2.200')
|
|
443
|
+
self.assertIsInstance(dhcp_leases[1].ipaddress, IPv4Address)
|
|
444
|
+
self.assertEqual(dhcp_leases[1].ipaddress, get_ip('192.168.2.200'))
|
|
445
|
+
self.assertEqual(dhcp_leases[1].hostname, 'raspberrypi')
|
|
446
|
+
self.assertEqual(dhcp_leases[1].lease_time, '0:53:20')
|
|
447
|
+
|
|
448
|
+
def test_get_ipv4_status(self):
|
|
449
|
+
mock_data = json.loads('''
|
|
450
|
+
{
|
|
451
|
+
"dhcpd": {
|
|
452
|
+
"udhcpd": {
|
|
453
|
+
"auto": "1",
|
|
454
|
+
"enable": "0",
|
|
455
|
+
"pool_start": "192.168.1.2",
|
|
456
|
+
"pool_end": "192.168.1.254",
|
|
457
|
+
"lease_time": "7200",
|
|
458
|
+
"pri_dns": "211.136.192.6",
|
|
459
|
+
"snd_dns": "0.0.0.0",
|
|
460
|
+
"gateway": "192.168.2.1",
|
|
461
|
+
"pool_extend": "1"
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
"network": {
|
|
465
|
+
"lan": {
|
|
466
|
+
"ipaddr": "192.168.1.100",
|
|
467
|
+
"netmask": "255.255.255.0",
|
|
468
|
+
"ip_mode": "dynamic",
|
|
469
|
+
"fac_ipaddr": "192.168.1.1",
|
|
470
|
+
"fac_netmask": "255.255.255.0",
|
|
471
|
+
"macaddr": "ec-60-73-2b-0b-ee"
|
|
472
|
+
},
|
|
473
|
+
"wan_status": {
|
|
474
|
+
"ipaddr": "0.0.0.0",
|
|
475
|
+
"netmask": "0.0.0.0",
|
|
476
|
+
"gateway": "0.0.0.0",
|
|
477
|
+
"pri_dns": "0.0.0.0",
|
|
478
|
+
"snd_dns": "0.0.0.0",
|
|
479
|
+
"link_status": 0,
|
|
480
|
+
"error_code": 4,
|
|
481
|
+
"proto": "dhcp",
|
|
482
|
+
"up_time": 0,
|
|
483
|
+
"up_speed": 0,
|
|
484
|
+
"down_speed": 0,
|
|
485
|
+
"phy_status": 0
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
"error_code": 0
|
|
489
|
+
}''')
|
|
490
|
+
check_payload = {}
|
|
491
|
+
|
|
492
|
+
class TPLinkXDRClientTest(TPLinkXDRClient):
|
|
493
|
+
def _request(self, payload: dict) -> dict:
|
|
494
|
+
nonlocal check_payload
|
|
495
|
+
check_payload = payload
|
|
496
|
+
return mock_data
|
|
497
|
+
|
|
498
|
+
client = TPLinkXDRClientTest('', '')
|
|
499
|
+
ipv4_status = client.get_ipv4_status()
|
|
500
|
+
|
|
501
|
+
self.assertEqual(check_payload['method'], 'get')
|
|
502
|
+
self.assertIsInstance(check_payload['dhcpd'], dict)
|
|
503
|
+
self.assertEqual(check_payload['dhcpd']['name'], 'udhcpd')
|
|
504
|
+
self.assertIsInstance(check_payload['network'], dict)
|
|
505
|
+
self.assertEqual(check_payload['network']['name'], ['lan', 'wan_status'])
|
|
506
|
+
|
|
507
|
+
self.assertIsInstance(ipv4_status, IPv4Status)
|
|
508
|
+
self.assertEqual(ipv4_status.wan_ipv4_ipaddr, '0.0.0.0')
|
|
509
|
+
self.assertIsInstance(ipv4_status.wan_ipv4_ipaddress, IPv4Address)
|
|
510
|
+
self.assertEqual(ipv4_status.wan_ipv4_ipaddress, get_ip('0.0.0.0'))
|
|
511
|
+
self.assertEqual(ipv4_status.wan_ipv4_gateway, '0.0.0.0')
|
|
512
|
+
self.assertIsInstance(ipv4_status.wan_ipv4_gateway_address, IPv4Address)
|
|
513
|
+
self.assertEqual(ipv4_status.wan_ipv4_gateway_address, get_ip('0.0.0.0'))
|
|
514
|
+
self.assertEqual(ipv4_status.wan_ipv4_netmask, '0.0.0.0')
|
|
515
|
+
self.assertIsInstance(ipv4_status.wan_ipv4_netmask_address, IPv4Address)
|
|
516
|
+
self.assertEqual(ipv4_status.wan_ipv4_netmask_address, get_ip('0.0.0.0'))
|
|
517
|
+
self.assertEqual(ipv4_status.wan_ipv4_pridns, '0.0.0.0')
|
|
518
|
+
self.assertIsInstance(ipv4_status.wan_ipv4_pridns_address, IPv4Address)
|
|
519
|
+
self.assertEqual(ipv4_status.wan_ipv4_pridns_address, get_ip('0.0.0.0'))
|
|
520
|
+
self.assertEqual(ipv4_status.wan_ipv4_snddns, '0.0.0.0')
|
|
521
|
+
self.assertIsInstance(ipv4_status.wan_ipv4_snddns_address, IPv4Address)
|
|
522
|
+
self.assertEqual(ipv4_status.wan_ipv4_snddns_address, get_ip('0.0.0.0'))
|
|
523
|
+
self.assertEqual(ipv4_status.lan_macaddr, 'EC-60-73-2B-0B-EE')
|
|
524
|
+
self.assertIsInstance(ipv4_status.lan_macaddress, EUI48)
|
|
525
|
+
self.assertEqual(ipv4_status.lan_macaddress, get_mac('EC-60-73-2B-0B-EE'))
|
|
526
|
+
self.assertEqual(ipv4_status.lan_ipv4_ipaddr, '192.168.1.100')
|
|
527
|
+
self.assertIsInstance(ipv4_status.lan_ipv4_ipaddress, IPv4Address)
|
|
528
|
+
self.assertEqual(ipv4_status.lan_ipv4_ipaddress, get_ip('192.168.1.100'))
|
|
529
|
+
self.assertEqual(ipv4_status.lan_ipv4_dhcp_enable, False)
|
|
530
|
+
self.assertEqual(ipv4_status.lan_ipv4_netmask, '255.255.255.0')
|
|
531
|
+
self.assertIsInstance(ipv4_status.lan_ipv4_netmask_address, IPv4Address)
|
|
532
|
+
self.assertEqual(ipv4_status.lan_ipv4_netmask_address, get_ip('255.255.255.0'))
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
if __name__ == '__main__':
|
|
536
|
+
main()
|
tplinkrouterc6u/__init__.py
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
from tplinkrouterc6u.client import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
from tplinkrouterc6u.
|
|
11
|
-
from tplinkrouterc6u.
|
|
1
|
+
from tplinkrouterc6u.client.c6u import TplinkRouter
|
|
2
|
+
from tplinkrouterc6u.client.deco import TPLinkDecoClient
|
|
3
|
+
from tplinkrouterc6u.client_abstract import AbstractRouter
|
|
4
|
+
from tplinkrouterc6u.client.mr import TPLinkMRClient
|
|
5
|
+
from tplinkrouterc6u.client.ex import TPLinkEXClient
|
|
6
|
+
from tplinkrouterc6u.client.c6v4 import TplinkC6V4Router
|
|
7
|
+
from tplinkrouterc6u.client.c5400x import TplinkC5400XRouter
|
|
8
|
+
from tplinkrouterc6u.client.c1200 import TplinkC1200Router
|
|
9
|
+
from tplinkrouterc6u.client.xdr import TPLinkXDRClient
|
|
10
|
+
from tplinkrouterc6u.provider import TplinkRouterProvider
|
|
11
|
+
from tplinkrouterc6u.common.package_enum import Connection, VPN
|
|
12
|
+
from tplinkrouterc6u.common.dataclass import (
|
|
12
13
|
Firmware,
|
|
13
14
|
Status,
|
|
14
15
|
Device,
|
|
15
16
|
IPv4Reservation,
|
|
16
17
|
IPv4DHCPLease,
|
|
17
18
|
IPv4Status,
|
|
19
|
+
SMS,
|
|
20
|
+
LTEStatus,
|
|
21
|
+
VPNStatus,
|
|
18
22
|
)
|
|
19
|
-
from tplinkrouterc6u.exception import ClientException
|
|
23
|
+
from tplinkrouterc6u.common.exception import ClientException, ClientError, AuthorizeError
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""All clients are here"""
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from re import search
|
|
2
|
+
from requests import post, Response
|
|
3
|
+
from tplinkrouterc6u.common.encryption import EncryptionWrapper
|
|
4
|
+
from tplinkrouterc6u.common.exception import ClientException, AuthorizeError
|
|
5
|
+
from tplinkrouterc6u.client.c5400x import TplinkC5400XRouter
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TplinkC1200Router(TplinkC5400XRouter):
|
|
9
|
+
username = ''
|
|
10
|
+
password = ''
|
|
11
|
+
_pwdNN = ''
|
|
12
|
+
_pwdEE = ''
|
|
13
|
+
_encryption = EncryptionWrapper()
|
|
14
|
+
|
|
15
|
+
def supports(self) -> bool:
|
|
16
|
+
if len(self.password) > 125:
|
|
17
|
+
return False
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
self._request_pwd()
|
|
21
|
+
return True
|
|
22
|
+
except ClientException:
|
|
23
|
+
return False
|
|
24
|
+
|
|
25
|
+
def authorize(self) -> None:
|
|
26
|
+
if self._pwdNN == '':
|
|
27
|
+
self._request_pwd()
|
|
28
|
+
|
|
29
|
+
response = self._try_login()
|
|
30
|
+
|
|
31
|
+
is_valid_json = False
|
|
32
|
+
try:
|
|
33
|
+
response.json()
|
|
34
|
+
is_valid_json = True
|
|
35
|
+
except BaseException:
|
|
36
|
+
"""Ignore"""
|
|
37
|
+
|
|
38
|
+
if is_valid_json is False or response.status_code == 403:
|
|
39
|
+
self._logged = False
|
|
40
|
+
self._request_pwd()
|
|
41
|
+
response = self._try_login()
|
|
42
|
+
|
|
43
|
+
data = response.text
|
|
44
|
+
try:
|
|
45
|
+
data = response.json()
|
|
46
|
+
data = self._decrypt_response(data)
|
|
47
|
+
|
|
48
|
+
self._stok = data[self._data_block]['stok']
|
|
49
|
+
regex_result = search(
|
|
50
|
+
'sysauth=(.*);', response.headers['set-cookie'])
|
|
51
|
+
self._sysauth = regex_result.group(1)
|
|
52
|
+
self._logged = True
|
|
53
|
+
|
|
54
|
+
except Exception as e:
|
|
55
|
+
error = ("TplinkRouter - C1200 - Cannot authorize! Error - {}; Response - {}".format(e, data))
|
|
56
|
+
if self._logger:
|
|
57
|
+
self._logger.debug(error)
|
|
58
|
+
if 'data' in vars() and data.get('errorcode') == 'login failed':
|
|
59
|
+
raise AuthorizeError(error)
|
|
60
|
+
raise ClientException(error)
|
|
61
|
+
|
|
62
|
+
def _request_pwd(self) -> None:
|
|
63
|
+
url = '{}/cgi-bin/luci/;stok=/login?form=login'.format(self.host)
|
|
64
|
+
response = post(
|
|
65
|
+
url, params={'operation': 'read'},
|
|
66
|
+
timeout=self.timeout,
|
|
67
|
+
verify=self._verify_ssl,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
data = response.json()
|
|
72
|
+
|
|
73
|
+
args = data[self._data_block]['password']
|
|
74
|
+
|
|
75
|
+
self._pwdNN = args[0]
|
|
76
|
+
self._pwdEE = args[1]
|
|
77
|
+
|
|
78
|
+
except Exception as e:
|
|
79
|
+
error = ('TplinkRouter - C1200 - {} - Unknown error for pwd! Error - {}; Response - {}'
|
|
80
|
+
.format(self.__class__.__name__, e, response.text))
|
|
81
|
+
if self._logger:
|
|
82
|
+
self._logger.debug(error)
|
|
83
|
+
raise ClientException(error)
|
|
84
|
+
|
|
85
|
+
def _try_login(self) -> Response:
|
|
86
|
+
url = '{}/cgi-bin/luci/;stok=/login?form=login'.format(self.host)
|
|
87
|
+
|
|
88
|
+
crypted_pwd = self._encryption.encrypt_password_C1200(self.password, self._pwdNN, self._pwdEE)
|
|
89
|
+
|
|
90
|
+
body = self._get_login_data(crypted_pwd)
|
|
91
|
+
|
|
92
|
+
return post(
|
|
93
|
+
url,
|
|
94
|
+
data=body,
|
|
95
|
+
headers=self._headers_login,
|
|
96
|
+
timeout=self.timeout,
|
|
97
|
+
verify=self._verify_ssl,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def _get_login_data(crypted_pwd: str) -> str:
|
|
102
|
+
return 'operation=login&password={}'.format(crypted_pwd)
|