Skip to content

Fix miniMQTT compatibility and native_networking examples #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jan 27, 2022
201 changes: 193 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,200 @@
# SPDX-License-Identifier: Unlicense

*.mpy
.idea
__pycache__
_build
*.pyc
.env
bundles
*.DS_Store
.eggs
dist
**/*.egg-info
.vscode/settings.json

.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Local History for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/

# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ To use Azure IoT Central, you will need to create an Azure IoT Central app, crea

from adafruit_azureiot import IoTCentralDevice

device = IoTCentralDevice(wifi, secrets["id_scope"], secrets["device_id"], secrets["key"])
device = IoTCentralDevice(wifi, secrets["id_scope"], secrets["device_id"], secrets["device_device_sas_key"])
device.connect()

Once the device is connected, you will regularly need to run a ``loop`` to poll for messages from the cloud.
Expand Down
29 changes: 16 additions & 13 deletions adafruit_azureiot/device_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@
"""

import json
import ssl
import time

import adafruit_logging as logging
from adafruit_logging import Logger
import adafruit_minimqtt.adafruit_minimqtt as minimqtt
import adafruit_minimqtt.adafruit_minimqtt as MQTT

from . import constants
from .quote import quote
from .keys import compute_derived_symmetric_key
Expand Down Expand Up @@ -46,19 +49,19 @@ def __init__(
iface,
id_scope: str,
device_id: str,
key: str,
device_sas_key: str,
logger: Logger = None,
):
"""Creates an instance of the device registration service
:param socket: The network socket
:param str id_scope: The ID scope of the device to register
:param str device_id: The device ID of the device to register
:param str key: The primary or secondary key of the device to register
:param str device_sas_key: The primary or secondary key of the device to register
:param adafruit_logging.Logger logger: The logger to use to log messages
"""
self._id_scope = id_scope
self._device_id = device_id
self._key = key
self._device_sas_key = device_sas_key
self._logger = logger if logger is not None else logging.getLogger("log")

self._mqtt = None
Expand All @@ -73,7 +76,7 @@ def __init__(
# pylint: disable=C0103
def _on_connect(self, client, userdata, _, rc) -> None:
self._logger.info(
f"- device_registration :: _on_connect :: rc = {str(rc)}, userdata = {str(userdata)}"
f"- device_registration :: _on_connect :: rc = {rc}, userdata = {userdata}"
)

self._auth_response_received = True
Expand Down Expand Up @@ -107,7 +110,7 @@ def _connect_to_mqtt(self) -> None:
self._mqtt.loop()

self._logger.info(
f" - device_registration :: connect :: on_connect must be fired. Connected ? {str(self._mqtt.is_connected())}"
f" - device_registration :: connect :: on_connect must be fired. Connected ? {self._mqtt.is_connected()}"
)

if not self._mqtt.is_connected():
Expand All @@ -129,7 +132,7 @@ def _start_registration(self) -> None:

while self._operation_id is None and retry < 10:
time.sleep(1)
retry = retry + 1
retry += 1
self._mqtt.loop()

if self._operation_id is None:
Expand All @@ -148,7 +151,7 @@ def _wait_for_operation(self) -> None:

while self._hostname is None and retry < 10:
time.sleep(1)
retry = retry + 1
retry += 1
self._mqtt.loop()

if self._hostname is None:
Expand All @@ -172,21 +175,21 @@ def register_device(self, expiry: int) -> str:
# pylint: disable=C0103
sr = self._id_scope + "%2Fregistrations%2F" + self._device_id
sig_no_encode = compute_derived_symmetric_key(
self._key, sr + "\n" + str(expiry)
self._device_sas_key, sr + "\n" + str(expiry)
)
sig_encoded = quote(sig_no_encode, "~()*!.'")
auth_string = f"SharedAccessSignature sr={sr}&sig={sig_encoded}&se={str(expiry)}&skn=registration"
auth_string = f"SharedAccessSignature sr={sr}&sig={sig_encoded}&se={expiry}&skn=registration"

minimqtt.set_socket(self._socket, self._iface)
MQTT.set_socket(self._socket, self._iface)

self._mqtt = minimqtt.MQTT(
self._mqtt = MQTT.MQTT(
broker=constants.DPS_END_POINT,
username=username,
password=auth_string,
port=8883,
keep_alive=120,
is_ssl=True,
client_id=self._device_id,
ssl_context=ssl.create_default_context(),
)

self._mqtt.enable_logger(logging, self._logger.getEffectiveLevel())
Expand Down
11 changes: 4 additions & 7 deletions adafruit_azureiot/hmac.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,12 +331,11 @@ def sha_update(sha_info: dict, buffer: Union[bytes, bytearray]) -> None:
buffer_idx += i

sha_info["local"] += i
if sha_info["local"] == SHA_BLOCKSIZE:
sha_transform(sha_info)
sha_info["local"] = 0
else:
if sha_info["local"] != SHA_BLOCKSIZE:
return

sha_transform(sha_info)
sha_info["local"] = 0
while count >= SHA_BLOCKSIZE:
# copy buffer
sha_info["data"] = list(buffer[buffer_idx : buffer_idx + SHA_BLOCKSIZE])
Expand All @@ -351,9 +350,7 @@ def sha_update(sha_info: dict, buffer: Union[bytes, bytearray]) -> None:


def getbuf(s: Union[str, bytes, bytearray]) -> Union[bytes, bytearray]:
if isinstance(s, str):
return s.encode("ascii")
return bytes(s)
return s.encode("ascii") if isinstance(s, str) else bytes(s)


def sha_final(sha_info: dict) -> bytes:
Expand Down
Loading