diff --git a/app.py b/app.py index 7a54506..f77d4d6 100644 --- a/app.py +++ b/app.py @@ -3,10 +3,12 @@ from markupsafe import escape from flask_socketio import SocketIO, emit import serial import threading +from threading import Timer import time from collections import deque -import pandas as pd import re +import requests +from bs4 import BeautifulSoup app = Flask(__name__) socketio = SocketIO(app) @@ -18,9 +20,9 @@ port3_status = True global ser1 global ser2 global ser3 -global_dataframe = pd.DataFrame(columns=['Device Name', 'Frequency', 'Signal Strength', 'Plaintext']) frequency = lambda port: {'port1': 433, 'port2': 868,'port3': 915}.get(port, None) surveydata = {} +parsed_entries = set() def read_serial_data(port, ser, buffer): global surveydata @@ -54,7 +56,8 @@ def read_serial_data(port, ser, buffer): surveydata[key] = [] # Append the new values to the list for this frequency - surveydata[key].append([freq, rssi, decoded_value]) + current_timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + surveydata[key].append([freq, rssi, f"{decoded_value} -- Timestamp:{current_timestamp}"]) # Reset rssi and decoded_value for next packet rssi = None @@ -72,11 +75,88 @@ def read_serial_data(port, ser, buffer): time.sleep(0.1) except Exception as e: - print(f"Error: {e}") + #print("Could not access Serial Port") + #print(f"Error: {e}") pass +def parse_and_store_data(): + global surveydata + url = "http://10.130.1.1/cgi-bin/log-traffic.has" # Your target URL + headers = { + "Host": "10.130.1.1", + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language": "en-US,en;q=0.5", + "Accept-Encoding": "gzip, deflate", + "DNT": "1", + "Sec-GPC": "1", + "Authorization": "Basic cm9vdDpkcmFnaW5v", + "Connection": "keep-alive", + "Referer": "http://10.130.1.1/cgi-bin/log-lora.has", + "Upgrade-Insecure-Requests": "1" + } + response = requests.get(url, headers=headers) + + if response.status_code == 200: + soup = BeautifulSoup(response.text, 'html.parser') + table = soup.find('table') + rows = table.find_all('tr') + headers = [header.text.strip() for header in rows[0].find_all('th')][1:] + + for row in rows[1:]: + cells = row.find_all('td') + cell_data = [cell.text.strip() for cell in cells[1:] if cells.index(cell) < len(headers) + 1] + formatted_row = ' | '.join(cell_data) + + dev_id = extract_dev_id(formatted_row) # Your existing function to extract DevEui or DevAddr + freq = extract_freq(formatted_row) # Your existing function to extract frequency + + if dev_id and freq: + entry_identifier = f"{dev_id}_{formatted_row}" # Create a unique identifier for the entry + + # Only process the entry if we haven't seen this identifier before + if entry_identifier not in parsed_entries: + parsed_entries.add(entry_identifier) # Add the identifier to the set + + # Initialize dictionary for dev_id if not present + if dev_id not in surveydata: + surveydata[dev_id] = [] + + # Append new data to the list associated with the DevEui or DevAddr + surveydata[dev_id].append([freq, 0, formatted_row]) + + print("Data parsed and stored.") + else: + print(f"Request failed with status code: {response.status_code}") + + + # Schedule the next call to this function + Timer(60, parse_and_store_data).start() # Call this function every 60 seconds + + +def extract_dev_id(formatted_row): + # Assuming DevEui or DevAddr is in the 'Content' part of the formatted_row + # and it's formatted like 'Dev Addr: {DevEui}, Size: {Size}' + try: + content_part = formatted_row.split('|')[-1].strip() # Get the last part of the formatted_row, which is 'Content' + dev_id = content_part.split(',')[0].split(':')[-1].strip() # Extract the DevEui or DevAddr + return dev_id + except Exception as e: + print(f"Error extracting DevEui/DevAddr: {e}") + return None # Return None or some default value if extraction fails + + +def extract_freq(formatted_row): + # Assuming 'Freq' is a standalone field in the formatted_row + try: + freq_part = formatted_row.split('|')[3].strip() # Get the 'Freq' part (assuming it's the fifth field) + freq = float(freq_part) # Convert the frequency to float + return freq + except Exception as e: + print(f"Error extracting frequency: {e}") + return None # Return None or some default value if extraction fails def connect_serial(port,frequency): @@ -144,7 +224,7 @@ def analysis(): @app.route('/survey') def survey(): - return render_template('survey.html', data=global_dataframe) + return render_template('survey.html') @app.route('/tracking') def tracking(): @@ -255,8 +335,16 @@ def checkSer(): @app.route('/get_table_data') def get_table_data(): global surveydata - print(surveydata) - return jsonify(surveydata) + cleaned_data = {} + + for dev_id, data in surveydata.items(): + if dev_id: # Check if dev_id is not empty + cleaned_data[dev_id] = data + + #print(cleaned_data) # For debugging + return jsonify(cleaned_data) + if __name__ == '__main__': + Timer(60, parse_and_store_data).start() socketio.run(app, debug=True) diff --git a/draginoReq.py b/draginoReq.py new file mode 100644 index 0000000..4b9f5f6 --- /dev/null +++ b/draginoReq.py @@ -0,0 +1,58 @@ +import requests +from bs4 import BeautifulSoup + +# Define the URL and headers +url = "http://10.130.1.1/cgi-bin/log-traffic.has" +headers = { + "Host": "10.130.1.1", + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language": "en-US,en;q=0.5", + "Accept-Encoding": "gzip, deflate", + "DNT": "1", + "Sec-GPC": "1", + "Authorization": "Basic cm9vdDpkcmFnaW5v", + "Connection": "keep-alive", + "Referer": "http://10.130.1.1/cgi-bin/log-lora.has", + "Upgrade-Insecure-Requests": "1" +} + +# Send the GET request +response = requests.get(url, headers=headers) + +if response.status_code == 200: + # Parse the HTML content using BeautifulSoup + soup = BeautifulSoup(response.text, 'html.parser') + + # Find the table + table = soup.find('table') + + # Initialize an empty list to store formatted strings for each row + formatted_rows = [] + + # Find all table rows + rows = table.find_all('tr') + + # Get column headers from the first row + # Using .text.strip() to clean the text and [1:] to skip the empty first column + headers = [header.text.strip() for header in rows[0].find_all('th')][1:] + + # Iterate through each row (skipping the first row with the headers) + for row in rows[1:]: + # Find all data cells (td tags) in the row + cells = row.find_all('td') + + # Extract text from each cell + # Using [1:] to skip the first cell with the arrow icon + cell_data = [cell.text.strip() for cell in cells[1:] if cells.index(cell) < len(headers) + 1] + + # Format the row data into a neat line + formatted_row = ' | '.join(cell_data) + + # Append the formatted string to the list + formatted_rows.append(formatted_row) + + # Print the formatted string to display the row + print(formatted_row) +else: + print("Request failed with status code:", response.status_code) \ No newline at end of file diff --git a/examplereq b/examplereq new file mode 100644 index 0000000..eb0ad18 --- /dev/null +++ b/examplereq @@ -0,0 +1,1767 @@ + + + + + + + + LoRa Gateway + + + + + + + + + + + + + + + + + + + + + +
+ Please wait...

+
+
+ + + +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + Custom + + + + + + + + Home + + Logout + + + + + +
+ +
+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TimeMessage TypeModFreqData RateCNTContent
01/30-13:53:13Data Unconfirmed UpLoRa914.1SF10 BW12512Dev Addr: 27FD3566, Size: 20
01/30-13:51:34Data Unconfirmed UpLoRa914.9SF10 BW1257Dev Addr: 27FD3566, Size: 18
01/30-13:51:34Data Unconfirmed UpLoRa913.9SF10 BW1257Dev Addr: 27FD3566, Size: 18
+ + + + + + + + + + + diff --git a/lorawan.py b/lorawan.py new file mode 100644 index 0000000..ddc3c98 --- /dev/null +++ b/lorawan.py @@ -0,0 +1,122 @@ +##!/usr/bin/env python3 +import io +import sys +import time +import datetime +import argparse +from enum import IntEnum +import serial +from serial.threaded import LineReader, ReaderThread + +parser = argparse.ArgumentParser(description='Connect to LoRaWAN network') +parser.add_argument('port', help="Serial port of LoStik") +parser.add_argument('--joinmode', '-j', help="otaa, abp", default="otaa") + +# ABP credentials +parser.add_argument('--appskey', help="App Session Key", default="") +parser.add_argument('--nwkskey', help="Network Session Key", default="") +parser.add_argument('--devaddr', help="Device Address", default="") + +# OTAA credentials +parser.add_argument('--appeui', help="App EUI", default="") +parser.add_argument('--appkey', help="App Key", default="") +parser.add_argument('--deveui', help="Device EUI", default="") + +args = parser.parse_args() + +OTAA_RETRIES = 5 + +class MaxRetriesError(Exception): + pass + +class ConnectionState(IntEnum): + SUCCESS = 0 + CONNECTING = 100 + CONNECTED = 200 + FAILED = 500 + TO_MANY_RETRIES = 520 + + +class PrintLines(LineReader): + + retries = 0 + state = ConnectionState.CONNECTING + + def retry(self, action): + if(self.retries >= OTAA_RETRIES): + print("Too many retries, exiting") + self.state = ConnectionState.TO_MANY_RETRIES + return + self.retries = self.retries + 1 + action() + + def get_var(self, cmd): + self.send_cmd(cmd) + return self.transport.serial.readline() + + def join(self): + if args.joinmode == "abp": + self.join_abp() + else: + self.join_otaa() + + def join_otaa(self): + if len(args.appeui): + self.send_cmd('mac set appeui %s' % args.appeui) + if len(args.appkey): + self.send_cmd('mac set appkey %s' % args.appkey) + if len(args.deveui): + self.send_cmd('mac set deveui %s' % args.deveui) + self.send_cmd('mac join otaa') + + def join_abp(self): + if len(args.devaddr): + self.send_cmd('mac set devaddr %s' % args.devaddr) + if len(args.appskey): + self.send_cmd('mac set appskey %s' % args.appskey) + if len(args.nwkskey): + self.send_cmd('mac set nwkskey %s' % args.nwkskey) + self.send_cmd('mac join abp') + + def connection_made(self, transport): + """ + Fires when connection is made to serial port device + """ + print("Connection to LoStik established") + self.transport = transport + self.retry(self.join) + + def handle_line(self, data): + # if data == "ok" or data == 'busy': + # return + print("STATUS: %s" % data) + if data.strip() == "denied" or data.strip() == "no_free_ch": + print("Retrying OTAA connection") + self.retry(self.join) + elif data.strip() == "accepted": + print("UPDATING STATE to connected") + self.state = ConnectionState.CONNECTED + + def connection_lost(self, exc): + """ + Called when serial connection is severed to device + """ + if exc: + print(exc) + print("Lost connection to serial device") + + def send_cmd(self, cmd, delay=.5): + print(cmd) + self.transport.write(('%s\r\n' % cmd).encode('UTF-8')) + time.sleep(delay) + + +ser = serial.Serial(args.port, baudrate=57600) +with ReaderThread(ser, PrintLines) as protocol: + while protocol.state < ConnectionState.FAILED: + if protocol.state != ConnectionState.CONNECTED: + time.sleep(1) + continue + protocol.send_cmd("mac tx uncnf 1 %d" % int(time.time())) + time.sleep(10) + exit(protocol.state) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 04a159c..95c8027 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ +beautifulsoup4==4.12.3 Flask==2.3.2 Flask_SocketIO==5.3.6 MarkupSafe==2.1.3 -pandas==2.0.3 pyserial==3.5 +Requests==2.31.0 diff --git a/rn2903-lorawan.txt b/rn2903-lorawan.txt new file mode 100644 index 0000000..0dacd47 --- /dev/null +++ b/rn2903-lorawan.txt @@ -0,0 +1 @@ +python3 lorawan.py --joinmode otaa --appkey "814BFA6E589EE49376628B0CDD642E1F" --deveui "70B3D57ED80022D3" --appeui 0000000000000000 /dev/tty.usbserial-1140 diff --git a/sdr-companion/868-sf7-125bw-cr4_8.grc b/sdr-companion/868-sf7-125bw-cr4_8.grc new file mode 100644 index 0000000..f6cd9e3 --- /dev/null +++ b/sdr-companion/868-sf7-125bw-cr4_8.grc @@ -0,0 +1,2246 @@ + + + + Tue Apr 12 11:23:34 2016 + + options + + author + + + + window_size + + + + category + Custom + + + comment + + + + description + + + + _enabled + True + + + _coordinate + (8, 12) + + + _rotation + 0 + + + generate_options + wx_gui + + + hier_block_src_path + .: + + + id + lora_receive_realtime + + + max_nouts + 0 + + + qt_qss_theme + + + + realtime_scheduling + + + + run_command + {python} -u {filename} + + + run_options + prompt + + + run + True + + + thread_safe_setters + + + + title + + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (544, 12) + + + _rotation + 0 + + + id + bitrate + + + value + sf * (1 / (2**sf / float(bw))) + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (456, 12) + + + _rotation + 0 + + + id + bw + + + value + 125000 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (280, 13) + + + _rotation + 0 + + + id + capture_freq + + + value + 868.1e6 + + + + variable + + comment + The decimation determines the oversampling rate. +A sample rate of 1e6 and decimation of 1 equals +8 times oversampling, a decimation of 2 is 4 times +oversampling, and so on. Set higher decimation +for better performance, but worse accuracy. + + + _enabled + True + + + _coordinate + (640, 76) + + + _rotation + 0 + + + id + decimation + + + value + 1 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (384, 76) + + + _rotation + 0 + + + id + downlink + + + value + False + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (768, 12) + + + _rotation + 0 + + + id + firdes_tap + + + value + firdes.low_pass(1, samp_rate, bw, 10000, firdes.WIN_HAMMING, 6.67) + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (912, 16) + + + _rotation + 0 + + + id + offset + + + value + -26e3 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (184, 13) + + + _rotation + 0 + + + id + samp_rate + + + value + 1e6 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (384, 12) + + + _rotation + 0 + + + id + sf + + + value + 7 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (640, 12) + + + _rotation + 0 + + + id + symbols_per_sec + + + value + float(bw) / (2**sf) + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (280, 76) + + + _rotation + 0 + + + id + target_freq + + + value + 868.1e6 + + + + lora_lora_receiver + + bandwidth + bw + + + alias + + + + crc + True + + + center_freq + capture_freq + + + channel_list + [target_freq] + + + cr + 4 + + + comment + + + + conj + downlink + + + affinity + + + + decimation + decimation + + + disable_channelization + False + + + disable_drift_correction + False + + + _enabled + 1 + + + _coordinate + (392, 212) + + + _rotation + 0 + + + id + lora_lora_receiver_0 + + + implicit + False + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + reduced_rate + False + + + samp_rate + 1e6 + + + sf + sf + + + + lora_message_socket_sink + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (640, 236) + + + _rotation + 0 + + + id + lora_message_socket_sink_0 + + + ip + 127.0.0.1 + + + layer + 0 + + + port + 40868 + + + + osmosdr_source + + alias + + + + ant0 + + + + bb_gain0 + 20 + + + bw0 + 0 + + + dc_offset_mode0 + 0 + + + corr0 + 0 + + + freq0 + capture_freq + + + gain_mode0 + False + + + if_gain0 + 20 + + + iq_balance_mode0 + 0 + + + gain0 + 10 + + + ant1 + + + + bb_gain1 + 20 + + + bw1 + 0 + + + dc_offset_mode1 + 0 + + + corr1 + 0 + + + freq1 + 100e6 + + + gain_mode1 + False + + + if_gain1 + 20 + + + iq_balance_mode1 + 0 + + + gain1 + 10 + + + ant2 + + + + bb_gain2 + 20 + + + bw2 + 0 + + + dc_offset_mode2 + 0 + + + corr2 + 0 + + + freq2 + 100e6 + + + gain_mode2 + False + + + if_gain2 + 20 + + + iq_balance_mode2 + 0 + + + gain2 + 10 + + + ant3 + + + + bb_gain3 + 20 + + + bw3 + 0 + + + dc_offset_mode3 + 0 + + + corr3 + 0 + + + freq3 + 100e6 + + + gain_mode3 + False + + + if_gain3 + 20 + + + iq_balance_mode3 + 0 + + + gain3 + 10 + + + ant4 + + + + bb_gain4 + 20 + + + bw4 + 0 + + + dc_offset_mode4 + 0 + + + corr4 + 0 + + + freq4 + 100e6 + + + gain_mode4 + False + + + if_gain4 + 20 + + + iq_balance_mode4 + 0 + + + gain4 + 10 + + + comment + + + + affinity + + + + args + + + + _enabled + 1 + + + _coordinate + (24, 188) + + + _rotation + 0 + + + id + osmosdr_source_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + nchan + 1 + + + type + fc32 + + + sample_rate + samp_rate + + + + uhd_usrp_source + + alias + + + + ant0 + RX2 + + + bw0 + 0 + + + center_freq0 + capture_freq + + + dc_offs_enb0 + "" + + + iq_imbal_enb0 + "" + + + norm_gain0 + False + + + gain0 + 15 + + + lo_export0 + False + + + lo_source0 + internal + + + ant10 + + + + bw10 + 0 + + + center_freq10 + 0 + + + dc_offs_enb10 + "" + + + iq_imbal_enb10 + "" + + + norm_gain10 + False + + + gain10 + 0 + + + lo_export10 + False + + + lo_source10 + internal + + + ant11 + + + + bw11 + 0 + + + center_freq11 + 0 + + + dc_offs_enb11 + "" + + + iq_imbal_enb11 + "" + + + norm_gain11 + False + + + gain11 + 0 + + + lo_export11 + False + + + lo_source11 + internal + + + ant12 + + + + bw12 + 0 + + + center_freq12 + 0 + + + dc_offs_enb12 + "" + + + iq_imbal_enb12 + "" + + + norm_gain12 + False + + + gain12 + 0 + + + lo_export12 + False + + + lo_source12 + internal + + + ant13 + + + + bw13 + 0 + + + center_freq13 + 0 + + + dc_offs_enb13 + "" + + + iq_imbal_enb13 + "" + + + norm_gain13 + False + + + gain13 + 0 + + + lo_export13 + False + + + lo_source13 + internal + + + ant14 + + + + bw14 + 0 + + + center_freq14 + 0 + + + dc_offs_enb14 + "" + + + iq_imbal_enb14 + "" + + + norm_gain14 + False + + + gain14 + 0 + + + lo_export14 + False + + + lo_source14 + internal + + + ant15 + + + + bw15 + 0 + + + center_freq15 + 0 + + + dc_offs_enb15 + "" + + + iq_imbal_enb15 + "" + + + norm_gain15 + False + + + gain15 + 0 + + + lo_export15 + False + + + lo_source15 + internal + + + ant16 + + + + bw16 + 0 + + + center_freq16 + 0 + + + dc_offs_enb16 + "" + + + iq_imbal_enb16 + "" + + + norm_gain16 + False + + + gain16 + 0 + + + lo_export16 + False + + + lo_source16 + internal + + + ant17 + + + + bw17 + 0 + + + center_freq17 + 0 + + + dc_offs_enb17 + "" + + + iq_imbal_enb17 + "" + + + norm_gain17 + False + + + gain17 + 0 + + + lo_export17 + False + + + lo_source17 + internal + + + ant18 + + + + bw18 + 0 + + + center_freq18 + 0 + + + dc_offs_enb18 + "" + + + iq_imbal_enb18 + "" + + + norm_gain18 + False + + + gain18 + 0 + + + lo_export18 + False + + + lo_source18 + internal + + + ant19 + + + + bw19 + 0 + + + center_freq19 + 0 + + + dc_offs_enb19 + "" + + + iq_imbal_enb19 + "" + + + norm_gain19 + False + + + gain19 + 0 + + + lo_export19 + False + + + lo_source19 + internal + + + ant1 + + + + bw1 + 0 + + + center_freq1 + 0 + + + dc_offs_enb1 + "" + + + iq_imbal_enb1 + "" + + + norm_gain1 + False + + + gain1 + 0 + + + lo_export1 + False + + + lo_source1 + internal + + + ant20 + + + + bw20 + 0 + + + center_freq20 + 0 + + + dc_offs_enb20 + "" + + + iq_imbal_enb20 + "" + + + norm_gain20 + False + + + gain20 + 0 + + + lo_export20 + False + + + lo_source20 + internal + + + ant21 + + + + bw21 + 0 + + + center_freq21 + 0 + + + dc_offs_enb21 + "" + + + iq_imbal_enb21 + "" + + + norm_gain21 + False + + + gain21 + 0 + + + lo_export21 + False + + + lo_source21 + internal + + + ant22 + + + + bw22 + 0 + + + center_freq22 + 0 + + + dc_offs_enb22 + "" + + + iq_imbal_enb22 + "" + + + norm_gain22 + False + + + gain22 + 0 + + + lo_export22 + False + + + lo_source22 + internal + + + ant23 + + + + bw23 + 0 + + + center_freq23 + 0 + + + dc_offs_enb23 + "" + + + iq_imbal_enb23 + "" + + + norm_gain23 + False + + + gain23 + 0 + + + lo_export23 + False + + + lo_source23 + internal + + + ant24 + + + + bw24 + 0 + + + center_freq24 + 0 + + + dc_offs_enb24 + "" + + + iq_imbal_enb24 + "" + + + norm_gain24 + False + + + gain24 + 0 + + + lo_export24 + False + + + lo_source24 + internal + + + ant25 + + + + bw25 + 0 + + + center_freq25 + 0 + + + dc_offs_enb25 + "" + + + iq_imbal_enb25 + "" + + + norm_gain25 + False + + + gain25 + 0 + + + lo_export25 + False + + + lo_source25 + internal + + + ant26 + + + + bw26 + 0 + + + center_freq26 + 0 + + + dc_offs_enb26 + "" + + + iq_imbal_enb26 + "" + + + norm_gain26 + False + + + gain26 + 0 + + + lo_export26 + False + + + lo_source26 + internal + + + ant27 + + + + bw27 + 0 + + + center_freq27 + 0 + + + dc_offs_enb27 + "" + + + iq_imbal_enb27 + "" + + + norm_gain27 + False + + + gain27 + 0 + + + lo_export27 + False + + + lo_source27 + internal + + + ant28 + + + + bw28 + 0 + + + center_freq28 + 0 + + + dc_offs_enb28 + "" + + + iq_imbal_enb28 + "" + + + norm_gain28 + False + + + gain28 + 0 + + + lo_export28 + False + + + lo_source28 + internal + + + ant29 + + + + bw29 + 0 + + + center_freq29 + 0 + + + dc_offs_enb29 + "" + + + iq_imbal_enb29 + "" + + + norm_gain29 + False + + + gain29 + 0 + + + lo_export29 + False + + + lo_source29 + internal + + + ant2 + + + + bw2 + 0 + + + center_freq2 + 0 + + + dc_offs_enb2 + "" + + + iq_imbal_enb2 + "" + + + norm_gain2 + False + + + gain2 + 0 + + + lo_export2 + False + + + lo_source2 + internal + + + ant30 + + + + bw30 + 0 + + + center_freq30 + 0 + + + dc_offs_enb30 + "" + + + iq_imbal_enb30 + "" + + + norm_gain30 + False + + + gain30 + 0 + + + lo_export30 + False + + + lo_source30 + internal + + + ant31 + + + + bw31 + 0 + + + center_freq31 + 0 + + + dc_offs_enb31 + "" + + + iq_imbal_enb31 + "" + + + norm_gain31 + False + + + gain31 + 0 + + + lo_export31 + False + + + lo_source31 + internal + + + ant3 + + + + bw3 + 0 + + + center_freq3 + 0 + + + dc_offs_enb3 + "" + + + iq_imbal_enb3 + "" + + + norm_gain3 + False + + + gain3 + 0 + + + lo_export3 + False + + + lo_source3 + internal + + + ant4 + + + + bw4 + 0 + + + center_freq4 + 0 + + + dc_offs_enb4 + "" + + + iq_imbal_enb4 + "" + + + norm_gain4 + False + + + gain4 + 0 + + + lo_export4 + False + + + lo_source4 + internal + + + ant5 + + + + bw5 + 0 + + + center_freq5 + 0 + + + dc_offs_enb5 + "" + + + iq_imbal_enb5 + "" + + + norm_gain5 + False + + + gain5 + 0 + + + lo_export5 + False + + + lo_source5 + internal + + + ant6 + + + + bw6 + 0 + + + center_freq6 + 0 + + + dc_offs_enb6 + "" + + + iq_imbal_enb6 + "" + + + norm_gain6 + False + + + gain6 + 0 + + + lo_export6 + False + + + lo_source6 + internal + + + ant7 + + + + bw7 + 0 + + + center_freq7 + 0 + + + dc_offs_enb7 + "" + + + iq_imbal_enb7 + "" + + + norm_gain7 + False + + + gain7 + 0 + + + lo_export7 + False + + + lo_source7 + internal + + + ant8 + + + + bw8 + 0 + + + center_freq8 + 0 + + + dc_offs_enb8 + "" + + + iq_imbal_enb8 + "" + + + norm_gain8 + False + + + gain8 + 0 + + + lo_export8 + False + + + lo_source8 + internal + + + ant9 + + + + bw9 + 0 + + + center_freq9 + 0 + + + dc_offs_enb9 + "" + + + iq_imbal_enb9 + "" + + + norm_gain9 + False + + + gain9 + 0 + + + lo_export9 + False + + + lo_source9 + internal + + + clock_rate + 0.0 + + + comment + + + + affinity + + + + dev_addr + "" + + + dev_args + "" + + + _enabled + 0 + + + _coordinate + (16, 388) + + + _rotation + 0 + + + id + uhd_usrp_source_0 + + + maxoutbuf + 0 + + + clock_source0 + + + + sd_spec0 + + + + time_source0 + + + + clock_source1 + + + + sd_spec1 + + + + time_source1 + + + + clock_source2 + + + + sd_spec2 + + + + time_source2 + + + + clock_source3 + + + + sd_spec3 + + + + time_source3 + + + + clock_source4 + + + + sd_spec4 + + + + time_source4 + + + + clock_source5 + + + + sd_spec5 + + + + time_source5 + + + + clock_source6 + + + + sd_spec6 + + + + time_source6 + + + + clock_source7 + + + + sd_spec7 + + + + time_source7 + + + + minoutbuf + 0 + + + nchan + 1 + + + num_mboards + 1 + + + type + fc32 + + + samp_rate + samp_rate + + + hide_cmd_port + False + + + hide_lo_controls + True + + + stream_args + + + + stream_chans + [] + + + sync + + + + otw + + + + + wxgui_fftsink2 + + avg_alpha + 0 + + + average + False + + + baseband_freq + capture_freq + + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + fft_size + 1024 + + + freqvar + None + + + _coordinate + (392, 340) + + + _rotation + 0 + + + grid_pos + + + + id + wxgui_fftsink2_1 + + + notebook + + + + peak_hold + False + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_rate + 15 + + + samp_rate + samp_rate + + + title + FFT Plot + + + type + complex + + + win_size + + + + win + None + + + y_divs + 10 + + + y_per_div + 10 + + + + lora_lora_receiver_0 + lora_message_socket_sink_0 + frames + in + + + osmosdr_source_0 + lora_lora_receiver_0 + 0 + 0 + + + osmosdr_source_0 + wxgui_fftsink2_1 + 0 + 0 + + + uhd_usrp_source_0 + lora_lora_receiver_0 + 0 + 0 + + + uhd_usrp_source_0 + wxgui_fftsink2_1 + 0 + 0 + + diff --git a/sdr-companion/915-sf7-125bw-cr4_8.grc b/sdr-companion/915-sf7-125bw-cr4_8.grc new file mode 100644 index 0000000..1343e93 --- /dev/null +++ b/sdr-companion/915-sf7-125bw-cr4_8.grc @@ -0,0 +1,2246 @@ + + + + Tue Apr 12 11:23:34 2016 + + options + + author + + + + window_size + + + + category + Custom + + + comment + + + + description + + + + _enabled + True + + + _coordinate + (8, 12) + + + _rotation + 0 + + + generate_options + wx_gui + + + hier_block_src_path + .: + + + id + lora_receive_realtime + + + max_nouts + 0 + + + qt_qss_theme + + + + realtime_scheduling + + + + run_command + {python} -u {filename} + + + run_options + prompt + + + run + True + + + thread_safe_setters + + + + title + + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (544, 12) + + + _rotation + 0 + + + id + bitrate + + + value + sf * (1 / (2**sf / float(bw))) + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (456, 12) + + + _rotation + 0 + + + id + bw + + + value + 125000 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (280, 13) + + + _rotation + 0 + + + id + capture_freq + + + value + 915.0e6 + + + + variable + + comment + The decimation determines the oversampling rate. +A sample rate of 1e6 and decimation of 1 equals +8 times oversampling, a decimation of 2 is 4 times +oversampling, and so on. Set higher decimation +for better performance, but worse accuracy. + + + _enabled + True + + + _coordinate + (640, 76) + + + _rotation + 0 + + + id + decimation + + + value + 1 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (384, 76) + + + _rotation + 0 + + + id + downlink + + + value + False + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (768, 12) + + + _rotation + 0 + + + id + firdes_tap + + + value + firdes.low_pass(1, samp_rate, bw, 10000, firdes.WIN_HAMMING, 6.67) + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (912, 16) + + + _rotation + 0 + + + id + offset + + + value + -26e3 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (184, 13) + + + _rotation + 0 + + + id + samp_rate + + + value + 1e6 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (384, 12) + + + _rotation + 0 + + + id + sf + + + value + 7 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (640, 12) + + + _rotation + 0 + + + id + symbols_per_sec + + + value + float(bw) / (2**sf) + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (280, 76) + + + _rotation + 0 + + + id + target_freq + + + value + 915.0e6 + + + + lora_lora_receiver + + bandwidth + bw + + + alias + + + + crc + True + + + center_freq + capture_freq + + + channel_list + [target_freq] + + + cr + 4 + + + comment + + + + conj + downlink + + + affinity + + + + decimation + decimation + + + disable_channelization + False + + + disable_drift_correction + False + + + _enabled + 1 + + + _coordinate + (392, 212) + + + _rotation + 0 + + + id + lora_lora_receiver_0 + + + implicit + False + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + reduced_rate + False + + + samp_rate + 1e6 + + + sf + sf + + + + lora_message_socket_sink + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (640, 236) + + + _rotation + 0 + + + id + lora_message_socket_sink_0 + + + ip + 127.0.0.1 + + + layer + 0 + + + port + 40868 + + + + osmosdr_source + + alias + + + + ant0 + + + + bb_gain0 + 20 + + + bw0 + 0 + + + dc_offset_mode0 + 0 + + + corr0 + 0 + + + freq0 + capture_freq + + + gain_mode0 + False + + + if_gain0 + 20 + + + iq_balance_mode0 + 0 + + + gain0 + 10 + + + ant1 + + + + bb_gain1 + 20 + + + bw1 + 0 + + + dc_offset_mode1 + 0 + + + corr1 + 0 + + + freq1 + 100e6 + + + gain_mode1 + False + + + if_gain1 + 20 + + + iq_balance_mode1 + 0 + + + gain1 + 10 + + + ant2 + + + + bb_gain2 + 20 + + + bw2 + 0 + + + dc_offset_mode2 + 0 + + + corr2 + 0 + + + freq2 + 100e6 + + + gain_mode2 + False + + + if_gain2 + 20 + + + iq_balance_mode2 + 0 + + + gain2 + 10 + + + ant3 + + + + bb_gain3 + 20 + + + bw3 + 0 + + + dc_offset_mode3 + 0 + + + corr3 + 0 + + + freq3 + 100e6 + + + gain_mode3 + False + + + if_gain3 + 20 + + + iq_balance_mode3 + 0 + + + gain3 + 10 + + + ant4 + + + + bb_gain4 + 20 + + + bw4 + 0 + + + dc_offset_mode4 + 0 + + + corr4 + 0 + + + freq4 + 100e6 + + + gain_mode4 + False + + + if_gain4 + 20 + + + iq_balance_mode4 + 0 + + + gain4 + 10 + + + comment + + + + affinity + + + + args + + + + _enabled + 1 + + + _coordinate + (24, 188) + + + _rotation + 0 + + + id + osmosdr_source_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + nchan + 1 + + + type + fc32 + + + sample_rate + samp_rate + + + + uhd_usrp_source + + alias + + + + ant0 + RX2 + + + bw0 + 0 + + + center_freq0 + capture_freq + + + dc_offs_enb0 + "" + + + iq_imbal_enb0 + "" + + + norm_gain0 + False + + + gain0 + 15 + + + lo_export0 + False + + + lo_source0 + internal + + + ant10 + + + + bw10 + 0 + + + center_freq10 + 0 + + + dc_offs_enb10 + "" + + + iq_imbal_enb10 + "" + + + norm_gain10 + False + + + gain10 + 0 + + + lo_export10 + False + + + lo_source10 + internal + + + ant11 + + + + bw11 + 0 + + + center_freq11 + 0 + + + dc_offs_enb11 + "" + + + iq_imbal_enb11 + "" + + + norm_gain11 + False + + + gain11 + 0 + + + lo_export11 + False + + + lo_source11 + internal + + + ant12 + + + + bw12 + 0 + + + center_freq12 + 0 + + + dc_offs_enb12 + "" + + + iq_imbal_enb12 + "" + + + norm_gain12 + False + + + gain12 + 0 + + + lo_export12 + False + + + lo_source12 + internal + + + ant13 + + + + bw13 + 0 + + + center_freq13 + 0 + + + dc_offs_enb13 + "" + + + iq_imbal_enb13 + "" + + + norm_gain13 + False + + + gain13 + 0 + + + lo_export13 + False + + + lo_source13 + internal + + + ant14 + + + + bw14 + 0 + + + center_freq14 + 0 + + + dc_offs_enb14 + "" + + + iq_imbal_enb14 + "" + + + norm_gain14 + False + + + gain14 + 0 + + + lo_export14 + False + + + lo_source14 + internal + + + ant15 + + + + bw15 + 0 + + + center_freq15 + 0 + + + dc_offs_enb15 + "" + + + iq_imbal_enb15 + "" + + + norm_gain15 + False + + + gain15 + 0 + + + lo_export15 + False + + + lo_source15 + internal + + + ant16 + + + + bw16 + 0 + + + center_freq16 + 0 + + + dc_offs_enb16 + "" + + + iq_imbal_enb16 + "" + + + norm_gain16 + False + + + gain16 + 0 + + + lo_export16 + False + + + lo_source16 + internal + + + ant17 + + + + bw17 + 0 + + + center_freq17 + 0 + + + dc_offs_enb17 + "" + + + iq_imbal_enb17 + "" + + + norm_gain17 + False + + + gain17 + 0 + + + lo_export17 + False + + + lo_source17 + internal + + + ant18 + + + + bw18 + 0 + + + center_freq18 + 0 + + + dc_offs_enb18 + "" + + + iq_imbal_enb18 + "" + + + norm_gain18 + False + + + gain18 + 0 + + + lo_export18 + False + + + lo_source18 + internal + + + ant19 + + + + bw19 + 0 + + + center_freq19 + 0 + + + dc_offs_enb19 + "" + + + iq_imbal_enb19 + "" + + + norm_gain19 + False + + + gain19 + 0 + + + lo_export19 + False + + + lo_source19 + internal + + + ant1 + + + + bw1 + 0 + + + center_freq1 + 0 + + + dc_offs_enb1 + "" + + + iq_imbal_enb1 + "" + + + norm_gain1 + False + + + gain1 + 0 + + + lo_export1 + False + + + lo_source1 + internal + + + ant20 + + + + bw20 + 0 + + + center_freq20 + 0 + + + dc_offs_enb20 + "" + + + iq_imbal_enb20 + "" + + + norm_gain20 + False + + + gain20 + 0 + + + lo_export20 + False + + + lo_source20 + internal + + + ant21 + + + + bw21 + 0 + + + center_freq21 + 0 + + + dc_offs_enb21 + "" + + + iq_imbal_enb21 + "" + + + norm_gain21 + False + + + gain21 + 0 + + + lo_export21 + False + + + lo_source21 + internal + + + ant22 + + + + bw22 + 0 + + + center_freq22 + 0 + + + dc_offs_enb22 + "" + + + iq_imbal_enb22 + "" + + + norm_gain22 + False + + + gain22 + 0 + + + lo_export22 + False + + + lo_source22 + internal + + + ant23 + + + + bw23 + 0 + + + center_freq23 + 0 + + + dc_offs_enb23 + "" + + + iq_imbal_enb23 + "" + + + norm_gain23 + False + + + gain23 + 0 + + + lo_export23 + False + + + lo_source23 + internal + + + ant24 + + + + bw24 + 0 + + + center_freq24 + 0 + + + dc_offs_enb24 + "" + + + iq_imbal_enb24 + "" + + + norm_gain24 + False + + + gain24 + 0 + + + lo_export24 + False + + + lo_source24 + internal + + + ant25 + + + + bw25 + 0 + + + center_freq25 + 0 + + + dc_offs_enb25 + "" + + + iq_imbal_enb25 + "" + + + norm_gain25 + False + + + gain25 + 0 + + + lo_export25 + False + + + lo_source25 + internal + + + ant26 + + + + bw26 + 0 + + + center_freq26 + 0 + + + dc_offs_enb26 + "" + + + iq_imbal_enb26 + "" + + + norm_gain26 + False + + + gain26 + 0 + + + lo_export26 + False + + + lo_source26 + internal + + + ant27 + + + + bw27 + 0 + + + center_freq27 + 0 + + + dc_offs_enb27 + "" + + + iq_imbal_enb27 + "" + + + norm_gain27 + False + + + gain27 + 0 + + + lo_export27 + False + + + lo_source27 + internal + + + ant28 + + + + bw28 + 0 + + + center_freq28 + 0 + + + dc_offs_enb28 + "" + + + iq_imbal_enb28 + "" + + + norm_gain28 + False + + + gain28 + 0 + + + lo_export28 + False + + + lo_source28 + internal + + + ant29 + + + + bw29 + 0 + + + center_freq29 + 0 + + + dc_offs_enb29 + "" + + + iq_imbal_enb29 + "" + + + norm_gain29 + False + + + gain29 + 0 + + + lo_export29 + False + + + lo_source29 + internal + + + ant2 + + + + bw2 + 0 + + + center_freq2 + 0 + + + dc_offs_enb2 + "" + + + iq_imbal_enb2 + "" + + + norm_gain2 + False + + + gain2 + 0 + + + lo_export2 + False + + + lo_source2 + internal + + + ant30 + + + + bw30 + 0 + + + center_freq30 + 0 + + + dc_offs_enb30 + "" + + + iq_imbal_enb30 + "" + + + norm_gain30 + False + + + gain30 + 0 + + + lo_export30 + False + + + lo_source30 + internal + + + ant31 + + + + bw31 + 0 + + + center_freq31 + 0 + + + dc_offs_enb31 + "" + + + iq_imbal_enb31 + "" + + + norm_gain31 + False + + + gain31 + 0 + + + lo_export31 + False + + + lo_source31 + internal + + + ant3 + + + + bw3 + 0 + + + center_freq3 + 0 + + + dc_offs_enb3 + "" + + + iq_imbal_enb3 + "" + + + norm_gain3 + False + + + gain3 + 0 + + + lo_export3 + False + + + lo_source3 + internal + + + ant4 + + + + bw4 + 0 + + + center_freq4 + 0 + + + dc_offs_enb4 + "" + + + iq_imbal_enb4 + "" + + + norm_gain4 + False + + + gain4 + 0 + + + lo_export4 + False + + + lo_source4 + internal + + + ant5 + + + + bw5 + 0 + + + center_freq5 + 0 + + + dc_offs_enb5 + "" + + + iq_imbal_enb5 + "" + + + norm_gain5 + False + + + gain5 + 0 + + + lo_export5 + False + + + lo_source5 + internal + + + ant6 + + + + bw6 + 0 + + + center_freq6 + 0 + + + dc_offs_enb6 + "" + + + iq_imbal_enb6 + "" + + + norm_gain6 + False + + + gain6 + 0 + + + lo_export6 + False + + + lo_source6 + internal + + + ant7 + + + + bw7 + 0 + + + center_freq7 + 0 + + + dc_offs_enb7 + "" + + + iq_imbal_enb7 + "" + + + norm_gain7 + False + + + gain7 + 0 + + + lo_export7 + False + + + lo_source7 + internal + + + ant8 + + + + bw8 + 0 + + + center_freq8 + 0 + + + dc_offs_enb8 + "" + + + iq_imbal_enb8 + "" + + + norm_gain8 + False + + + gain8 + 0 + + + lo_export8 + False + + + lo_source8 + internal + + + ant9 + + + + bw9 + 0 + + + center_freq9 + 0 + + + dc_offs_enb9 + "" + + + iq_imbal_enb9 + "" + + + norm_gain9 + False + + + gain9 + 0 + + + lo_export9 + False + + + lo_source9 + internal + + + clock_rate + 0.0 + + + comment + + + + affinity + + + + dev_addr + "" + + + dev_args + "" + + + _enabled + 0 + + + _coordinate + (16, 388) + + + _rotation + 0 + + + id + uhd_usrp_source_0 + + + maxoutbuf + 0 + + + clock_source0 + + + + sd_spec0 + + + + time_source0 + + + + clock_source1 + + + + sd_spec1 + + + + time_source1 + + + + clock_source2 + + + + sd_spec2 + + + + time_source2 + + + + clock_source3 + + + + sd_spec3 + + + + time_source3 + + + + clock_source4 + + + + sd_spec4 + + + + time_source4 + + + + clock_source5 + + + + sd_spec5 + + + + time_source5 + + + + clock_source6 + + + + sd_spec6 + + + + time_source6 + + + + clock_source7 + + + + sd_spec7 + + + + time_source7 + + + + minoutbuf + 0 + + + nchan + 1 + + + num_mboards + 1 + + + type + fc32 + + + samp_rate + samp_rate + + + hide_cmd_port + False + + + hide_lo_controls + True + + + stream_args + + + + stream_chans + [] + + + sync + + + + otw + + + + + wxgui_fftsink2 + + avg_alpha + 0 + + + average + False + + + baseband_freq + capture_freq + + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + fft_size + 1024 + + + freqvar + None + + + _coordinate + (392, 340) + + + _rotation + 0 + + + grid_pos + + + + id + wxgui_fftsink2_1 + + + notebook + + + + peak_hold + False + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_rate + 15 + + + samp_rate + samp_rate + + + title + FFT Plot + + + type + complex + + + win_size + + + + win + None + + + y_divs + 10 + + + y_per_div + 10 + + + + lora_lora_receiver_0 + lora_message_socket_sink_0 + frames + in + + + osmosdr_source_0 + lora_lora_receiver_0 + 0 + 0 + + + osmosdr_source_0 + wxgui_fftsink2_1 + 0 + 0 + + + uhd_usrp_source_0 + lora_lora_receiver_0 + 0 + 0 + + + uhd_usrp_source_0 + wxgui_fftsink2_1 + 0 + 0 + + diff --git a/sdr-companion/Dockerfile b/sdr-companion/Dockerfile new file mode 100644 index 0000000..a61785c --- /dev/null +++ b/sdr-companion/Dockerfile @@ -0,0 +1,34 @@ +from archlinux:latest + +workdir /lib + +# Update to latest arch +run pacman -Syu --noconfirm + +# Install required dependencies +run pacman -S git python2-scipy swig cppunit fftw boost boost-libs gnuradio gnuradio-osmosdr libvolk log4cpp base-devel cmake wxgtk-common wxgtk2 wxgtk3 wxpython libuhd-firmware gnuradio-companion python2-requests --noconfirm + +workdir /liquid + +# Manual liquid-dsp install +run git clone https://github.com/jgaeddert/liquid-dsp.git . && \ + sh ./bootstrap.sh && \ + sh ./configure --prefix=/usr && \ + make && \ + make install + +# Install gr-lora +workdir /src + +arg CACHEBUST +run git clone https://github.com/rpp0/gr-lora.git . && \ + mkdir build && \ + cd build && \ + cmake ../ -DCMAKE_INSTALL_PREFIX=/usr && \ + make && \ + make install && \ + ldconfig + +workdir /src/apps + +expose 40868 diff --git a/sdr-companion/docker_build_image.sh b/sdr-companion/docker_build_image.sh new file mode 100755 index 0000000..37c121e --- /dev/null +++ b/sdr-companion/docker_build_image.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +LATEST_VERSION=`git ls-remote https://github.com/rpp0/gr-lora.git | grep HEAD | cut -f 1` +docker build -t rpp0/gr-lora --build-arg CACHEBUST=$LATEST_VERSION . +#docker tag rpp0/gr-lora:latest rpp0/gr-lora:$LATEST_VERSION diff --git a/sdr-companion/docker_run_grlora.sh b/sdr-companion/docker_run_grlora.sh new file mode 100755 index 0000000..a55091a --- /dev/null +++ b/sdr-companion/docker_run_grlora.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +DOCKER_XAUTH=/tmp/.docker.xauth +touch /tmp/.docker.xauth +xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $DOCKER_XAUTH nmerge - +docker run -i -t --rm --privileged -e DISPLAY=$DISPLAY -e XAUTHORITY=$DOCKER_XAUTH -v /tmp/.docker.xauth:/tmp/.docker.xauth:ro -v /tmp/.X11-unix:/tmp/.X11-unix:ro -v /dev/bus/usb:/dev/bus/usb --entrypoint /bin/bash rpp0/gr-lora:latest diff --git a/sdr-companion/mkimage-arch-pacman.conf b/sdr-companion/mkimage-arch-pacman.conf new file mode 100644 index 0000000..e6ef1e1 --- /dev/null +++ b/sdr-companion/mkimage-arch-pacman.conf @@ -0,0 +1,91 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -C - -f %u > %o +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +#UseDelta = 0.7 +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#TotalDownload +# We cannot check disk space from within a chroot environment +#CheckSpace +#VerbosePkgLists + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +#[testing] +#Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +#[community-testing] +#Include = /etc/pacman.d/mirrorlist + +[community] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/sdr-companion/mkimage-arch.sh b/sdr-companion/mkimage-arch.sh new file mode 100755 index 0000000..ad63180 --- /dev/null +++ b/sdr-companion/mkimage-arch.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +# Generate a minimal filesystem for archlinux and load it into the local +# docker as "archlinux" +# requires root +set -e + +hash pacstrap &>/dev/null || { + echo "Could not find pacstrap. Run pacman -S arch-install-scripts" + exit 1 +} + +hash expect &>/dev/null || { + echo "Could not find expect. Run pacman -S expect" + exit 1 +} + + +export LANG="C.UTF-8" + +ROOTFS=$(mktemp -d ${TMPDIR:-/var/tmp}/rootfs-archlinux-XXXXXXXXXX) +chmod 755 $ROOTFS + +# packages to ignore for space savings +PKGIGNORE=( + cryptsetup + device-mapper + dhcpcd + iproute2 + jfsutils + linux + lvm2 + man-db + man-pages + mdadm + nano + netctl + openresolv + pciutils + pcmciautils + reiserfsprogs + s-nail + systemd-sysvcompat + usbutils + vi + xfsprogs +) +IFS=',' +PKGIGNORE="${PKGIGNORE[*]}" +unset IFS + +arch="$(uname -m)" +# Set to arch="armv7hf" in order to cross-compile +case "$arch" in + armv*) + if pacman -Q archlinuxarm-keyring >/dev/null 2>&1; then + pacman-key --init + pacman-key --populate archlinuxarm + else + echo "Could not find archlinuxarm-keyring. Please, install it and run pacman-key --populate archlinuxarm" + exit 1 + fi + PACMAN_CONF=$(mktemp ${TMPDIR:-/var/tmp}/pacman-conf-archlinux-XXXXXXXXX) + version="$(echo $arch | cut -c 5)" + sed "s/Architecture = armv/Architecture = armv${version}h/g" './mkimage-archarm-pacman.conf' > "${PACMAN_CONF}" + PACMAN_MIRRORLIST='Server = http://mirror.archlinuxarm.org/$arch/$repo' + PACMAN_EXTRA_PKGS='archlinuxarm-keyring' + EXPECT_TIMEOUT=1800 # Most armv* based devices can be very slow (e.g. RPiv1) + ARCH_KEYRING=archlinuxarm + DOCKER_IMAGE_NAME="armv${version}h/archlinux" + ;; + *) + PACMAN_CONF='./mkimage-arch-pacman.conf' + PACMAN_MIRRORLIST='Server = https://mirrors.kernel.org/archlinux/$repo/os/$arch' + PACMAN_EXTRA_PKGS='' + EXPECT_TIMEOUT=60 + ARCH_KEYRING=archlinux + DOCKER_IMAGE_NAME=archlinux + ;; +esac + +export PACMAN_MIRRORLIST + +expect < $ROOTFS/etc/locale.gen +arch-chroot $ROOTFS locale-gen +arch-chroot $ROOTFS /bin/sh -c 'echo $PACMAN_MIRRORLIST > /etc/pacman.d/mirrorlist' + +# udev doesn't work in containers, rebuild /dev +DEV=$ROOTFS/dev +rm -rf $DEV +mkdir -p $DEV +mknod -m 666 $DEV/null c 1 3 +mknod -m 666 $DEV/zero c 1 5 +mknod -m 666 $DEV/random c 1 8 +mknod -m 666 $DEV/urandom c 1 9 +mkdir -m 755 $DEV/pts +mkdir -m 1777 $DEV/shm +mknod -m 666 $DEV/tty c 5 0 +mknod -m 600 $DEV/console c 5 1 +mknod -m 666 $DEV/tty0 c 4 0 +mknod -m 666 $DEV/full c 1 7 +mknod -m 600 $DEV/initctl p +mknod -m 666 $DEV/ptmx c 5 2 +ln -sf /proc/self/fd $DEV/fd + +tar --numeric-owner --xattrs --acls -C $ROOTFS -c . | docker import - $DOCKER_IMAGE_NAME +docker run --rm -t $DOCKER_IMAGE_NAME echo Success. +rm -rf $ROOTFS diff --git a/sdr-companion/sdr-companion.md b/sdr-companion/sdr-companion.md new file mode 100644 index 0000000..db3884a --- /dev/null +++ b/sdr-companion/sdr-companion.md @@ -0,0 +1,75 @@ +# Introduction + +In certain scenarios, traditional LoRa receivers, such as the Adafruit Feather LoRa or Lostik, may not adequately decode LoRa traffic. To address this, we introduce a Software Defined Radio (SDR) companion module designed to offer a more robust alternative for decoding when the conventional LoRa Scanner application falls short. + +SDRs provide unparalleled flexibility compared to traditional hardware radios, which are often limited by their specific design and capabilities. With an SDR, you can decode a wide array of signals beyond LoRa, making it an invaluable tool for radio signal research and experimentation. The ability to tweak settings and experiment with different decoding algorithms allows for a deeper exploration into radio communications. This is especially beneficial in the evolving field of LoRa technology, where ongoing research and experimentation can yield significant insights. Projects like the HackRF demonstrate the power of a supportive community, offering extensive resources to enhance your SDR experience. + +## gr-lora + +The **gr-lora** project comprises GNU Radio blocks designed to decode LoRa-modulated radio messages using an SDR. LoRa (Long Range) is crucial for Internet of Things (IoT) applications due to its long-range, low-power, and low-bitrate communication capabilities. + +While gr-lora supports the majority of LoRa's physical-layer modulation features, it does not facilitate CRC checks of payload and header or decode multiple channels simultaneously. Tested primarily with a USRP B201 and a Microchip RN2483 transmitter, it is also compatible with popular SDRs like the HackRF. + +A standout feature of gr-lora is its clock recovery algorithm, introduced in version 0.6, enhancing the handling of long LoRa messages. Improvements in whitening, detection, and decoding further solidify its utility in IoT applications. This ongoing project exemplifies the collaborative spirit of the open-source community, continually evolving to meet users' needs. + +## Running the sdr-companion + +Ensure [Docker](https://www.docker.com/get-started/) is installed on your system to proceed with the sdr-companion setup. + +1. **Download the Docker Image**: Begin by downloading the gr-lora image using the following command: + + ```bash + docker pull rpp0/gr-lora:latest + ``` + +2. **Prepare Your SDR**: Connect your SDR (e.g., HackRF) to your machine. Ensure device permissions are correctly set to avoid detection issues. + +3. **Run the Docker Container**: Execute the script to start the Docker container with gr-lora: + + ```bash + ./docker_run_grlora.sh + ``` + + Upon success, you'll enter the Docker container environment: + + ```bash + [root@9089ddfe32b5 apps]# + ``` + +4. **Launch GNU Radio Companion**: Inside the container, open the lora_receive_realtime.grc flowgraph with GNU Radio Companion: + + ```bash + gnuradio-companion lora_receive_realtime.grc + ``` + +5. **Configure and Execute**: Adjust the frequency, spreading factor, and other settings as needed at the gnuradio-companion interface. Start receiving and decoding by selecting *Run -> Execute*. + + Decoded traffic will be displayed in hex format in the gnuradio-companion console. + +## Prebuilt Flowgraphs + +For convenience, prebuilt flowgraphs for specific frequencies are available: + +- **915 MHz SF7 125k BW CR 4/5**: `915-sf7-125bw-cr4_5.grc` +- **868 MHz SF7 125k BW CR 4/5**: `868-sf7-125bw-cr4_5.grc` + +To download these into the Docker container: + +1. **Identify Host IP**: Use `ip addr` (or `ifconfig` if available) to find your host machine's IP address. + +2. **Host Web Server**: On your host machine, in the directory with the flowgraphs, start a web server: + + ```bash + python3 -m http.server 80 + ``` + +3. **Download Flowgraphs**: Inside the container, use curl to download the desired flowgraph: + + ```bash + curl -O http:///915-sf7-125bw-cr4_5.grc + curl -O http:///868-sf7-125bw-cr4_5.grc + ``` + +## Troubleshooting and Support + +For troubleshooting common issues or seeking additional guidance, refer to the gr-lora project documentation and community forums. These resources can provide valuable support as you navigate installation and operation challenges. diff --git a/templates/analysis.html b/templates/analysis.html index dff10fd..ea6dd16 100644 --- a/templates/analysis.html +++ b/templates/analysis.html @@ -67,12 +67,31 @@
-
+

+ + +

Status: Checking...

+ - +
diff --git a/templates/tracking.html b/templates/tracking.html index ddac759..55d8c66 100644 --- a/templates/tracking.html +++ b/templates/tracking.html @@ -75,50 +75,71 @@
+ -