Skip to content

Commit

Permalink
Merge pull request #34 from kb1lqc/develop
Browse files Browse the repository at this point in the history
Merge `kb1lqc/develop` into `FaradayRF/master`
  • Loading branch information
kb1lqc committed Feb 1, 2018
2 parents 8246af0 + c649c5e commit fa69121
Show file tree
Hide file tree
Showing 9 changed files with 385 additions and 39 deletions.
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[run]
source=faradayio
23 changes: 13 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
sudo: required
dist: trusty
language: python
python:
- "3.5"

# Install dependencies
- '3.5'
install:
- pip install -r requirements.txt
- git clone https://github.com/rhjdjong/SlipLib.git
- pip install SlipLib

# Run tests
- "~/virtualenv/python3.5/bin/pip3 install -r requirements.txt"
script:
- "flake8 --exclude .venv/,docs/,SlipLib/ ."
- pytest tests/
- "~/virtualenv/python3.5/bin/flake8 --exclude docs/ ."
- sudo ~/virtualenv/python3.5/bin/pytest tests/
- sudo ~/virtualenv/python3.5/bin/python3 -m coverage run ~/virtualenv/python3.5/bin/pytest
- coveralls
deploy:
provider: pypi
user: "KB1LQC"
password:
secure: EqQ5i1mVqBVOFa/hI7GbEE5MxJuFzV27d90qHfxNxa5lwYqu05mN5uTh3QHdUK75LehJqxvJvb0MNgj3tX5n9Dyef/tbho/YZvKPqdgLiHhIS7zQyqZQ0b3zB0gqG2gxfEZv68qD+EtMYR8UGh2CLEQGQBsG5Qap2VsWMmusS4M52kU321p3nkr8D+PBln9ggG1kEa0y+eQchCr3JbnY4dLb8G0H24yEpt9KSfbulcNFfJW2DP4RQ83zQKU1eU2/gpr6V71WP8YLv9uR8NC1p/iv6WlA1AJUSaHI6KvLZej/0GNz8MxPmqbvTR+6gkAzRoA/rz5ZIe9wgUywCEvMwXERdYT22KB1KhDtwovh+5rj4/DupGYcDb/zxlcuMy6LpDB0/QrWuL2uVudqaEnUpawqUNNCsubifmpkvP+A/iCRez6iMEcdt6nlQZMDlUQgFZsNcvwOVTjWiJF+/UM88StNd0wmkGxkDZWS6nkiWV31sIczFMFgbjAPyoJHS6I3yEwEC9juFjDYYfQ8KI3aKpW+zEFZOT/FjJ/nkqX6gtRQoYfib82wKx3JQezQeR/aTwG5Wx6rlV98ZAenuQyT+t+jAM2dhrzIkspZ0VJMu+I46owHYt7DjE0Y4bj2Wf8SSABUPNuZnZy8FVZpVw+fWVKbBC6C47IQcvHgIJqwdVk=
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See the [FaradayRF contributing guide](https://github.com/FaradayRF/Athena/blob/master/CONTRIBUTING.md)
32 changes: 29 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
# faradayio
Asynchronous input/output program linking a network interface and UART port for Faraday radios
# FaradayIO
[![Build Status](https://travis-ci.org/FaradayRF/faradayio.svg?branch=master)](https://travis-ci.org/FaradayRF/faradayio)
[![Coverage Status](https://coveralls.io/repos/github/FaradayRF/faradayio/badge.svg?branch=master)](https://coveralls.io/github/FaradayRF/faradayio?branch=master)

[![Build Status](https://travis-ci.org/FaradayRF/faradayio.svg?branch=master)](https://travis-ci.org/FaradayRF/faradayio)
The `faradayio` module provides a [TUN/TAP](https://en.wikipedia.org/wiki/TUN/TAP) interface which tunnels network traffic in [SLIP](https://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol) format over a serial port. This was originally designed for the [Faraday](https://faradayrf.com/faraday/) radio but the software is radio agnostic. By default this module helps create a TUN/TAP adapter on the `10.0.0.0` network and a simple command line program is also provided to automatically setup a network adapter for a Faraday radio.

## Installation
Installation is simple. If you are just installing to use with a radio then the pypi installation is all you need. However, if you are looking to develop code then you should install from a GitHub repository clone in editable mode. Please note we suggest installing with a [virtual environment](https://github.com/FaradayRF/faradayio/wiki/Working-With-Python3-Virtual-Environments) in all cases!
### PyPi
To install `faradayio` simply install with `pip3`
```
pip3 install faradayio
```
### Git Repository Editable Mode
To install `faradayio` from a git repository in editable mode simple checkout from GitHub and use `pip3` to install in editable mode.

```
$ git clone git@github.com:FaradayRF/faradayio.git
$ cd faradayio
$ pip3 install -e .
```

## Usage
_Placeholder for command line program completion. This should also have some module use examples as well but that will wait until this module is actually used to create a working program._

## Wiki
Please use our [faradayio wiki](https://github.com/FaradayRF/faradayio/wiki) to find helpful tips on installation, setting up a development environment, and running unit tests.

## FaradayRF
This project is provided by [FaradayRF](https://www.faradayrf.com) as [GPLv3](https://github.com/FaradayRF/faradayio/blob/master/LICENSE) software aimed at the amateur radio (ham radio) community. Please join us on our [Gitter lobby](https://gitter.im/FaradayRF/Lobby) if you have any questions. Send an email to [Support@faradayrf.com](Support@faradayrf.com) if you would like to contact us via email.
165 changes: 153 additions & 12 deletions faradayio/faraday.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@
"""

import sliplib
import pytun
import threading


class Faraday(object):
"""A class that enables transfer of data between computer and Faraday
This class interfaces a Faraday over a serial port. All it simply does is
properly encode/decode SLIP packets.
Attributes:
_serialPort (serial instance): Pyserial serial port instance.
"""
Expand All @@ -21,7 +26,7 @@ def __init__(self, serialPort=None):
self._serialPort = serialPort

def send(self, msg):
"""Converts data to slip format then sends over serial port
"""Encodes data to slip protocol and then sends over serial port
Uses the SlipLib module to convert the message data into SLIP format.
The message is then sent over the serial port opened with the instance
Expand All @@ -47,18 +52,17 @@ def send(self, msg):
return res

def receive(self, length):
"""Reads in data from a serial port (length bytes), decodes slip
"""Reads in data from a serial port (length bytes), decodes SLIP packets
A generator function which reads the serial port opened with the
instance of Faraday used to read() and then uses the SlipLib module to
convert the SLIP format into bytes. Each message received is added to a
receive buffer in SlipLib which is then yielded.
A function which reads from the serial port and then uses the SlipLib
module to decode the SLIP protocol packets. Each message received
is added to a receive buffer in SlipLib which is then returned.
Args:
length (int): Length to receive with serialPort.read(length)
Yields:
bytes: The next message in the receive buffer
Returns:
bytes: An iterator of the receive buffer
"""

Expand All @@ -69,8 +73,145 @@ def receive(self, length):
ret = self._serialPort.serialPort.read(length)

# Decode data from slip format, stores msgs in sliplib.Driver.messages
slipDriver.receive(ret)
temp = slipDriver.receive(ret)
return iter(temp)


class TunnelServer(object):
"""
A class which creates a TUN/TAP device for Faraday uses.
Creates a basic TUN/TAP adapter with generic values for use with Faraday.
Also provides a method to close TUN/TAP when the class is destroyed.
Attributes:
addr: IP address of TUN/TAP adapter
netmask: Netmask of TUN/TAP adapter
mtu: Maximum Transmission Unit for TUN/TAP adapter
name: Name of TUN/TAP adapter
"""
def __init__(self, addr,
netmask,
mtu,
name):
self._tun = pytun.TunTapDevice(name=name)
self._tun.addr = addr
self._tun.netmask = netmask
self._tun.mtu = mtu

# Set TUN persistance to True and bring TUN up
self._tun.persist(True)
self._tun.up()

def __del__(self):
"""
Clean up TUN when the TunnelServer class is destroyed
"""
self._tun.down()
print("TUN brought down...")


class Monitor(threading.Thread):
"""
A class which inherits from threading.Thread to provide TUN/TAP monitors
# Yield each message as a generator
for item in slipDriver.messages:
yield item
Inherits from threading.Thread and is designed to be run as a thread. This
provides functions which can be used to monitor the TUN/TAP adapter and
send/receive data when it arrives over TUN or serial.
Attributes:
serialPort: Pyserial instance for a serial port
name: Name of TUN/TAP device to be created by the monitor
addr: IP address of the TUN/TAP device to be created
mtu: Maximum Transmission Unit of TUN/TAP adapter TODO delete?
"""
def __init__(self,
serialPort,
name="Faraday",
addr='10.0.0.1',
netmask='255.255.255.0',
mtu=1500):
super().__init__()
self._isRunning = threading.Event()
self._serialPort = serialPort

# Start a TUN adapter
self._TUN = TunnelServer(name=name,
addr=addr,
netmask=netmask,
mtu=mtu)

# Create a Faraday instance
self._faraday = Faraday(serialPort=serialPort)

def checkTUN(self):
"""
Checks the TUN adapter for data and returns any that is found.
Returns:
packet: Data read from the TUN adapter
"""
packet = self._TUN._tun.read(self._TUN._tun.mtu)
return(packet)

def monitorTUN(self):
"""
Monitors the TUN adapter and sends data over serial port.
Returns:
ret: Number of bytes sent over serial port
"""
packet = self.checkTUN()

if packet:
try:
# TODO Do I need to strip off [4:] before sending?
ret = self._faraday.send(packet)
return ret

except AttributeError as error:
# AttributeError was encountered
print("AttributeError")

def rxSerial(self, length):
"""
Checks the serial port for data and returns any that is found.
Args:
length: Number of bytes to read from serial port
Returns:
data: Data received from serial port
"""
return(self._faraday.receive(length))

def txSerial(self, data):
"""
Sends data over serial port.
Args:
data: Data to be sent over serial port
Returns:
length: Number of bytes sent over serial port
"""
return self._faraday.send(data)

def checkSerial(self):
"""
Check the serial port for data to write to the TUN adapter.
"""
for item in self.rxSerial(self._TUN._tun.mtu):
self._TUN._tun.write(item)

def run(self):
"""
Wrapper function for TUN and serial port monitoring
Wraps the necessary functions to loop over until self._isRunning
threading.Event() is set(). This checks for data on the TUN/serial
interfaces and then sends data over the appropriate interface.
"""
while not self._isRunning.is_set():
self.checkTUN()
self.checkSerial()
16 changes: 8 additions & 8 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
attrs==17.3.0
configparser==3.5.0
enum34==1.1.6
attrs==17.4.0
flake8==3.5.0
funcsigs==1.0.2
mccabe==0.6.1
pluggy==0.6.0
py==1.5.2
pycodestyle==2.3.1
pyflakes==1.6.0
pytest==3.3.0
pyserial==3.4
pytest==3.3.2
python-pytun==2.2.1
scapy-python3==0.23
six==1.11.0
pyserial==3.4
pyserial-asyncio==0.4
asyncio==3.4.3
sliplib==0.3.0
sphinx-rtd-theme==0.2.4
coveralls==1.2.0
pytest-cov==2.5.1
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
name='faradayio',
packages=['faradayio'],
version='0.0.1',
description='FaradayRF Asynchronous input/output module and program',
description='FaradayRF TUN/TAP adapter',
author='FaradayRF',
author_email='Support@FaradayRF.com',
url='https://github.com/FaradayRF/faradayio',
Expand Down
10 changes: 5 additions & 5 deletions tests/serialtestclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Import modules
import asyncio
import serial
import serial_asyncio
# import serial_asyncio


class SerialTestClass(object):
Expand All @@ -17,10 +17,10 @@ def __init__(self):
serial.serial_for_url(url=self._port,
timeout=self._timeout,
baudrate=self._baudrate)
self.asyncSerialPort = \
serial_asyncio.open_serial_connection(url=self._port,
timeout=self._timeout,
baudrate=self._baudrate)
# self.asyncSerialPort = \
# serial_asyncio.open_serial_connection(url=self._port,
# timeout=self._timeout,
# baudrate=self._baudrate)

def _run(coro):
"""Run the coroutine"""
Expand Down

0 comments on commit fa69121

Please sign in to comment.