{"id":16132018,"url":"https://github.com/jeija/renard-phy","last_synced_at":"2025-03-18T14:31:30.357Z","repository":{"id":145096818,"uuid":"150616194","full_name":"Jeija/renard-phy","owner":"Jeija","description":"Open Sigfox Stack Reference Implementation - Physical Layer for SDR","archived":false,"fork":false,"pushed_at":"2020-06-12T20:45:29.000Z","size":112,"stargazers_count":22,"open_issues_count":0,"forks_count":11,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-02-28T10:09:55.401Z","etag":null,"topics":["phy","reverse-engineering","sdr","sigfox"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Jeija.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-27T16:25:51.000Z","updated_at":"2024-11-13T16:48:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"b7cb7c57-d4aa-472c-9325-77d1b5cfedf5","html_url":"https://github.com/Jeija/renard-phy","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jeija%2Frenard-phy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jeija%2Frenard-phy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jeija%2Frenard-phy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jeija%2Frenard-phy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Jeija","download_url":"https://codeload.github.com/Jeija/renard-phy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243933431,"owners_count":20370986,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["phy","reverse-engineering","sdr","sigfox"],"created_at":"2024-10-09T22:28:47.518Z","updated_at":"2025-03-18T14:31:30.350Z","avatar_url":"https://github.com/Jeija.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `renard-phy` - Sigfox Protocol Physical Layer\n\n\u003cimg src=\"logo.svg\" align=\"right\" width=\"20%\"/\u003e\n\n`renard-phy` is an open source physical layer implementation of the Sigfox protocol's uplink and downlink written in Python for use with software defined radios (SDRs).\nIt supports demodulating received Sigfox uplinks and downlinks recorded as WAV files (e.g. with [gqrx](http://gqrx.dk/) and any SDR hardware that supports Sigfox's frequency range).\nModulating uplink and downlink frames is supported for the [*HackRF One*](https://greatscottgadgets.com/hackrf/) SDR.\n\n`renard-phy` is built on top of [`renard`](https://github.com/Jeija/renard), the CLI interface to the open source Sigfox protocol library [`librenard`](https://github.com/Jeija/librenard).\n\n`renard-phy` has only been tested in regulatory zone \"RCZ1\" (Europe / ETSI).\n\n## Install / Dependencies\n* `renard-phy` requires `renard` as a git submodule, so make sure to clone this repository recursively:\n```\ngit clone --recursive https://github.com/Jeija/renard-phy\n```\n* Compile `renard` (see also [`renard`'s README](https://github.com/Jeija/renard))\n```\ncd renard\nmake\ncd ..\n```\n* Install `renard-phy`'s dependencies: [NumPy](https://www.numpy.org/), [SciPy](https://www.scipy.org/), [Scapy](https://scapy.net/) and [matplotlib](https://matplotlib.org/). If you wish to transmit frames with the *HackRF One*, make sure to install the [HackRF drivers](https://github.com/mossmann/hackrf) so that `/usr/bin/hackrf_transfer` exists.\n\n## Usage\n### Sample Recordings\nIf you want to try out `renard-phy`, but don't have recordings of Sigfox uplinks / downlinks, you can download [sample WAV files](https://github.com/Jeija/renard-phy/releases/tag/recordings-release).\n\n### Demodulation\n#### Uplink\n* Demodulate, do not decode:\n```\n$ cd renard-phy\n$ ./uplink/demodulate.py uplink_4byte_zeros.wav\nEstimating Frequency using 4096-length FFT\nSignal Frequency: 2707.03 Hz\nMixing to Baseband with Costas Loop...\nLow-pass Filtering...\nNormalizing...\nFinding Preamble(s)...\nFound 3 Preambles!\n[Frame 0]: Determining Frame Type...\n[Frame 0]: Frame Type is 0x35f, Packet Length 12 bits\n[Frame 0]: Content: 35f0088db334d000000000089b9c3e7\n[Frame 0]: Decoding with renard:\n[Frame 1]: Determining Frame Type...\n[Frame 1]: Frame Type is 0x598, Packet Length 12 bits\n[Frame 1]: Content: 59800ee806638c000000000ef0b52ed\n[Frame 1]: Decoding with renard:\n[Frame 2]: Determining Frame Type...\n[Frame 2]: Frame Type is 0x5a3, Packet Length 12 bits\n[Frame 2]: Content: 5a300aaedff9e4000000000abd7b31e\n[Frame 2]: Decoding with renard:\n```\n\n* Demodulate and plot baseband signal, mark preambles:\n```\n$ ./uplink/demodulate.py uplink_4byte_zeros.wav --plot\n```\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"uplink_plot_screenshot.png\" width=\"50%\"/\u003e\n\u003c/p\u003e\n\n* Demodulate and decode frame contents with `renard` (you can also do this manually by copy-pasting the frame content output):\n```\n$ ./uplink/demodulate.py uplink_4byte_zeros.wav --decode\n```\n\n#### Downlink\n* Demodulate, do not decode:\n```\n$ ./downlink/demodulate.py downlink_0000000000000000.wav\n```\n\n* Demodulate and plot baseband signal, mark preamble:\n```\n$ ./downlink/demodulate.py downlink_0000000000000000.wav --plot\n```\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"downlink_plot_screenshot.png\" width=\"50%\"/\u003e\n\u003c/p\u003e\n\n* Demodulate and brute-force-decode (other decoding options are available by manually copy-pasting the frame output for use with `renard`):\n```\n$ ./downlink/demodulate.py downlink_0000000000000000.wav --decode\n```\n\n### Modulation and Transmission with *HackRF One*\nThe content (payload / device ID / SN / ...) of the transmitted frames is generated by `renard`. Command line arguments to the `modulate_hackrf.py` scripts are passed to renard, so see [`renard`'s documentation](https://github.com/Jeija/renard) for a more extensive overview of possible command line options.\n\n#### Uplink\n* Transmit uplink with payload `0xabad1dea`. Mind that all command line options to `./uplink/modulate_hackrf.py` are simply forwarded to `renard ulencode` and `renard`'s raw frame output is then converted to raw signals for transmission with the *HackRF One*.\n```\n$ ./uplink/modulate_hackrf.py -p abad1dea -s 1a0 -i 004d33db -k 479e4480fd7596d45b0122fd282db3cf\n```\n\n* You can also transmit uplinks with arbitrary frame contents using `./uplink/modulate_hackrf_hex.py` by providing the binary frame content as hexadecimal string:\n```\n$ ./uplink/modulate_hackrf_hex.py aaaaa35f0001db334d00deadbeef68a60055\n```\n\n* You can even transmit multiple uplinks at different frequencies at the same time (frequency multiplexing) by providing all their hexadecimal frame contents to `./uplink/modulate_hackrf_hex_multiplex.py`. The script will output a command that can be used to transmit the generated *HackRF One* sample file:\n```\n$ ./uplink/modulate_hackrf_hex_multiplex.py aaaaa35f0001db334d00deadbeef68a60055 aaaaa35f0002db334d00abad1dea7c74c0e0\n```\n\n#### Downlink\n* Transmit downlink with payload `0xdeadbeef02468ace`. The first parameter to `./downlink/modulate_hackrf.py` is the frequency of the *uplink that requested the downlink* in Hz. This value is used to calculate the appropriate downlink frequency that the frame is transmitted at. All further command line options are simply forwareded to `renard dlencode`.\n```\n$ ./downlink/modulate_hackrf.py 868100000 -p deadbeef02468ace -i 004d33db -k 479e4480fd7596d45b0122fd282db3cf -s 1a1\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeija%2Frenard-phy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeija%2Frenard-phy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeija%2Frenard-phy/lists"}