iotprovision package

Subpackages

Submodules

Provisioning main()

This script can do one or more (default: all) of the following steps:

  • Generate root and signer certificates, register with AWS (certs)

  • Update the kit’s debugger firmware to latest version

  • Provision a connected IoT kit (provision)

  • Program WINC AWS parameters needed by demo app

  • Program kit with a demo/application (application)

  • Optionally set up WiFi credentials in demo application

Provisioning

Provisioner class, implement API for provisioning.

class iotprovision.provisioner.Provisioner(programmer, skip_program_provision_fw=False, port=None, installdir=os.path.abspath(os.path.dirname(__file__)))

Bases: object

IOT provisioner API base class This class provides functions which the provisioning algorithm (caller) can use to perform its tasks. The base class provides only generic functionality. Where provider-specific implementation is required, a sub-class can be used.

Hierarchy:

Provisioner
|
|- ProvisionerGoogle
|- ProvisionerAzure
|- ProvisionerAws
    |
    |- ProvisionerAwsMar
    |- ProvisionerAwsJitr
Parameters:
  • programmer (object) – Programmer to use

  • skip_program_provision_fw (boolean) – Set to True to skip programming the target

  • port (str) – Serial port to use

  • installdir (str) – Path to operate in

Raises:

KitConnectionError exception if none or multiple kits found, its value will contain the list of kits.

FW_INTERFACES = {'ProvisioningV2': <class 'iotprovision.firmwareinterface.ProvisioningFirmwareInterface'>, 'WincUpgradeV1': <class 'iotprovision.firmwareinterface.WincUpgradeFirmwareInterface'>, 'WxDemoV1': <class 'iotprovision.firmwareinterface.DemoFirmwareInterface'>}
MINIMUM_DEBUGGER_VERSION = '1.15.479'
WINC_FW_VERSION_BUNDLED = '19.7.7'
check_debugger_fw()

Check the installed debugger FW version against bundled FW, print advice

check_winc_fw(advise=False)

Check if Winc firmware needs upgrading :param advise: Print warning/info messages about FW upgrade recommended :return: True if installed version is outdated

configure_kit(function, skip_programming=False)

Configure kit for provisioning function, program FW if required

Parameters:
  • function (str) – Firmware function (eg. “iotprovision”) as defined

  • skip_programming (boolean) – Skip programming FW. Use with extreme care!

connect(function, skip_programming=False)

Connect actively to the kit for provisioning function, program FW if required

Parameters:
  • function (str) – Firmware function (eg. “iotprovision”) as defined

  • skip_programming (boolean) – Skip programming FW. Use with extreme care!

static create_root_of_trust(force=False, org_name=DEFAULT_ORGANIZATION_NAME, root_common_name=DEFAULT_ROOT_COMMON_NAME, signer_common_name=DEFAULT_SIGNER_COMMON_NAME)

Create certificates.

Parameters:
  • force (boolean) – Set to True to force regeneration

  • org_name (str) – Organization name

  • root_common_name (str) – Common name of Root

  • signer_common_name (str) – Common name of Signer

debuggerupgrade(tool)

Update kit’s debugger firmware to bundled file

Parameters:

tool (str) – tool to upgrade

disconnect()
erase_target_device()

Erases the target device as clean-up step

generate_certificates(force, organization_name, root_common_name, signer_common_name)
get_debugger_versions()

Get debugger version installed on selected kit, and bundled version.

program_application(cloud_provider)

Program demo application for selected cloud provider

Parameters:

cloud_provider (str) – Cloud provider in use

reboot_debugger()

Reboot debugger to invalidate USB mass storage cache for click-me file change. This tends to upset subsequent programming operations in some circumstances, so do it last in provisioning session

setup_account(profile_name, force_setup)
setup_wifi(cloud_provider, ssid, psk='', auth='wpa-psk')

Set up WiFi credentials for demo firmware using its CLI This will only work with applications having this CLI.

Parameters:
  • cloud_provider (str) – Cloud provider in use

  • ssid (str) – Network SSID

  • psk (str) – Network passkey

  • auth (str) – Network authentication method

static store_iot_id(iot_id, iot_id_filename)

Store the identifier of a device

Identifier will be available from file if kit has previously been provisioned on this computer. This identifier is the unique identifier of a node/device in IoT. Terminology varies among cloud providers, e.g. Thing Name for AWS or Device ID for Azure.

Parameters:
  • iot_id (str) – ID

  • iot_id_filename (str) – File to store ID in

winc_upgrade(force_upgrade=False)

Upgrade the WINC1500 module using the bundled firmware

Parameters:

force_upgrade (boolean) – perform the upgrade regardless of the current version

Returns:

True if WINC software is upgraded

class iotprovision.provisioner.ProvisionerAws(programmer, skip_program_provision_fw=False, port=None, installdir=os.path.abspath(os.path.dirname(__file__)))

Bases: Provisioner

AWS Microchip sandbox account provisioning mechanism

Parameters:
  • programmer (object) – Programmer to use

  • skip_program_provision_fw (boolean) – Set to True to skip programming the target

  • port (str) – Serial port to use

  • installdir (str) – Path to operate in

Raises:

KitConnectionError exception if none or multiple kits found, its value will contain the list of kits.

do_provision(force_new_device_certificate=False, skip_program_provision_firmware=False)

Provisioning for AWS

Parameters:
  • force_new_device_certificate (boolean) – Set to True to force new certificate

  • skip_program_provision_firmware (boolean) – Set to True to skip programming

generate_certificates(force, organization_name, root_common_name, signer_common_name)
class iotprovision.provisioner.ProvisionerAwsJitr(programmer, skip_program_provision_fw=False, port=None, installdir=os.path.abspath(os.path.dirname(__file__)))

Bases: ProvisionerAws

AWS JITR provisioning mechanism

Parameters:
  • programmer (object) – Programmer to use

  • skip_program_provision_fw (boolean) – Set to True to skip programming the target

  • port (str) – Serial port to use

  • installdir (str) – Path to operate in

Raises:

KitConnectionError exception if none or multiple kits found, its value will contain the list of kits.

aws_custom_register(force, aws_profile='default', org_name=DEFAULT_ORGANIZATION_NAME, root_common_name=DEFAULT_ROOT_COMMON_NAME, signer_common_name=DEFAULT_SIGNER_COMMON_NAME)

Create certificate files and register signer with AWS. For custom provisioning only.

Parameters:
  • force (boolean) – Set to True to force regeneration

  • aws_profile (str) – AWS profile name

  • org_name (str) – Organization name

  • root_common_name (str) – Common name of Root

  • signer_common_name (str) – Common name of Signer

aws_custom_register_signeronly(aws_profile='default')

Register signer with AWS. For custom provisioning only.

Parameters:

aws_profile (str) – AWS profile name

do_provision(force_new_device_certificate=False, skip_program_provision_firmware=False)

Provisioning for AWS

Parameters:
  • force_new_device_certificate (boolean) – Set to True to force new certificate

  • skip_program_provision_firmware (boolean) – Set to True to skip programming

generate_certificates(force, organization_name, root_common_name, signer_common_name)

Create root & signer certificates, register signer with AWS. Only do this once.

Parameters:
  • force (boolean) – Set to True to force regeneration

  • org_name (str) – Organization name

  • root_common_name (str) – Common name of Root

  • signer_common_name (str) – Common name of Signer

setup_account(profile_name, force_setup)

Prepare AWS account for JITR

Parameters:
  • profile_name (str) – AWS profile name

  • force_setup (boolean) – Set to True to force account setup

class iotprovision.provisioner.ProvisionerAwsMar(programmer, skip_program_provision_fw=False, port=None, installdir=os.path.abspath(os.path.dirname(__file__)))

Bases: ProvisionerAws

AWS MAR provisioning mechanism

Parameters:
  • programmer (object) – Programmer to use

  • skip_program_provision_fw (boolean) – Set to True to skip programming the target

  • port (str) – Serial port to use

  • installdir (str) – Path to operate in

Raises:

KitConnectionError exception if none or multiple kits found, its value will contain the list of kits.

do_provision(force_new_device_certificate=False, skip_program_provision_firmware=False)

Provisioning for AWS

Parameters:
  • force_new_device_certificate (boolean) – Set to True to force new certificate

  • skip_program_provision_firmware (boolean) – Set to True to skip programming

generate_certificates(force, organization_name, root_common_name, signer_common_name)

Create root & signer certificates, register signer with AWS. Only do this once.

Parameters:
  • force (boolean) – Set to True to force regeneration

  • org_name (str) – Organization name

  • root_common_name (str) – Common name of Root

  • signer_common_name (str) – Common name of Signer

setup_account(profile_name, force_setup)

Prepare AWS account for MAR

class iotprovision.provisioner.ProvisionerAzure(programmer, skip_program_provision_fw=False, port=None, installdir=os.path.abspath(os.path.dirname(__file__)))

Bases: Provisioner

Azure provisioning mechanisms

Parameters:
  • programmer (object) – Programmer to use

  • skip_program_provision_fw (boolean) – Set to True to skip programming the target

  • port (str) – Serial port to use

  • installdir (str) – Path to operate in

Raises:

KitConnectionError exception if none or multiple kits found, its value will contain the list of kits.

do_provision(force_new_device_certificate=False, skip_program_provision_firmware=False)

Do the actual provisioning for Azure

Parameters:
  • force_new_device_certificate (boolean) – Set to True to force new certificate

  • skip_program_provision_firmware (boolean) – Set to True to skip programming

generate_certificates(force, organization_name, root_common_name, signer_common_name)

Generate certificates

Parameters:
  • force (boolean) – Set to True to force regeneration

  • org_name (str) – Organization name

  • root_common_name (str) – Common name of Root

  • signer_common_name (str) – Common name of Signer

exception iotprovision.provisioner.ProvisionerError(msg=None)

Bases: Exception

Provisioner specific exception

class iotprovision.provisioner.ProvisionerGoogle(programmer, skip_program_provision_fw=False, port=None, installdir=os.path.abspath(os.path.dirname(__file__)))

Bases: Provisioner

Google provisioning mechanism

Parameters:
  • programmer (object) – Programmer to use

  • skip_program_provision_fw (boolean) – Set to True to skip programming the target

  • port (str) – Serial port to use

  • installdir (str) – Path to operate in

Raises:

KitConnectionError exception if none or multiple kits found, its value will contain the list of kits.

do_provision(force_new_device_certificate=False, skip_program_provision_firmware=False)

Do the actual provisioning for Google

Parameters:
  • force_new_device_certificate (boolean) – Set to True to force new certificate

  • skip_program_provision_firmware (boolean) – Set to True to skip programming

iotprovision.provisioner.get_provisioner(programmer, args)

Resolves the provisioning algorithm requested by the user

Firmware interface

Collection of firmware Serial-port-based communication interface classes

The class is instantiated with kit_info from pykitcommander.kitprotocols.setup_kit() and uses the kit_info porotocol_class to actually send FW commands to the kit.

class iotprovision.firmwareinterface.ApplicationFirmwareInterface(kit_info, programmer, port=None, stopbits=1, encoding='UTF-8')

Bases: object

Base class for firmware interfaces Supports open, close, and get_comport_handle

Parameters:
  • kit_info (dict) – Kit information from pykitcommander

  • programmer (object) – Programmer to use

  • port (str, optional, defaults to the active kit) – Serial port to connect to

  • stopbits (int, optional, defaults to 1) – Number of stopbits to use

  • encoding (str, optional, defaults to UTF-8) – Text encoding to use

close()

Close serial port

get_comport_handle()

Get serial port handle

Returns:

handle to serial port in use by this protocol

get_firmware_driver()

Get firmware driver handle

Returns:

handle to firmware driver from pykitcommander

open()

Open serial port using values set during construction

class iotprovision.firmwareinterface.DemoFirmwareInterface(kit_info, programmer, port=None, stopbits=1, encoding='UTF-8')

Bases: ApplicationFirmwareInterface

Interface to demo firmware

Parameters:
  • kit_info (dict) – Kit information from pykitcommander

  • programmer (object) – Programmer to use

  • port (str, optional, defaults to the active kit) – Serial port to connect to

  • stopbits (int, optional, defaults to 1) – Number of stopbits to use

  • encoding (str, optional, defaults to UTF-8) – Text encoding to use

DEFAULT_BAUD = 9600
demo_fw_command(cmd, args=[])

Send a request to demo FW CLI, return response.

Parameters:
  • cmd (str) – Command to send

  • args (list of str) – arguments (payload)

open()

Open port, then send an initial empty command and discard the response (list of available commands). This reduces the risk of communication glitches on initial real command sent to demo FW.

read_fw_version()

Get demo FW version.

class iotprovision.firmwareinterface.ProvisioningFirmwareInterface(kit_info, programmer, port=None, stopbits=1, encoding='UTF-8')

Bases: ApplicationFirmwareInterface

Interface to provisioning firmware

Implementation of the provisioning firmware communication protocol.

Actual firmware interaction is delegated to firmware driver supplied by pykitcommander: fwdriver.firmware_command(command, [<arg-list>][, blob]) where args can be either integer, bytes, or str

Parameters:
  • kit_info (dict) – Kit information from pykitcommander

  • programmer (object) – Programmer to use

  • port (str, optional, defaults to the active kit) – Serial port to connect to

  • stopbits (int, optional, defaults to 1) – Number of stopbits to use

  • encoding (str, optional, defaults to UTF-8) – Text encoding to use

DEFAULT_BAUD = 115200
ECC_SLOT_WORD_SIZE_BYTES = 4
close()

Close serial port

ecc_lock_slot(slot_number)

Lock an ECC slot. Note: Locking ECC slots can not be undone!

Parameters:

slot_number (int) – Slot number to lock.

ecc_read_public_key()

Reads the public key

Returns:

Public key

Return type:

str

ecc_read_serialnumber()

Reads the ECC serialnumber

Returns:

ECC serialnumber

Return type:

str

ecc_read_slot(slot_number, num_bytes=None)

Read contents of a slot on the ECC

Parameters:
  • slot_number (int) – ECC slot to read from

  • num_bytes (int) – Number of bytes to read, or omit for entire slot

Returns:

contents of slot

ecc_sign_digest(digest)

Send a digest for signing by the ECC

Parameters:

digest – Digest to sign

Returns:

Signature of signed digest

ecc_write_slot(slot_number, data)

Write data to ECC slot.

Parameters:
  • num_bytes (int) – Number of bytes to write. Note slot length depends on slot number.

  • data – Data to write

enter_bridge_mode()

Enable bridge mode in target

In bridge mode target will just forward data from the host to the modem UART and forward data from the modem UART to the host Note that when in bridge mode no normal commands will work

Returns:

Empty string if OK

Return type:

str

Raises:

KitCommunicationError – If an unexpected response was received from target

exit_bridge_mode()

Disable bridge mode in target

Raises:

KitCommunicationError: If an unexpected response was received from target

get_led_status(led)

Get LED state

Parameters:

led (str) – Name of led to check

Returns:

“ON” or “OFF”

Return type:

str

open()

Open serial port using values set during construction

read_fw_version()

Reads the FW version of the provisioning FW

Returns:

Firmware version

Return type:

str

reset()

Reset target via debugger. Wait for ready prompt from FW.

set_led_status(led, state)

Turn LED on or off

Parameters:
  • led (str) – Name of led to manipulate

  • state (str) – “ON” or “OFF” (case-insensitive)

sw_reset()

Software Reset the provisioning firmware (using FW command)

synchronize()

Synchronize with firmware CLI

winc_add_client_certificate(cert)

Add a client certificate to blob

Parameters:

cert – Certificate data (DER or PEM format)

winc_erase_sector(address)

Erase a WINC sector.

Parameters:

address – Start adress of sector, must be a multiple of WINC_SECTOR_SIZE (4kB)

winc_erase_tls_certificate_sector()

Erase TLS certificate sectors in WINC FIXME: this is redundant, remove?

winc_read(address, length)

Read data from WINC flash

Parameters:
  • address (int) – Start address to read from

  • length (int) – Number of bytes to read

winc_read_fw_version()

Reads the FW version of the WINC module using provisioning FW

Returns:

Firmware and driver version as a tuple

winc_write(address, data)

Write data to WINC flash

Parameters:
  • address (int) – Start address to write to

  • data (encoded str) – raw data to write

winc_write_endpoint_name(endpoint_name)

Write endpoint name to the WINC

Parameters:

endpoint_name (str) – Endpoint name to write

winc_write_thing_name(thing_name)

Write thing name to the WINC

Parameters:

thing_name (str) – Thing name to write

winc_write_tls_certificates_sector()

Create the WINC blob and write to target.

class iotprovision.firmwareinterface.WincUpgradeFirmwareInterface(kit_info, programmer, port=None, stopbits=2, encoding='UTF-8')

Bases: ApplicationFirmwareInterface

Interface to WINC upgrade firmware

Parameters:
  • kit_info (dict) – Kit information from pykitcommander

  • programmer (object) – Programmer to use

  • port (str, optional, defaults to the active kit) – Serial port to connect to

  • stopbits (int, optional, defaults to 2) – Number of stopbits to use

  • encoding (str, optional, defaults to UTF-8) – Text encoding to use

DEFAULT_BAUD = 115200
read_fw_version()

Dummy get FW version. Needs to be present because called from protocol-independent part of Provisioner.

ECC storage

Management of provisioning storage in the ECC. Information generated by provisioning is stored in ECC slot 8 for use by application firmware.

class iotprovision.eccstorage.EccStorage(protocol, slot=8)

Bases: object

Class used to manage ECC storage

Parameters:
  • protocol (object) – Protocol object to use for communication

  • slot (int) – ECC slot number

AWS_ENDPOINT = 2
AWS_THINGNAME = 1
AZURE_DEVICE_ID = 5
AZURE_ID_SCOPE = 3
AZURE_IOT_HUB_NAME = 4
EMPTY = 0
GOOGLE_DEVICE_ID = 9
GOOGLE_PROJECT_ID = 6
GOOGLE_PROJECT_REGION = 7
GOOGLE_REGISTRY_ID = 8
NUM_TYPES = 10
add_provinfo_item(datatype, data)

Add provisioning info object to ecc blob.

Parameters:
  • type – Type of data

  • data – Data blob

build_item(datatype, data)

Create data item with 16-bit data header

Header is 16 bits represented as little-endian 2-byte array

+15-----9-8------------------- 0
|  type  |    next (offset)    |
+.-----------------------------
It is laid out as 2 bytes in little-endian fashion immediately prior to the data blob.
    +7--------------------0+
0   |     next[7:0]        |
    +7------------1+----0--+
1   |        type  |next[8]|
    +--------------+-------+
2   |        data          |
... |                      |
    +----------------------+
Parameters:
  • datatype – Data type, see DATA_TYPES above

  • data – data blob

Returns:

data item with header

create_write_provinfo(items)

Convenience function: create and write provisioning info block in one go

Parameters:

items – List of (datatype, data) tuples to write

read_provinfo()

Read existing provisioning info from ECC.

Returns:

list of (datatype, data) tuples

write_provinfo_items()

Write provisioning info to ECC slot

Kit reconfiguration

Set up IoT board configuration for selected cloud provider.

Set correct configuration registers for cloud providers so that redirect works.

To re-provision for another cloud provider the following configuration registers must be updated:

  • KEY2 must be rewritten to the new device ID (UID, ThingID, …)

  • KEY2 length must be set according to the length of the new device ID

  • CLICK_ME_TYPE must be set according to the used cloud provider

Data is stored as raw binary data in the KEY2 register

https://confluence.microchip.com/display/XP/Redirect+2.0+specification

Parameters:
  • serialnumber (str) – Kit serial number to connect to

  • cloud_provider (str) – Which cloud provider to provision for

  • key2_value (str) – Value to put in KEY2 field for redirection-metadata

Returns:

True if OK, False if error.

Return type:

boolean

Global configuration

class iotprovision.config.Config

Global configuration settings. Do not instantiate object from this.

class Certs

Bases: object

Certificate store settings and functions. Usage example:

from config import Config
root_ca_cert_filename = Config.Certs.get_path("root_ca_cert_file")
device_filename = Config.Certs.get_path("device_cert_file", serial_num)
Certs.certs_dir $home/.microchip-iot
Certs.aws_thing_file = 'aws-thing-name.txt'
Certs.azure_device_id_file = 'azure-device-id.txt'
Certs.device_cert_file = 'device.crt'
Certs.device_cert_file_sandbox = 'device_sandbox.crt'
Certs.device_csr_file = 'device.csr'
Certs.ecc_serial_file = 'ecc_serial_number.txt'
classmethod Certs.get_path(item, subdir=None)

Get pathname for file in certificate store.

Parameters:
  • item (str) – Attribute name

  • subdir (str) – Subdirectory of certs_dir, mandatory for device specific files

Returns:

Absolute pathname for specified item

Raises:

AttributeError if nonexistent attribute

Certs.root_ca_cert_file = 'root-ca.crt'
Certs.root_ca_key_file = 'root-ca.key'
Certs.root_certs_backup_file = 'root_certs_backup.bin'
Certs.signer_ca_cert_file = 'signer-ca.crt'
Certs.signer_ca_csr_file = 'signer-ca.csr'
Certs.signer_ca_key_file = 'signer-ca.key'
Certs.signer_ca_ver_cert_file = 'signer-ca-verification.crt'
Certs.signer_cert_file = 'signer.crt'
Certs.signer_cert_file_sandbox = 'signer_sandbox.crt'

Module contents

Python provisioning of IoT kits

iotprovision is a command-line utility for provisioning Microchip AVR-IoT, PIC-IoT and SAM-IoT kits for use with various cloud providers.

It is used as a CLI.

Type iotprovision –help to get help.

Overview

iotprovision is available:

Dependencies

iotprovision depends on pytrustplatform, pyawsutils and pyazureutils. iotprovision depends on pykitcommander to manage Microchip IoT kit firmware and connection. iotprovision depends on pyedbglib for its transport protocol. pyedbglib requires a USB transport library like libusb. See pyedbglib package for more information: https://pypi.org/project/pyedbglib/