Skip to main content

Core library for Amfiprot

Project description

Amfiprot is a communication protocol for embedded devices used and developed by Amfitech. The protocol can be extended with plugins for specific devices implementing the Amfiprot protocol (e.g. the AmfiTrack).

Prerequisites

  • Python 3.6 or higher.
  • libusb in order to communicate with USB devices through pyusb

Installation

Windows

Get a libusb Windows binary from https://libusb.info/. From the downloaded archive, copy the following two files:

  • VS2015-x64\dll\libusb-1.0.dll to C:\Windows\System32
  • ``VS2015-Win32\dll\libusb-1.0.dlltoC:\Windows\SysWOW64`

Install (or update) amfiprot with pip:

pip install -U amfiprot

Linux (Ubuntu)

Install libusb:

sudo apt install libusb-1.0-0-dev

Make sure that your user has access to USB devices. For example, give the plugdev group access to USB devices by creating a udev rule:

echo 'SUBSYSTEM=="usb", MODE="660", GROUP="plugdev"' | sudo tee /etc/udev/rules.d/50-pyusb.rules
sudo udevadm control --reload
sudo udevadm trigger

Check whether you are a member of plugdev with:

groups <username>

If not, add yourself to the group with:

sudo usermod -aG plugdev <username>

Finally, install (or update) amfiprot with pip:

pip install -U amfiprot

Quick start

The basic workflow when using the library is:

  1. Create a Connection to a device connected directly to the host machine (we call this the "root node").
  2. Search for Nodes on the Connection (i.e. nodes connected through the root node)
  3. Create a Device using one of the discovered Nodes.
  4. Start the Connection.
  5. Communicate with the Device.

Example:

import amfiprot

VENDOR_ID = 0xC17
PRODUCT_ID = 0xD12

if __name__ == "__main__":
    conn = amfiprot.UsbConnection(VENDOR_ID, PRODUCT_ID)
    nodes = conn.find_nodes()

    print(f"Found {len(nodes)} node(s).")
    for node in nodes:
        print(f"[{node.tx_id}] {node.name}")

    dev = amfiprot.Device(nodes[0])
    conn.start()
    
    cfg = dev.config.read_all()

    while True:
        if dev.packet_available():
            print(dev.get_packet())

The following sections provide a more in-depth explanation.

Discovering and connecting to a root node

After attaching a device to your host machine, you can scan for connected devices (e.g. connected via USB) with:

phys_devs = amfiprot.UsbConnection.scan_physical_devices()

for dev in phys_devs:
    print(dev)

A connection can then be created using a specific physical device:

conn = amfiprot.UsbConnection(dev['vid'], dev['pid'], dev['serial_number'])

Using serial_number is optional. If none is given, the first device matching the given vendor and product ID is used.

Finding nodes

After creating a connection, we can search for nodes that are connected to the root node (e.g. via RF or UART):

nodes = conn.find_nodes()

find_nodes() returns a list of Node instances. A Node provides a low-level interface to the physical device and can be used to retrieve the uuid, tx_id and name of the device, and send/receive raw packets. It is not recommended to use the Node directly, but rather attach it to a Device instance.

Creating a device

A Device is an abstraction layer on top of a Node and is created by injecting a Node in the constructor:

dev = amfiprot.Device(node)

The Device provides a higher-level interface allowing the user to easily:

  • Update the firmware
  • Reboot the device
  • Read/write configurations
  • Read decoded packets

We are still able to access the Node through the Device if necessary:

tx_id = dev.node.tx_id

Starting the connection and interacting with the device

Before interacting with the Device, the Connection must be started:

conn.start()

This creates a child process that asynchronously sends and receives packets on the specified interface. We can now interact with the Device in the main process without worrying about blocking:

device_name = dev.name()
print(f"Reading packets from {device_name}...")

while True:
	if dev.packet_available():
		print(dev.get_packet())

We can access the device configuration through a Configurator instance which is automatically created as a member (dev.config) of the Device:

# Read the entire configuration as a JSON-like object (a list of dicts)
cfg = dev.config.read_all()

# Print all parameters
for category in cfg:
    print(f"CATEGORY: {category['name']}")
    for parameter in category['parameters']:
        print(parameter)

The configuration can be easily saved to and loaded from a .json file:

import json

# Write configuration to file
with open("config.json", "w") as outfile:
	json.dump(cfg, outfile, indent=4)

# Read configuration from file and send to device
with open("config.json", "r") as infile:
    new_cfg = json.load(infile)
    dev.config.write_all(new_cfg)

Contributions and bug reporting

The Amfiprot Python package is open-source and the source code can be found on our Github repository. Contributions can be made through pull requests to the development branch. Bug reports and feature requests can be created in the Issues tab.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

amfiprot-0.0.1a3.tar.gz (19.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

amfiprot-0.0.1a3-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file amfiprot-0.0.1a3.tar.gz.

File metadata

  • Download URL: amfiprot-0.0.1a3.tar.gz
  • Upload date:
  • Size: 19.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.1

File hashes

Hashes for amfiprot-0.0.1a3.tar.gz
Algorithm Hash digest
SHA256 8cad8a0e3c99ac24275aec0fcf0e33ec8de44a1f155c49d86e1bf4ebe26afaf3
MD5 a1ab2ec70a762a11ff9824b03b479edc
BLAKE2b-256 dc66f7101a90c3445ea95af92b0906fc3b5b979025fb81c1467f9fd162a207f4

See more details on using hashes here.

File details

Details for the file amfiprot-0.0.1a3-py3-none-any.whl.

File metadata

  • Download URL: amfiprot-0.0.1a3-py3-none-any.whl
  • Upload date:
  • Size: 20.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.1

File hashes

Hashes for amfiprot-0.0.1a3-py3-none-any.whl
Algorithm Hash digest
SHA256 fe3ac9fb3c9ecd930c01426700ea7bb8e5529e9597ac7b2200e51ccb83fbed24
MD5 4dd7fc21c14f88197c829747a618de22
BLAKE2b-256 9e13d3c9a0b8c5b8668cde91f31f23bab07a9a6c5752266f6f8a42a608c07f5c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page