pymammotion 0.4.0a5__py3-none-any.whl → 0.4.0a7__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.
- pymammotion/aliyun/cloud_gateway.py +9 -1
- pymammotion/data/model/device.py +7 -4
- pymammotion/data/model/device_info.py +2 -1
- pymammotion/data/mqtt/event.py +18 -14
- pymammotion/data/mqtt/status.py +1 -1
- pymammotion/data/state_manager.py +23 -11
- pymammotion/mammotion/devices/mammotion_cloud.py +15 -7
- pymammotion/mqtt/linkkit/__init__.py +1 -1
- pymammotion/mqtt/linkkit/h2client.py +171 -135
- pymammotion/mqtt/linkkit/linkkit.py +448 -451
- pymammotion/mqtt/mammotion_mqtt.py +11 -7
- pymammotion/utility/device_config.py +657 -25
- pymammotion/utility/device_type.py +13 -1
- {pymammotion-0.4.0a5.dist-info → pymammotion-0.4.0a7.dist-info}/METADATA +3 -1
- {pymammotion-0.4.0a5.dist-info → pymammotion-0.4.0a7.dist-info}/RECORD +17 -17
- {pymammotion-0.4.0a5.dist-info → pymammotion-0.4.0a7.dist-info}/LICENSE +0 -0
- {pymammotion-0.4.0a5.dist-info → pymammotion-0.4.0a7.dist-info}/WHEEL +0 -0
@@ -16,16 +16,19 @@
|
|
16
16
|
#
|
17
17
|
#
|
18
18
|
|
19
|
-
import
|
20
|
-
import
|
19
|
+
import concurrent.futures
|
20
|
+
import hashlib
|
21
21
|
import hmac
|
22
|
-
import ssl
|
23
22
|
import logging
|
24
23
|
import os
|
24
|
+
import ssl
|
25
25
|
import threading
|
26
|
+
import time
|
27
|
+
|
26
28
|
import crcmod
|
27
|
-
import
|
28
|
-
import
|
29
|
+
import hyper
|
30
|
+
from types import TracebackType
|
31
|
+
from typing import Optional, Type
|
29
32
|
|
30
33
|
|
31
34
|
def _assert_value(condition, error_msg):
|
@@ -38,26 +41,26 @@ _H2_OPT_PORT_DEFAULT = 443
|
|
38
41
|
_H2_MAX_FILE_SIZE = 1024 * 1024 * 1024
|
39
42
|
|
40
43
|
|
41
|
-
def h2_set_option(opt, value):
|
42
|
-
if
|
44
|
+
def h2_set_option(opt, value) -> None:
|
45
|
+
if opt == "heart_beat_interval":
|
43
46
|
global _H2_OPT_HEART_BEAT_TIME_DEFAULT
|
44
47
|
_H2_OPT_HEART_BEAT_TIME_DEFAULT = value
|
45
|
-
elif
|
48
|
+
elif opt == "port":
|
46
49
|
global _H2_OPT_PORT_DEFAULT
|
47
50
|
_H2_OPT_PORT_DEFAULT = value
|
48
|
-
elif
|
51
|
+
elif opt == "max_file_size":
|
49
52
|
global _H2_MAX_FILE_SIZE
|
50
53
|
_H2_MAX_FILE_SIZE = value
|
51
54
|
|
52
55
|
|
53
|
-
class StreamHandler
|
54
|
-
def __init__(self):
|
56
|
+
class StreamHandler:
|
57
|
+
def __init__(self) -> None:
|
55
58
|
pass
|
56
59
|
|
57
|
-
def __enter__(self):
|
60
|
+
def __enter__(self) -> None:
|
58
61
|
pass
|
59
62
|
|
60
|
-
def __exit__(self, type, value, trace):
|
63
|
+
def __exit__(self, type: Optional[Type[BaseException]], value: Optional[BaseException], trace: Optional[TracebackType]) -> None:
|
61
64
|
pass
|
62
65
|
|
63
66
|
def get_content_length(self):
|
@@ -66,14 +69,14 @@ class StreamHandler():
|
|
66
69
|
def next(self):
|
67
70
|
return None
|
68
71
|
|
69
|
-
def has_next(self):
|
72
|
+
def has_next(self) -> bool:
|
70
73
|
return False
|
71
74
|
|
72
75
|
|
73
76
|
class FileStreamHandler(StreamHandler):
|
74
|
-
def __init__(self, filename, block_size=512 * 1024, opt_crc64=False):
|
77
|
+
def __init__(self, filename, block_size=512 * 1024, opt_crc64=False) -> None:
|
75
78
|
self.__filename = filename
|
76
|
-
self.__block_size = block_size
|
79
|
+
self.__block_size = block_size
|
77
80
|
self.__size = os.stat(filename).st_size
|
78
81
|
self.__opt_crc64 = opt_crc64
|
79
82
|
self.__last_crc = 0
|
@@ -82,12 +85,12 @@ class FileStreamHandler(StreamHandler):
|
|
82
85
|
def get_content_length(self):
|
83
86
|
return self.__size
|
84
87
|
|
85
|
-
def __enter__(self):
|
86
|
-
logging.debug(
|
87
|
-
self.__f = open(self.__filename,
|
88
|
+
def __enter__(self) -> None:
|
89
|
+
logging.debug("open the file, filename:%s" % self.__filename)
|
90
|
+
self.__f = open(self.__filename, "rb")
|
88
91
|
self.__read_size = 0
|
89
92
|
|
90
|
-
def __exit__(self, type, value, trace):
|
93
|
+
def __exit__(self, type: Optional[Type[BaseException]], value: Optional[BaseException], trace: Optional[TracebackType]) -> None:
|
91
94
|
if self.__f:
|
92
95
|
self.__f.close()
|
93
96
|
self.__f = None
|
@@ -99,8 +102,9 @@ class FileStreamHandler(StreamHandler):
|
|
99
102
|
if data:
|
100
103
|
self.__read_size += len(data)
|
101
104
|
if self.__opt_crc64:
|
102
|
-
do_crc64 = crcmod.mkCrcFun(
|
103
|
-
|
105
|
+
do_crc64 = crcmod.mkCrcFun(
|
106
|
+
0x142F0E1EBA9EA3693, initCrc=self.__last_crc, xorOut=0xFFFFFFFFFFFFFFFF, rev=True
|
107
|
+
)
|
104
108
|
self.__last_crc = do_crc64(data)
|
105
109
|
return data
|
106
110
|
|
@@ -115,7 +119,7 @@ class FileStreamHandler(StreamHandler):
|
|
115
119
|
|
116
120
|
|
117
121
|
class H2Exception(Exception):
|
118
|
-
def __init__(self, code, msg):
|
122
|
+
def __init__(self, code, msg) -> None:
|
119
123
|
Exception.__init__(self, msg)
|
120
124
|
self.__code = code
|
121
125
|
self.__msg = msg
|
@@ -126,13 +130,12 @@ class H2Exception(Exception):
|
|
126
130
|
def get_msg(self):
|
127
131
|
return self.__msg
|
128
132
|
|
129
|
-
def __name__(self):
|
130
|
-
return
|
133
|
+
def __name__(self) -> str:
|
134
|
+
return "H2Exception"
|
131
135
|
|
132
136
|
|
133
137
|
class UploadFileInfo:
|
134
|
-
def __init__(self, local_filename, remote_filename=None,
|
135
|
-
overwrite=True):
|
138
|
+
def __init__(self, local_filename, remote_filename=None, overwrite=True) -> None:
|
136
139
|
self.local_filename = local_filename
|
137
140
|
self.opt_overwrite = overwrite
|
138
141
|
if not remote_filename:
|
@@ -140,35 +143,35 @@ class UploadFileInfo:
|
|
140
143
|
else:
|
141
144
|
self.remote_filename = remote_filename
|
142
145
|
|
143
|
-
def __name__(self):
|
144
|
-
return
|
146
|
+
def __name__(self) -> str:
|
147
|
+
return "UploadFileInfo"
|
145
148
|
|
146
149
|
|
147
150
|
class UploadFileResult:
|
148
|
-
def __init__(self, code=None, exception=None, upload_size=None, total_size=None, file_store_id=None):
|
151
|
+
def __init__(self, code=None, exception=None, upload_size=None, total_size=None, file_store_id=None) -> None:
|
149
152
|
self.upload_size = upload_size
|
150
153
|
self.total_size = total_size
|
151
154
|
self.file_store_id = file_store_id
|
152
155
|
self.code = code
|
153
156
|
self.exception = exception
|
154
157
|
|
155
|
-
def __name__(self):
|
156
|
-
return
|
158
|
+
def __name__(self) -> str:
|
159
|
+
return "UploadFileResult"
|
157
160
|
|
158
161
|
|
159
162
|
class H2FileUploadSink:
|
160
|
-
def on_file_upload_start(self, id, upload_file_info, user_data):
|
163
|
+
def on_file_upload_start(self, id, upload_file_info, user_data) -> None:
|
161
164
|
pass
|
162
165
|
|
163
|
-
def on_file_upload_end(self, id, upload_file_info, upload_file_result, user_data):
|
166
|
+
def on_file_upload_end(self, id, upload_file_info, upload_file_result, user_data) -> None:
|
164
167
|
pass
|
165
168
|
|
166
|
-
def on_file_upload_progress(self, id, upload_file_info, upload_file_result, user_data):
|
169
|
+
def on_file_upload_progress(self, id, upload_file_info, upload_file_result, user_data) -> None:
|
167
170
|
pass
|
168
171
|
|
169
172
|
|
170
173
|
class H2FileTask:
|
171
|
-
def __init__(self, id, file_info, future_result):
|
174
|
+
def __init__(self, id, file_info, future_result) -> None:
|
172
175
|
self.__file_info = file_info
|
173
176
|
self.__future_result = future_result
|
174
177
|
self.__id = id
|
@@ -182,18 +185,18 @@ class H2FileTask:
|
|
182
185
|
def result(self, timeout=None):
|
183
186
|
return self.__future_result.result(timeout)
|
184
187
|
|
185
|
-
def cancel(self):
|
188
|
+
def cancel(self) -> None:
|
186
189
|
self.__future_result.call()
|
187
190
|
|
188
191
|
def get_id(self):
|
189
192
|
return self.__id
|
190
193
|
|
191
|
-
def __name__(self):
|
192
|
-
return
|
194
|
+
def __name__(self) -> str:
|
195
|
+
return "H2FileTask"
|
193
196
|
|
194
197
|
|
195
198
|
class H2Stream:
|
196
|
-
def __init__(self, client, id):
|
199
|
+
def __init__(self, client, id) -> None:
|
197
200
|
self.__client = client
|
198
201
|
self.__conn = None
|
199
202
|
# self.__length = None
|
@@ -204,8 +207,8 @@ class H2Stream:
|
|
204
207
|
self.__x_request_id = None
|
205
208
|
self.__x_data_stream_id = None
|
206
209
|
|
207
|
-
def __name__(self):
|
208
|
-
return
|
210
|
+
def __name__(self) -> str:
|
211
|
+
return "H2Stream"
|
209
212
|
|
210
213
|
def get_id(self):
|
211
214
|
return self.__id
|
@@ -214,7 +217,7 @@ class H2Stream:
|
|
214
217
|
_assert_value(path, "path is required")
|
215
218
|
|
216
219
|
with self.__client._get_auth_lock():
|
217
|
-
url =
|
220
|
+
url = "/stream/open" + path
|
218
221
|
self.__conn = self.__client.get_connect()
|
219
222
|
|
220
223
|
# self.__length = length
|
@@ -228,12 +231,12 @@ class H2Stream:
|
|
228
231
|
if header:
|
229
232
|
conn_header.update(header)
|
230
233
|
|
231
|
-
req_id = self.__conn.request(
|
234
|
+
req_id = self.__conn.request("GET", url, None, conn_header)
|
232
235
|
response = self.__conn.get_response(req_id)
|
233
236
|
|
234
237
|
self.__check_response(response)
|
235
|
-
self.__x_request_id = response.headers[
|
236
|
-
self.__x_data_stream_id = response.headers[
|
238
|
+
self.__x_request_id = response.headers["x-request-id"][0]
|
239
|
+
self.__x_data_stream_id = response.headers["x-data-stream-id"][0]
|
237
240
|
|
238
241
|
logging.debug("x_request_id: %s" % self.__x_request_id)
|
239
242
|
logging.debug("x_data_stream_id: %s" % self.__x_data_stream_id)
|
@@ -241,11 +244,10 @@ class H2Stream:
|
|
241
244
|
return response
|
242
245
|
|
243
246
|
def close(self, header):
|
244
|
-
logging.debug(
|
245
|
-
final_header = {
|
246
|
-
'x-data-stream-id': self.__x_data_stream_id}
|
247
|
+
logging.debug("close the stream")
|
248
|
+
final_header = {"x-request-id": self.__x_request_id, "x-data-stream-id": self.__x_data_stream_id}
|
247
249
|
final_header.update(header)
|
248
|
-
req_id = self.__conn.request(
|
250
|
+
req_id = self.__conn.request("GET", "/stream/close/" + self.__path, None, final_header)
|
249
251
|
response = self.__conn.get_response(req_id)
|
250
252
|
self.__check_response(response)
|
251
253
|
return response
|
@@ -253,14 +255,14 @@ class H2Stream:
|
|
253
255
|
def send(self, headers, data_handler):
|
254
256
|
# prepare for sending
|
255
257
|
with self.__client._get_auth_lock():
|
256
|
-
url =
|
258
|
+
url = "/stream/send" + self.__path
|
257
259
|
logging.debug("request url: %s" % url)
|
258
|
-
self.__stream_id = self.__conn.putrequest(
|
259
|
-
self.__conn.putheader(
|
260
|
-
self.__conn.putheader(
|
260
|
+
self.__stream_id = self.__conn.putrequest("GET", url)
|
261
|
+
self.__conn.putheader("x-request-id", self.__x_request_id, stream_id=self.__stream_id)
|
262
|
+
self.__conn.putheader("x-data-stream-id", self.__x_data_stream_id, stream_id=self.__stream_id)
|
261
263
|
content_length = data_handler.get_content_length()
|
262
264
|
if content_length:
|
263
|
-
self.__conn.putheader(
|
265
|
+
self.__conn.putheader("content-length", "%s" % (content_length), self.__stream_id)
|
264
266
|
for k, v in headers.items():
|
265
267
|
self.__conn.putheader(k, v, self.__stream_id)
|
266
268
|
self.__conn.endheaders(stream_id=self.__stream_id)
|
@@ -280,20 +282,22 @@ class H2Stream:
|
|
280
282
|
return response
|
281
283
|
|
282
284
|
def __check_response(self, response, msg=None):
|
283
|
-
if
|
284
|
-
raise H2Exception(response.status,
|
285
|
-
msg if msg else 'fail to request http/2, code:%d' % (response.status))
|
285
|
+
if response.status != 200:
|
286
|
+
raise H2Exception(response.status, msg if msg else "fail to request http/2, code:%d" % (response.status))
|
286
287
|
|
287
|
-
def __str__(self):
|
288
|
-
return
|
289
|
-
|
290
|
-
|
291
|
-
|
288
|
+
def __str__(self) -> str:
|
289
|
+
return "H2Stream(id=%s,stream_x_id=%s,x_request_id=%s,x_data_stream_id:%s" % (
|
290
|
+
self.__id,
|
291
|
+
self.__stream_id,
|
292
|
+
self.__x_request_id,
|
293
|
+
self.__x_data_stream_id,
|
294
|
+
)
|
292
295
|
|
293
296
|
|
294
297
|
class H2Client:
|
295
|
-
def __init__(
|
296
|
-
|
298
|
+
def __init__(
|
299
|
+
self, region, product_key, device_name, device_secret, client_id=None, opt_max_thread_num=4, endpoint=None
|
300
|
+
) -> None:
|
297
301
|
_assert_value(region, "region is not empty")
|
298
302
|
_assert_value(product_key, "product_key is not empty")
|
299
303
|
_assert_value(device_name, "device_name is not empty")
|
@@ -334,7 +338,7 @@ class H2Client:
|
|
334
338
|
def open(self):
|
335
339
|
with self.__conn_lock:
|
336
340
|
if self.__conn:
|
337
|
-
logging.info(
|
341
|
+
logging.info("the client is opened")
|
338
342
|
return -1
|
339
343
|
return self.__connect()
|
340
344
|
|
@@ -343,22 +347,30 @@ class H2Client:
|
|
343
347
|
return self.__close_connect()
|
344
348
|
self.__close_all_streams()
|
345
349
|
|
346
|
-
def upload_file_async(
|
347
|
-
|
348
|
-
|
350
|
+
def upload_file_async(
|
351
|
+
self, local_filename, remote_filename=None, over_write=True, upload_file_sink=None, upload_sink_user_data=None
|
352
|
+
):
|
353
|
+
_assert_value(local_filename, "local_filename is required")
|
349
354
|
self.__check_file(local_filename)
|
350
355
|
|
351
356
|
file_info = UploadFileInfo(local_filename, remote_filename, over_write)
|
352
357
|
|
353
|
-
future_result = self.__thread_executor.submit(
|
354
|
-
|
358
|
+
future_result = self.__thread_executor.submit(
|
359
|
+
self.__post_file_task, file_info, upload_file_sink, upload_sink_user_data
|
360
|
+
)
|
355
361
|
return H2FileTask(id, file_info, future_result)
|
356
362
|
|
357
|
-
def upload_file_sync(
|
358
|
-
|
363
|
+
def upload_file_sync(
|
364
|
+
self,
|
365
|
+
local_filename,
|
366
|
+
remote_filename=None,
|
367
|
+
over_write=True,
|
368
|
+
timeout=None,
|
369
|
+
upload_file_sink=None,
|
370
|
+
upload_sink_user_data=None,
|
371
|
+
):
|
359
372
|
self.__check_file(local_filename)
|
360
|
-
f = self.upload_file_async(local_filename, remote_filename, over_write,
|
361
|
-
upload_file_sink, upload_sink_user_data)
|
373
|
+
f = self.upload_file_async(local_filename, remote_filename, over_write, upload_file_sink, upload_sink_user_data)
|
362
374
|
return f.result(timeout)
|
363
375
|
|
364
376
|
def __create_stream_id(self):
|
@@ -378,12 +390,12 @@ class H2Client:
|
|
378
390
|
return self.__to_unsign(value1) == self.__to_unsign(value2)
|
379
391
|
|
380
392
|
def __to_unsign(self, value):
|
381
|
-
return value if value > 0 else (
|
393
|
+
return value if value > 0 else (0xFFFFFFFFFFFFFFFF + 1 + value)
|
382
394
|
|
383
395
|
def __check_file(self, path):
|
384
396
|
stat_info = os.stat(path)
|
385
|
-
if
|
386
|
-
raise ValueError(
|
397
|
+
if stat_info.st_size >= _H2_MAX_FILE_SIZE:
|
398
|
+
raise ValueError("maximum file size exceeded")
|
387
399
|
|
388
400
|
def __post_file_task(self, file_info, sink=None, user_data=None):
|
389
401
|
local_filename = file_info.local_filename
|
@@ -398,66 +410,83 @@ class H2Client:
|
|
398
410
|
stream = self.new_stream()
|
399
411
|
self.__on_new_stream(stream)
|
400
412
|
try:
|
401
|
-
logging.info(
|
402
|
-
|
413
|
+
logging.info(
|
414
|
+
"start to post file, local_filename:%s, remote:%s, over_write:%d"
|
415
|
+
% (local_filename, remote_filename, over_write)
|
416
|
+
)
|
403
417
|
|
404
418
|
# callback
|
405
419
|
if sink:
|
406
420
|
sink.on_file_upload_start(stream.get_id(), file_info, user_data)
|
407
421
|
|
408
422
|
# open stream
|
409
|
-
header = {
|
410
|
-
response = stream.open(
|
411
|
-
x_file_upload_id = response.headers[
|
423
|
+
header = {"x-file-name": remote_filename, "x-file-overwrite": "1" if over_write else "0"}
|
424
|
+
response = stream.open("/c/iot/sys/thing/file/upload", header)
|
425
|
+
x_file_upload_id = response.headers["x-file-upload-id"][0]
|
412
426
|
|
413
427
|
# send stream
|
414
|
-
header = {
|
428
|
+
header = {"x-file-upload-id": x_file_upload_id}
|
415
429
|
fs = FileStreamHandler(local_filename, opt_crc64=True)
|
416
430
|
stream.send(header, fs)
|
417
431
|
|
418
432
|
# close stream
|
419
433
|
response = stream.close(header)
|
420
|
-
remote_crc64 = int(response.headers[
|
421
|
-
logging.info(
|
434
|
+
remote_crc64 = int(response.headers["x-file-crc64ecma"][0])
|
435
|
+
logging.info("crc64, local:%ld, remote:%ld" % (fs.get_crc64(), remote_crc64))
|
422
436
|
if not self.__crc_equal(fs.get_crc64(), remote_crc64):
|
423
|
-
raise Exception(
|
424
|
-
file_store_id = response.headers[
|
425
|
-
logging.info(
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
437
|
+
raise Exception("fail to check crc64, local:%ld, remote:%ld" % (fs.get_crc64(), remote_crc64))
|
438
|
+
file_store_id = response.headers["x-file-store-id"][0]
|
439
|
+
logging.info(
|
440
|
+
"finish uploading file, local_filename:%s, remote:%s, over_write:%d, file_store_id:%s"
|
441
|
+
% (local_filename, remote_filename, over_write, file_store_id)
|
442
|
+
)
|
443
|
+
|
444
|
+
return UploadFileResult(code, exception, fs.get_read_size(), fs.get_content_length, file_store_id)
|
430
445
|
except H2Exception as e:
|
431
446
|
logging.error(
|
432
447
|
"fail to upload the file, local_filename:%s, remote:%s, over_write:%d, x_file_upload_id:%s, stream:%s, code:%s, error:%s"
|
433
|
-
% (local_filename, remote_filename, over_write, x_file_upload_id, stream, e.get_code(), e)
|
434
|
-
|
435
|
-
|
436
|
-
|
448
|
+
% (local_filename, remote_filename, over_write, x_file_upload_id, stream, e.get_code(), e)
|
449
|
+
)
|
450
|
+
return UploadFileResult(
|
451
|
+
e.get_code(),
|
452
|
+
exception,
|
453
|
+
(fs.get_read_size() if fs else -1),
|
454
|
+
(fs.get_content_length() if fs else -1),
|
455
|
+
file_store_id,
|
456
|
+
)
|
437
457
|
except Exception as e:
|
438
458
|
logging.error(
|
439
459
|
"fail to upload the file, local_filename:%s, remote:%s, over_write:%d, x_file_upload_id:%s, stream:%s, error:%s"
|
440
|
-
% (local_filename, remote_filename, over_write, x_file_upload_id, stream, e)
|
441
|
-
|
442
|
-
|
443
|
-
|
460
|
+
% (local_filename, remote_filename, over_write, x_file_upload_id, stream, e)
|
461
|
+
)
|
462
|
+
return UploadFileResult(
|
463
|
+
-1,
|
464
|
+
exception,
|
465
|
+
(fs.get_read_size() if fs else -1),
|
466
|
+
(fs.get_content_length() if fs else -1),
|
467
|
+
file_store_id,
|
468
|
+
)
|
444
469
|
# raise e
|
445
470
|
finally:
|
446
471
|
self.__on_free_stream(stream)
|
447
472
|
if sink:
|
448
|
-
result = UploadFileResult(
|
449
|
-
|
450
|
-
|
473
|
+
result = UploadFileResult(
|
474
|
+
code,
|
475
|
+
exception,
|
476
|
+
(fs.get_read_size() if fs else -1),
|
477
|
+
(fs.get_content_length() if fs else -1),
|
478
|
+
file_store_id,
|
479
|
+
)
|
451
480
|
sink.on_file_upload_end(stream.get_id(), file_info, result, user_data)
|
452
481
|
|
453
|
-
def __connect(self):
|
482
|
+
def __connect(self) -> int:
|
454
483
|
with self.__conn_lock:
|
455
484
|
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS)
|
456
485
|
h2_endpoint = self.__generate_endpoint()
|
457
|
-
logging.debug(
|
458
|
-
self.__conn = hyper.HTTP20Connection(
|
459
|
-
|
460
|
-
|
486
|
+
logging.debug("http/2 endpoint:%s" % (h2_endpoint))
|
487
|
+
self.__conn = hyper.HTTP20Connection(
|
488
|
+
h2_endpoint, port=self.__port, force_proto=hyper.tls.NPN_PROTOCOL, ssl_context=ctx
|
489
|
+
)
|
461
490
|
return 0
|
462
491
|
|
463
492
|
def get_connect(self):
|
@@ -469,22 +498,30 @@ class H2Client:
|
|
469
498
|
def __fill_auth_header(self, header):
|
470
499
|
client_id = self.__client_id or self.__device_name
|
471
500
|
timestamp = str(int(time.time() * 1000))
|
472
|
-
sign_content =
|
473
|
-
|
501
|
+
sign_content = (
|
502
|
+
"clientId"
|
503
|
+
+ client_id
|
504
|
+
+ "deviceName"
|
505
|
+
+ self.__device_name
|
506
|
+
+ "productKey"
|
507
|
+
+ self.__product_key
|
508
|
+
+ "timestamp"
|
509
|
+
+ timestamp
|
510
|
+
)
|
474
511
|
sign = hmac.new(self.__device_secret.encode("utf-8"), sign_content.encode("utf-8"), hashlib.sha256).hexdigest()
|
475
|
-
header[
|
476
|
-
header[
|
477
|
-
header[
|
478
|
-
header[
|
479
|
-
header[
|
480
|
-
header[
|
481
|
-
header[
|
512
|
+
header["x-auth-param-timestamp"] = timestamp
|
513
|
+
header["x-auth-param-signmethod"] = "hmacsha256"
|
514
|
+
header["x-auth-param-sign"] = sign
|
515
|
+
header["x-auth-param-product-key"] = self.__product_key
|
516
|
+
header["x-auth-param-device-name"] = self.__device_name
|
517
|
+
header["x-auth-param-client-id"] = client_id
|
518
|
+
header["x-auth-name"] = "devicename"
|
482
519
|
return header
|
483
520
|
|
484
521
|
def __fill_sdk_header(self, header):
|
485
|
-
header[
|
486
|
-
header[
|
487
|
-
header[
|
522
|
+
header["x-sdk-version"] = "1.2.0"
|
523
|
+
header["x-sdk-version-name"] = "1.2.0"
|
524
|
+
header["x-sdk-platform"] = "python"
|
488
525
|
return header
|
489
526
|
|
490
527
|
def get_default_header(self):
|
@@ -493,54 +530,53 @@ class H2Client:
|
|
493
530
|
self.__fill_sdk_header(header)
|
494
531
|
return header
|
495
532
|
|
496
|
-
def __close_connect(self):
|
533
|
+
def __close_connect(self) -> int:
|
497
534
|
with self.__conn_lock:
|
498
535
|
if self.__conn:
|
499
536
|
self.__conn.close(0)
|
500
537
|
return 0
|
501
538
|
|
502
|
-
def __close_all_streams(self):
|
539
|
+
def __close_all_streams(self) -> None:
|
503
540
|
with self.__stream_list_lock:
|
504
541
|
self.__stream_list.clear()
|
505
542
|
self.__stream_list = None
|
506
543
|
self.__stop_heart_beat()
|
507
544
|
|
508
|
-
def __on_new_stream(self, stream):
|
545
|
+
def __on_new_stream(self, stream) -> None:
|
509
546
|
with self.__stream_list_lock:
|
510
547
|
self.__stream_list.append(stream)
|
511
548
|
|
512
549
|
if len(self.__stream_list) == 1:
|
513
550
|
self.__start_heart_beat()
|
514
551
|
|
515
|
-
def __on_free_stream(self, stream):
|
552
|
+
def __on_free_stream(self, stream) -> None:
|
516
553
|
with self.__stream_list_lock:
|
517
554
|
self.__stream_list.remove(stream)
|
518
555
|
|
519
556
|
if len(self.__stream_list) == 0:
|
520
557
|
self.__stop_heart_beat()
|
521
558
|
|
522
|
-
def __start_heart_beat(self):
|
523
|
-
logging.debug(
|
559
|
+
def __start_heart_beat(self) -> None:
|
560
|
+
logging.debug("start heart_beat")
|
524
561
|
self.__schedule_heart_beat()
|
525
562
|
|
526
|
-
def __handle_heart_beat(self):
|
527
|
-
logging.debug(
|
528
|
-
self.__conn.ping(b
|
563
|
+
def __handle_heart_beat(self) -> None:
|
564
|
+
logging.debug("heart...")
|
565
|
+
self.__conn.ping(b"PINGPONG")
|
529
566
|
self.__schedule_heart_beat()
|
530
567
|
|
531
|
-
def __stop_heart_beat(self):
|
532
|
-
logging.debug(
|
568
|
+
def __stop_heart_beat(self) -> None:
|
569
|
+
logging.debug("stop heart")
|
533
570
|
self.__cancel_heart_beat()
|
534
571
|
|
535
|
-
def __schedule_heart_beat(self):
|
572
|
+
def __schedule_heart_beat(self) -> None:
|
536
573
|
with self.__heart_beat_lock:
|
537
574
|
if self.__opt_heart_beat_time and self.__opt_heart_beat_time > 0:
|
538
575
|
self.__timer = threading.Timer(self.__opt_heart_beat_time, self.__handle_heart_beat)
|
539
576
|
self.__timer.start()
|
540
577
|
|
541
|
-
def __cancel_heart_beat(self):
|
578
|
+
def __cancel_heart_beat(self) -> None:
|
542
579
|
with self.__heart_beat_lock:
|
543
580
|
if self.__timer:
|
544
581
|
self.__timer.cancel()
|
545
582
|
self.__timer = None
|
546
|
-
|