Skip to content

Commit

Permalink
First release of the dApp framework
Browse files Browse the repository at this point in the history
  • Loading branch information
Thecave3 authored Jan 27, 2025
2 parents 473e19f + 8658804 commit 8f7f6e3
Show file tree
Hide file tree
Showing 35 changed files with 2,542 additions and 85 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/mirror.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Mirror to Public Repository

on:
push:
branches:
- main

jobs:
mirror:
runs-on: ubuntu-latest
env:
MIRROR_PUSH: ${{ secrets.MIRROR_PUSH }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: '0' # Ensures the entire history is fetched

- name: Set up SSH Key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan github.com >> ~/.ssh/known_hosts
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}

- name: Conditional Push
run: |
if [ "${{ env.MIRROR_PUSH }}" == "true" ]; then
echo "MIRROR_PUSH is set to true, pushing to public repository..."
git remote add public [email protected]:wineslab/dApp-library.git
git push public main:main --force
else
echo "MIRROR_PUSH is not set to true, no action taken."
fi
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,25 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

e3protocol/asn1c_output/
e3protocol/asn1c_compiled_output/
e3protocol/client/client

# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
.idea/
.vscode/
e3protocol/server/e3_wrap.c
e3protocol/server/e3.py
e3protocol/sctp_traffic.pcap
logs/**
dapp_profile
profile_output.txt
e3protocol/client/test
8 changes: 0 additions & 8 deletions .idea/.gitignore

This file was deleted.

60 changes: 59 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,59 @@
# spear-dApp
# spear-dApp

password of the colosseum container of dApp is `spear`

## Usage

### Building OAI
```
./build_oai -w USRP --ninja --gNB --build-e3
```

### System configuration for OTA

This part of the guide is inteded to be only if running with `--ota` thus with UDS sockets
If we need the dApp to run in a different user than OAI (e.g., $USER vs root) we need to create a specific unix users group called `dapp` and we assign root and user to this group to enable shared UDS through a dedicated foldert:
```
sudo groupadd dapp
sudo usermod -aG dapp root
sudo usermod -aG dapp $USER
# check the groups
groups root $USER
```

Folder creation (path is not important, but it should be the same in OAI and the dApp)

```
mkdir -p /tmp/dapps
sudo chown :dapp /tmp/dapps
sudo chmod g+ws /tmp/dapps
```

If the dApp is not run from the root user, a new folder should be included called `logs`
```
# In the root of the project if you're following the dApp kickoff
mkdir logs
```

### Configuration for OAI
- Make sure that do_SRS flag is set to 0

We support two different configuration for OTA and colosseum.

### dApp kickoff

OAI should start _before_ running the dApp

```python
python3 src/dapp/dapp.py
```

There are many possible arguments:
- `ota` bool (false): If true, use the OAI and spectrum configurations for OTA else use the ones of Colosseum
- `control` bool (false): If set to true, performs the PRB masking
- `energy-gui` bool (false): If set to true, creates and show the energy spectrum
- `iq-plotter-gui` bool (false): If set to true, creates and show the sensed spectrum
- `save-iqs` bool (false): Specify if this is data collection run or not. In the first case I/Q samples will be saved
- `profile` bool (false): Enable profiling with cProfile
- `timed` bool (false): Run with a 5-minute time limit
65 changes: 65 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#==================================================================================
# Copyright (c) 2024 Northeastern University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#==================================================================================
FROM ubuntu:22.04

# Set timezone
ENV TZ=America/New_York
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Install required packages
RUN apt-get update && apt-get install -y htop build-essential cmake automake libtool bison \
flex git python3 python3-dev swig libsctp-dev

# Set the working directory
WORKDIR /workspace

# Clone the asn1c repository and build it
RUN git clone https://github.com/nokia/asn1c
WORKDIR /workspace/asn1c

RUN test -f configure || autoreconf -iv
RUN ./configure
RUN make
RUN make install

# Set the working directory for building the project
WORKDIR /workspace

# Copy the ASN.1 file, SWIG interface file, and C client source code into the container
COPY e3.asn /workspace/
COPY e3.i /workspace/
COPY client.c /workspace/

# Create an output directory for the compiled files
RUN mkdir -p /workspace/output

# Compile the ASN.1 files
RUN mkdir -p /workspace/output/asn1c_output && \
asn1c -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D /workspace/output/asn1c_output e3.asn

# Compile the C code for ASN.1
RUN gcc -c -o /workspace/output/asn1c_output/*.o /workspace/output/asn1c_output/*.c

# Generate the SWIG wrapper
RUN swig -python -o /workspace/output/e3_wrap.c e3.i

# Compile the SWIG wrapper and ASN.1 C code into a shared object
RUN gcc -shared -o /workspace/output/_e3.so /workspace/output/e3_wrap.c /workspace/output/asn1c_output/*.o -I/usr/include/python3.8

# Compile the C client
RUN gcc -o /workspace/output/client client.c /workspace/output/asn1c_output/*.o -lsctp

CMD ["/bin/bash"]
6 changes: 6 additions & 0 deletions docker/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

echo "this file and the docker is not currently working and may be not needed"
# docker build -t e3_project .
# docker run -it -v $(pwd)/output:/workspace/output e3_project

128 changes: 128 additions & 0 deletions docs/dapp_uml.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
@startuml
!theme mars
skinparam defaultFontSize 20
skinparam classFontSize 22
skinparam backgroundColor transparent
left to right direction
skinparam linetype ortho
!define AbstractClass class
hide empty members
hide circles

class E3Interface {
-- Attributes --
- _instance : E3Interface
- _lock : threading.Lock
- callbacks : list
- stop_event : multiprocessing.Event
- e3_connector : E3Connector
-- Methods --
__new__()
__init__(link: str, transport: str, profile: bool)
+ add_callback(callback)
+ remove_callback(callback)
+ terminate_connections()
- _handle_incoming_data(data)
- schedule_control(payload: bytes)
- schedule_report(payload: bytes)
}

AbstractClass SpectrumSharingDApp {
-- Attributes --
- counter : int
- limit_per_file : int
- FFT_SIZE : int
- Noise_floor_threshold : int
- First_carrier_offset : int
- Average_over_frames : int
- Num_car_prb : int
- prb_thrs : int
-- Methods --
__init__(ota: bool, save_iqs: bool, control: bool, **kwargs)
+ get_iqs_from_ran(data)
+ stop()
}


AbstractClass DApp {
-- Attributes --
- e3_interface : E3Interface
- control : bool
-- Methods --
__init__(ota: bool, save_iqs: bool, control: bool, **kwargs)
+ setup_connection()
+ control_loop()
+ stop()
}

class E3LinkLayer {
-- Enumeration --
+ ZMQ = "zmq"
+ POSIX = "posix"
-- Methods --
+ from_string(link_layer_str: str)
}

class E3TransportLayer {
-- Enumeration --
+ SCTP = "sctp"
+ TCP = "tcp"
+ IPC = "ipc"
-- Methods --
+ from_string(transport_layer_str: str)
}

AbstractClass E3Connector {
-- Attributes --
- VALID_CONFIGURATIONS : list
- E3_IPC_SETUP_PATH : str
- E3_IPC_SOCKET_PATH : str
- DAPP_IPC_SOCKET_PATH : str
-- Methods --
+ setup_connector(link_layer: str, transport_layer: str)
+ send_setup_request(payload: bytes)
+ setup_inbound_connection()
+ setup_outbound_connection()
+ send(payload: bytes)
+ receive() : bytes
+ dispose()
}

class ZMQConnector {
-- Attributes --
- setup_context : zmq.Context
- inbound_context : zmq.Context
- outbound_context : zmq.Context
- transport_layer : E3TransportLayer
-- Methods --
+ __init__(transport_layer: E3TransportLayer)
+ send_setup_request(payload: bytes)
+ setup_inbound_connection()
+ setup_outbound_connection()
+ send(payload: bytes)
+ receive() : bytes
+ dispose()
}

class POSIXConnector {
-- Attributes --
- transport_layer : E3TransportLayer
- CHUNK_SIZE : int
-- Methods --
+ __init__(transport_layer: E3TransportLayer)
+ send_setup_request(payload: bytes)
+ setup_inbound_connection()
+ setup_outbound_connection()
+ send(payload: bytes)
+ receive() : bytes
+ dispose()
}

DApp --> E3Interface
DApp <|-- SpectrumSharingDApp
E3Connector <|-- ZMQConnector
E3Connector <|-- POSIXConnector
E3Interface --* E3Connector
E3Connector --> E3LinkLayer
E3Connector --> E3TransportLayer
@enduml
54 changes: 54 additions & 0 deletions docs/gui_uml.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
@startuml
!theme mars
skinparam backgroundColor transparent
left to right direction
skinparam linetype ortho
!define AbstractClass class
hide empty members
hide circles

class EnergyPlotter {
-- Attributes --
- FFT_SIZE : int
- bw : float
- center_freq : float
- fig, ax, line1 : matplotlib.pyplot objects
-- Methods --
+ __init__(fft_size: int, bw: float, center_freq: float)
+ initialize_plot(fft_size: int)
+ update_plot(new_data)
+ process_iq_data(abs_iq_av_db)
}

class IQPlotter {
-- Attributes --
- buffer_size : int
- iq_size : int
- buffer : np.ndarray
- sampling_threshold : int
- fig, ax, img : matplotlib.pyplot objects
-- Methods --
+ __init__(buffer_size: int, iq_size: int, bw: float, center_freq: float)
+ initialize_plot(iq_shape)
+ update_plot(new_data)
+ process_iq_data(iq_data)
}

class DemoGui {
-- Attributes --
- BUFFER_SIZE : int
- iq_size : int
- bw : float
- center_freq : float
- sampling_threshold : int
- socketio : SocketIO
-- Methods --
+ __init__(buffer_size: int, iq_size: int, bw: float, center_freq: float)
+ _initialize_plot()
+ process_iq_data(message)
+ stop()
}

DemoGui --> IQPlotter : "contains"
DemoGui --> EnergyPlotter : "contains"
@enduml
Loading

0 comments on commit 8f7f6e3

Please sign in to comment.