Skip to content

Commit 2db5fde

Browse files
authored
Merge pull request #21 from Vovaman/f-18-make-real-tls
F 18 make real tls
2 parents 2a31035 + 5ce3d9b commit 2db5fde

File tree

10 files changed

+1424
-385
lines changed

10 files changed

+1424
-385
lines changed

HISTORY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
0.3.0
2+
-----
3+
Full support for TLS.
4+
5+
The installation method has also been changed.
6+
17
0.2.0
28
-----
39
Fix for big data packet.

Pipfile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,17 @@ verify_ssl = true
44
name = "pypi"
55

66
[packages]
7-
twine = "*"
7+
pyelftools = "*"
8+
micropy-cli = "*"
9+
esptool = "*"
10+
mpremote = "*"
811

912
[dev-packages]
13+
setuptools = ">=68.0.0"
14+
wheel = "*"
15+
build = "*"
16+
twine = ">=6.1.0"
17+
packaging = "==25.0"
1018

1119
[requires]
12-
python_version = "3.9"
20+
python_version = "3.10"

Pipfile.lock

Lines changed: 1348 additions & 177 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
1+
> This module is only for [micropython](https://micropython.org/)!
2+
13
# micropython-async_websocket_client
24
This module is designed for ESP32 (and other) controllers.
3-
Goal: create and keep alive connection channel with websocket server.
5+
6+
Target: create and keep alive connection channel with websocket server.
7+
48
You may send captured data from controlled devices through this channel to server and accept managing signals on your controller.
9+
510
This data channel works as background task while main control cycle is running too.
611
The break of websocket channel doesn't corrupt main cycle of control.
712

13+
Module supports TLS with both client and server certificates.
14+
815
This project based on:
16+
917
https://github.com/danni/uwebsockets
18+
1019
https://github.com/peterhinch/micropython-async
1120

1221
**My gratitudes to authors**.
1322

1423
# requirements
1524
This module is designed and tested on [ESP32S-WROOM-32](https://ru.wikipedia.org/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:ESP32_Espressif_ESP-WROOM-32_Dev_Board.jpg).
16-
Development and tests were done based on [esp32-20220618-v1.19.1.bin](https://micropython.org/resources/firmware/esp32-20220618-v1.19.1.bin).
25+
26+
Development and tests were done based on [ESP32-20250415-v1.25.0.bin](https://micropython.org/resources/firmware/ESP32_GENERIC-20250415-v1.25.0.bin).
1727

1828
# installation
1929
<details>
@@ -30,10 +40,10 @@ Development and tests were done based on [esp32-20220618-v1.19.1.bin](https://mi
3040
>>> wifi = network.WLAN(network.STA_IF)
3141
>>> wifi.active(1)
3242
>>> wifi.connect(<name_of_your_wifi_net>, <wifi_password>)
33-
>>> import upip
34-
>>> upip.install('micropython-async-websocket-client')
43+
>>> import mip
44+
>>> mip.install("github:Vovaman/micropython_async_websocket_client/async_websocket_client/ws.py")
3545
```
3646

37-
All needed dependencies are in esp32-20220618-v1.19.1.bin.
47+
All needed dependencies are in firmware.
3848
# example
39-
Sample using of this module is in https://github.com/Vovaman/example_async_websocket.
49+
An example of how to use this module can be found in the https://github.com/Vovaman/example_async_websocket.

async_websocket_client/ws.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import usocket as socket
2-
import uasyncio as a
3-
import ubinascii as binascii
4-
import urandom as random
5-
from ucollections import namedtuple
6-
import ure as re
7-
import ustruct as struct
8-
import ussl
1+
import socket
2+
import asyncio as a
3+
import binascii as b
4+
import random as r
5+
from collections import namedtuple
6+
import re
7+
import struct
8+
import ssl
99

1010
# Opcodes
1111
OP_CONT = const(0x0)
@@ -76,7 +76,7 @@ async def a_read(self, size: int = None):
7676
if size == 0:
7777
return b''
7878
chunks = []
79-
79+
8080
while True:
8181
b = self.sock.read(size)
8282
await a.sleep_ms(self.delay_read)
@@ -97,25 +97,34 @@ async def a_read(self, size: int = None):
9797
# Join all the chunks and return them
9898
return b''.join(chunks)
9999

100-
async def handshake(self, uri, headers=[]):
100+
async def handshake(self, uri, headers=[], keyfile=None, certfile=None, cafile=None):
101101
if self.sock:
102102
self.close()
103103

104104
self.sock = socket.socket()
105105
self.uri = self.urlparse(uri)
106106
ai = socket.getaddrinfo(self.uri.hostname, self.uri.port)
107107
addr = ai[0][4]
108+
108109
self.sock.connect(addr)
109110
self.sock.setblocking(False)
111+
110112
if self.uri.protocol == 'wss':
111-
self.sock = ussl.wrap_socket(self.sock, server_hostname=self.uri.hostname)
112-
# await self.open(False)
113+
with open(cafile, 'rb') as f:
114+
cadata = f.read()
115+
self.sock = ssl.wrap_socket(
116+
self.sock, server_side=False,
117+
key=keyfile, cert=certfile,
118+
cert_reqs=2, #ssl.CERT_REQUIED,
119+
cadata=cadata,
120+
server_hostname=self.uri.hostname
121+
)
113122

114123
def send_header(header, *args):
115124
self.sock.write(header % args + '\r\n')
116125

117126
# Sec-WebSocket-Key is 16 bytes of random base64 encoded
118-
key = binascii.b2a_base64(bytes(random.getrandbits(8)
127+
key = b.b2a_base64(bytes(r.getrandbits(8)
119128
for _ in range(16)))[:-1]
120129

121130
send_header(b'GET %s HTTP/1.1', self.uri.path or '/')
@@ -211,7 +220,7 @@ def write_frame(self, opcode, data=b''):
211220
raise ValueError()
212221

213222
if mask: # Mask is 4 bytes
214-
mask_bits = struct.pack('!I', random.getrandbits(32))
223+
mask_bits = struct.pack('!I', r.getrandbits(32))
215224
self.sock.write(mask_bits)
216225
data = bytes(b ^ mask_bits[i % 4]
217226
for i, b in enumerate(data))

how_to_make_package.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# build package
22
```bash
33
$ pipenv shell
4-
$ python setup.py sdist
4+
$ python -m build
55
```
66
# ...and upload to PyPi
77
```bash
8-
$ rm dist/*.orig
9-
$ python -m twine upload dist/*
8+
$ twine upload dist/*
109
```

pyproject.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "micropython-async_websocket_client"
7+
version = "0.3.0"
8+
authors = [
9+
{name = "Vladimir Badashkin", email = "bd_postbox1@mail.ru"},
10+
]
11+
description = "Asynchronous websocket client for ESP32 controller."
12+
readme = "README.md"
13+
license = {file = "LICENSE"}
14+
requires-python = ">=3.10"
15+
classifiers = [
16+
"Programming Language :: Python :: 3",
17+
"License :: OSI Approved :: Apache Software License",
18+
"Operating System :: OS Independent",
19+
]

sdist_upip/__init__.py

Whitespace-only changes.

sdist_upip/sdist_upip.py

Lines changed: 0 additions & 145 deletions
This file was deleted.

setup.py

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)