Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test refactor #8

Merged
merged 11 commits into from
May 26, 2021
16 changes: 8 additions & 8 deletions Manifest.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# This file is machine-generated - editing it directly is not advised

[[AdalmPluto]]
deps = ["Pkg", "Reexport", "Test"]
git-tree-sha1 = "dfe2f2f230d4d53fe0692ea4f8b7bfe0325bf2e5"
deps = ["Pkg", "Printf", "Reexport", "Test"]
git-tree-sha1 = "d3996574c75ac9ea44f94454d6c1893d6a861761"
uuid = "af34ca7c-e544-47d5-a6fe-72495f08728e"
version = "0.1.1"
version = "0.2.2"

[[ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
Expand Down Expand Up @@ -78,9 +78,9 @@ uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[Preferences]]
deps = ["TOML"]
git-tree-sha1 = "ea79e4c9077208cd3bc5d29631a26bc0cff78902"
git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.1"
version = "1.2.2"

[[Printf]]
deps = ["Unicode"]
Expand Down Expand Up @@ -126,10 +126,10 @@ deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[UHDBindings]]
deps = ["Libdl", "Printf"]
git-tree-sha1 = "d072efd625bf9029e55559d480ef3e4c0e83ae43"
deps = ["Libdl", "Pkg", "Printf", "Test"]
git-tree-sha1 = "3f27d40fb8337445194c03e11640131abe91ad0c"
uuid = "4d90b16f-829e-4b78-80d9-fb9bcf8c06e0"
version = "0.1.3"
version = "0.2.0"

[[UUIDs]]
deps = ["Random", "SHA"]
Expand Down
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "AbstractSDRs"
uuid = "0bdde9fc-719a-4dc7-8589-49ca6634fa6b"
authors = ["Robin Gerzaguet <[email protected]>"]
version = "0.1.2"
version = "0.2.0"

[deps]
AdalmPluto = "af34ca7c-e544-47d5-a6fe-72495f08728e"
Expand All @@ -10,13 +10,13 @@ Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
RTLSDR = "71cfaeeb-f3e6-59e7-80b9-1b8c23d8f010"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
UHDBindings = "4d90b16f-829e-4b78-80d9-fb9bcf8c06e0"
ZMQ = "c2297ded-f4af-51ae-bb23-16f91089e4e1"

[compat]
AdalmPluto = "0.1"
AdalmPluto = "0.2"
RTLSDR = "0.0.1"
Reexport = "0.2, 1.0"
UHDBindings = "0.1"
UHDBindings = "0.2"
ZMQ = "1.2"
julia = "1.5,1.6"
File renamed without changes.
10 changes: 9 additions & 1 deletion tests/minimalTransceiver.jl → examples/minimalTransceiver.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# using Pkg; Pkg.develop(PackageSpec(path="../UHD"));Pkg.activate(".");
# ----------------------------------------------------
# --- minimalTransceiver.jl
# ----------------------------------------------------
# This file is intented to give an example on how we can use tree based network architecture with SDR
# This file has to be run on a SDR based SoC that communicated with a remote PC
# ---------
# |
# For instance, a USRP e310 with a julia session runs minimalTransceiver.jl
# On the PC side, the backend SDROverNetworks can be used to recover data from the E310
@info "Julia-based minimal transceiver";

using Distributed
Expand Down
218 changes: 61 additions & 157 deletions src/AbstractSDRs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,67 +7,71 @@ using Sockets
using Reexport
using RTLSDR


import Base:close;
# ----------------------------------------------------
# --- UHD Bindings
# ----------------------------------------------------
# ---
@reexport using UHDBindings
# --- Specific UHD related functions
export UHDBinding

# ----------------------------------------------------
# --- Adalm Pluto managment
# ----------------------------------------------------
# ---
@reexport using AdalmPluto
export AdalmPluto;
export updateGainMode!;
# --- Conversion
# Adalm Pluto structure is based on Int parameters, and AbstractSDRs use massively Float. We need to convert just before dispatching. As some parameter may be float (as gain) we should round before conversion. The following function does that.
_toInt(x) = Int(round(x));
# --- Get Supported backends
# ----------------------------------------------------
"""
Returns an array of symbol which lists the supported SDR backends
# --- Syntax
l = getSupportedSDR()
# --- Input parameters
-
# --- Output parameters
- l : Array of symbols of supported SDRs
"""
function getSupportedSDRs()
return [:uhd;:sdr_over_network;:radiosim;:pluto;:rtlsdr];
end
export getSupportedSDRs


# ----------------------------------------------------
# --- RTL-SDR bindings
# ----------------------------------------------------
include("RTLSDRBindings.jl");
@reexport using .RTLSDRBindings
export RTLSDRBinding

# ----------------------------------------------------
# --- Socket System
# ----------------------------------------------------
# --- Create and load module to pilot E310 devices
# To control this device we create a pure Socket based system
# for which the AbstractSDRs package will help to bind the utils
include("SDROverNetworks.jl");
@reexport using .SDROverNetworks
# --- Specific E310 related functions
export SDROverNetwork;
# --- Utils
# ----------------------------------------------------
# Common generic functions and glue required for the package
# Nothing strictly related to radio here, only common stuff
include("Utils.jl")

# ----------------------------------------------------
# --- Simulation Radio
# --- Backends
# ----------------------------------------------------
# --- Load backend
include("Backends.jl")

# ----------------------------------------------------
# --- Create and module to emulate a radio device without any actual radio connected
include("RadioSims.jl");
@reexport using .RadioSims
# --- Specific simulation related function
export updatePacketSize!;
export updateBuffer!;
export RadioSim;
# --- Scanning
# ----------------------------------------------------
include("Scan.jl")
export scan

# ----------------------------------------------------
# --- Setting all methods using dispatch
# --- Radio configuration (update radio parameters)
# ----------------------------------------------------
include("Mutators.jl")
export updateCarrierFreq!
export updateSamplingRate!
export updateGain!
export updateGainMode!

# ----------------------------------------------------
# --- Common framework functions
# Closing resources call
# close(radio::RadioSim) = RadioSim.close(radio);
# close(radio::UHDBinding) = UHDBindings.close(radio);
# close(radio::SDROverNetwork) = SDROverNetworks.close(radio);
# close(radio::RTLSDRBinding) = RTLSDRBindings.close(radio);
# close(obj::PlutoSDR) = AdalmPluto.close(obj);
# export close;
# --- Assessors (get radio parameters)
# ----------------------------------------------------
include("Assessors.jl")
export getError
export getTimestamp
export getSamplingRate
export getCarrierFreq
export getGain
export isClosed
export getBufferSize


#----------------------------------------------------
# --- Common API
# ----------------------------------------------------

# recv call
"""
Expand Down Expand Up @@ -118,117 +122,14 @@ send(radio,buffer,cyclic=false)
- nbEch : Number of samples effectively send [Csize_t]. It corresponds to the number of complex samples sent.
"""

send(sig,obj::SDROverNetwork,tul...;kwarg...) = SDROverNetworks.send(sig,obj,tul...;kwarg...);
send(sig,obj::UHDBinding,tul...) = UHDBindings.send(sig,obj,tul...);
send(sig,obj::RadioSim,tul...) = RadioSims.send(sig,obj,tul...);
send(sig,obj::RTLSDRBinding,tul...) = RTLSDRBindings.send(sig,obj,tul...);
send(obj::SDROverNetwork,sig,tul...;kwarg...) = SDROverNetworks.send(obj,sig,tul...;kwarg...);
send(obj::UHDBinding,sig,tul...) = UHDBindings.send(obj,sig,tul...)
send(obj::RadioSim,sig,tul...) = RadioSims.send(obj,sig,tul...)
send(obj::RTLSDRBinding,sig,tul...) = RTLSDRBindings.send(obj,sig,tul...)
send(obj::PlutoSDR,sig,tul...;kwarg...) = AdalmPluto.send(obj,sig,tul...;parseKeyword(kwarg,[:use_internal_buffer])...)
export send

# Radio API
updateCarrierFreq!(obj::SDROverNetwork,tul...) = SDROverNetworks.updateCarrierFreq!(obj,tul...);
updateCarrierFreq!(obj::UHDBinding,tul...) = UHDBindings.updateCarrierFreq!(obj,tul...);
updateCarrierFreq!(obj::RadioSim,tul...) = RadioSims.updateCarrierFreq!(obj,tul...);
updateCarrierFreq!(obj::RTLSDRBinding,tul...) = RTLSDRBindings.updateCarrierFreq!(obj,tul...);
updateCarrierFreq!(obj::PlutoSDR,tul...) = AdalmPluto.updateCarrierFreq!(obj,_toInt.(tul)...);
export updateCarrierFreq!;

"""
Update sampling rate of current radio device, and update radio object with the new obtained sampling frequency.
# --- Syntax
updateSamplingRate!(radio,samplingRate)
# --- Input parameters
- radio : SDR device
- samplingRate : New desired sampling rate
# --- Output parameters
-
"""
updateSamplingRate!(obj::SDROverNetwork,tul...) = SDROverNetworks.updateSamplingRate!(obj,tul...);
updateSamplingRate!(obj::UHDBinding,tul...) = UHDBindings.updateSamplingRate!(obj,tul...);
updateSamplingRate!(obj::RadioSim,tul...) = RadioSims.updateSamplingRate!(obj,tul...);
updateSamplingRate!(obj::RTLSDRBinding,tul...) = RTLSDRBindings.updateSamplingRate!(obj,tul...);
function updateSamplingRate!(obj::PlutoSDR,tul...)
# For Adalm Pluto we should also update the RF filter band
AdalmPluto.updateSamplingRate!(obj,_toInt.(tul)...);
AdalmPluto.updateBandwidth!(obj,_toInt.(tul)...);
return obj.rx.effectiveSamplingRate
end
export updateSamplingRate!;

"""
Update gain of current radio device, and update radio object with the new obtained gain.
If the input is a [UHDRx] or a [UHDTx] object, it updates only the Rx or Tx gain
# --- Syntax
updateGain!(radio,gain)
# --- Input parameters
- radio : SDR device
- gain : New desired gain
# --- Output parameters
-
"""
updateGain!(obj::SDROverNetwork,tul...) = SDROverNetworks.updateGain!(obj,tul...);
updateGain!(obj::UHDBinding,tul...) = UHDBindings.updateGain!(obj,tul...);
updateGain!(obj::RadioSim,tul...) = RadioSims.updateGain!(obj,tul...);
updateGain!(obj::RTLSDRBinding,tul...) = RTLSDRBindings.updateGain!(obj,tul...);
updateGain!(obj::PlutoSDR,tul...) = AdalmPluto.updateGain!(obj,_toInt.(tul)...);
export updateGain!;

getError(obj::UHDBinding) = UHDBindings.getError(obj);
getError(obj::RadioSim) = RadioSims.getError(obj);
getError(obj::SDROverNetwork) = SDROverNetworks.getMD(obj)[3];
getError(obj::RTLSDRBinding) = RTLSDRBindings.getError(obj);
export getError;

getTimestamp(obj::UHDBinding) = UHDBindings.getTimestamp(obj);
getTimestamp(obj::RadioSim) = RadioSims.getTimestamp(obj);
getTimestamp(obj::SDROverNetwork) = SDROverNetworks.getMD(obj)[1:2];
getTimestamp(obj::RTLSDRBinding) = RTLSDRBindings.getTimestamp(obj);

"""
Get the current sampling rate of the radio device
The second parameter (optionnal) speicfies the Rx or Tx board (default : Rx)
"""
getSamplingRate(obj::UHDBinding;mode=:rx) = ((mode == :rx) ? obj.rx.samplingRate : obj.tx.samplingRate)
getSamplingRate(obj::RadioSim;mode=:rx) = ((mode == :rx) ? obj.rx.samplingRate : obj.tx.samplingRate)
getSamplingRate(obj::SDROverNetwork;mode=:rx) = ((mode == :rx) ? obj.rx.samplingRate : obj.tx.samplingRate)
getSamplingRate(obj::PlutoSDR;mode=:rx) = ((mode == :rx) ? obj.rx.effectiveSamplingRate : obj.tx.effectiveSamplingRate)
export getSamplingRate

"""
Get the current carrier frequency of the radio device
The second parameter (optionnal) speicfies the Rx or Tx board (default : Rx)
"""
getCarrierFreq(obj::UHDBinding;mode=:rx) = (mode == :rx) ? obj.rx.samplingRate : obj.tx.samplingRate
getCarrierFreq(obj::RadioSim;mode=:rx) = (mode == :rx) ? obj.rx.samplingRate : obj.tx.samplingRate
getCarrierFreq(obj::SDROverNetwork;mode=:rx) = (mode == :rx) ? obj.rx.samplingRate : obj.tx.samplingRate
getCarrierFreq(obj::PlutoSDR;mode=:rx) = (mode == :rx) ? obj.rx.effectiveCarrierFreq : obj.tx.effectiveCarrierFreq
export getCarrierFreq

# --- Container for Radio use
# We will have functions from different origin and different supported keywords
# This function parse the input keywords and returns the ones supported by the function, listed in iteration
function parseKeyword(kwargs,iteration)
# We populate a new dictionnary based on the input keywords and the supported ones
# In order not to create keywords that are not supported (i.e leaving the default value)
# we only evaluate the keywords defined both in the 2 dictionnaries
# This means that the default fallback should never happen
kwargs = Dict(key=>get(kwargs,key,0) for key in intersect(iteration,keys(kwargs)))
return kwargs
end


"""
Returns an array of symbol which lists the supported SDR backends
# --- Syntax
l = getSupportedSDR()
# --- Input parameters
-
# --- Output parameters
- l : Array of symbols of supported SDRs
"""
function getSupportedSDRs()
return [:uhd;:sdr_over_network;:radiosim;:pluto;:rtlsdr];
end
export getSupportedSDRs
"""
Open a Software Defined Radio of backend 'type', tune accordingly based on input parameters and use the supported keywords.
It returns a radio object, depending on the type of SDR that can be used with all AbstractSDRs supported functions
Expand Down Expand Up @@ -287,4 +188,7 @@ function openSDR(name::Symbol,tul...;key...)
end
export openSDR;




end # module
64 changes: 64 additions & 0 deletions src/Assessors.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# ----------------------------------------------------
# --- Accessor.jl
# ----------------------------------------------------
# Function to access to radio parameters

getError(obj::UHDBinding) = UHDBindings.getError(obj);
getError(obj::RadioSim) = RadioSims.getError(obj);
getError(obj::SDROverNetwork) = SDROverNetworks.getMD(obj)[3];
getError(obj::RTLSDRBinding) = RTLSDRBindings.getError(obj);

getTimestamp(obj::UHDBinding) = UHDBindings.getTimestamp(obj);
getTimestamp(obj::RadioSim) = RadioSims.getTimestamp(obj);
getTimestamp(obj::SDROverNetwork) = SDROverNetworks.getMD(obj)[1:2];
getTimestamp(obj::RTLSDRBinding) = RTLSDRBindings.getTimestamp(obj);

"""
Get the current sampling rate of the radio device
The second parameter (optionnal) speicfies the Rx or Tx board (default : Rx)
"""
getSamplingRate(obj::AbstractSDR;mode=:rx) = ((mode == :rx) ? obj.rx.samplingRate : obj.tx.samplingRate)
getSamplingRate(obj::PlutoSDR;mode=:rx) = ((mode == :rx) ? obj.rx.effectiveSamplingRate : obj.tx.effectiveSamplingRate)

"""
Get the current carrier frequency of the radio device
The second parameter (optionnal) speicfies the Rx or Tx board (default : Rx)
"""
getCarrierFreq(obj::AbstractSDR;mode=:rx) = (mode == :rx) ? obj.rx.carrierFreq : obj.tx.carrierFreq
getCarrierFreq(obj::PlutoSDR;mode=:rx) = (mode == :rx) ? obj.rx.effectiveCarrierFreq : obj.tx.effectiveCarrierFreq


"""
Get the current radio gain
The second parameter (optionnal) specifies the Rx or Tx board (default : Rx)
"""
getGain(obj::AbstractSDR;mode=:rx) = (mode == :rx) ? obj.rx.gain : obj.tx.gain
getGain(obj::PlutoSDR;mode=:rx) = AdalmPluto.getGain(obj)


"""
Check if a SDR has already been closed. The falg is true is the SDR ressources have been released and false otherwise.
# --- Syntax
flag = isClosed(radio)
# --- Input parameters
- radio : SDR device
# --- Output parameters
- flag : True is SDR is already closed, false otherwise
"""
isClosed(obj::AbstractSDR) = Bool(obj.tx.released) || Bool(obj.rx.released)
isClosed(obj::PlutoSDR) = Bool(obj.released)


"""
Returns the radio packet size. Each radio backend encapsulates the IQ samples into chunks of data. The `recv` command can be used with any size but it can be more efficient to match the desired size with the one provided by the radio
# --- Syntax
bufferSize = getBufferSize(radio)
# --- Input parameters
- radio : SDR device
# --- Output parameters
bufferSize : Size of radio internal buffer
"""
getBufferSize(obj::AbstractSDR) = obj.rx.packetSize # We get the fields
getBufferSize(obj::PlutoSDR) = obj.rx.buf.C_sample_size # For Pluto this is hidden in the buffer config


Loading