Open vivianchiong opened 1 year ago
Does my problem statement fall under "Shared Code Emulation" / "Shared Code Waveform Stack" capability mentioned in the Wiki?
Thanks again!
Yes.Kaushik B PatelAdjacent Link LLCCEO, Director of EngineeringOn Oct 12, 2023, at 2:39 PM, Vivian Chiong @.***> wrote: Does my problem statement fall under "Shared Code Emulation" / "Shared Code Waveform Stack" capability mentioned in the Wiki? Thanks again!
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>
Thanks for your response, I really appreciate it. So it seems that we need to put our MAC layer model inside a Shared Code Waveform instance, and implement the "Modem Hardware Abstraction Layer" and "Transport API"? in the left diagram. Then, whatever requirements we need from EMANE that is not encapsulated in our MAC layer model would go into some custom Radio Model and/or the PHY layer. Is my understanding correct?
I see there is https://github.com/adjacentlink/emane-model-lte and https://github.com/adjacentlink/srsRAN-emane mentioned in the Wiki, but I also found the repo https://github.com/adjacentlink/srsLTE-emane. What is the difference between srsRAN-emane and srsLTE-emane, and what do you think is the better reference in my case?
Specifically, I did not find too many materials on the "Modem Hardware Abstraction Layer" in EMANE so I'm not sure where to start.
Take a look at the emane-emedded-example. The emane-emedded-example is a simple example for embedding the emulator within your waveform stack, which is how we do shared code modeling. It is not represented in the diagram you referenced but it is the better option.
You can use any mechanism you like to communicate with your radio model, just keep in mind that emane API callbacks (functor queue) happen on the emulator's radio model thread -- so depending on your approach you may need to use synchronization objects. Consider using the FileDescriptorService as a message passing based alternative.
To use FileDescriptorService, I need to be able to call setFileDescriptorServiceProvider(FileDescriptorServiceProvider::instance())
on pPlatformService_
in the Embedded::RadioModel, but since pPlatformService_
is type PlatformServiceProvider
, it doesn't have the setFileDescriptorServiceProvider
method in its interface.
I tried to dynamic_cast
pPlatformService_
to EMANE::PlatformService
but I had no success. Would I have to modify and re-compile libemane buildMACLayer_i to force an instantiation of FileDescriptorService in my Embedded::RadioModel
? Or is it possible to set the FileDescriptorService directly within the emane-emedded-example?
Thank you for your help!
Thank you! That worked for me and I was able to register a socket/file descriptor at the end of the Embedded::RadioModel::postStart() method, and get my callback testFileDescriptor
(which accepts no parameters, just prints a single log message out) triggered like so
pPlatformService_->fileDescriptorService()
.addFileDescriptor(fd_,
EMANE::FileDescriptorServiceProvider::DescriptorType::READ,
std::bind(&Embedded::RadioModel::testFileDescriptor,
this));
However, my testFileDescriptor
is printing out an extreme number of times, even though I only send a single message over the registered socket/file descriptor in the main emane-embedded-example.cc
file here:
std::string str = "Hello World!";
if (sock.send(str) != ssize_t(str.length())) {
std::cerr << "Error writing to the UDP socket: " << sock.last_error_str() << std::endl;
} else {
std::cout << "Sent message!" << std::endl;
}
Am I using the FileDescriptorService
incorrectly? I have read up on the NEMQueuedLayer
code and the basics of epoll
, but I couldn't quite diagnose why the callback is being triggered so repeatedly. Could it be the length/content of the "Hello World!" message?
Please let me know if I should move my question to the emane-embedded-example
repo instead. Again, thank you so much for your help thus far, I truly appreciate it!
Are you reading the data from fd_ in testFileDescriptor()?
Ah, I am not. This is my testFileDescriptor() method body:
It sounds to me that I should be reading from fd_
inside the method body here, to clear the Hello World!
message from the socket right? It would make sense for it to constantly trigger if the socket always has data that the FileDescriptorService wants to read!
Would you recommend using a TCP or UDP socket to "register a socket with your radio model to exchange data and control with upper stack component(s)" #227 ? In the emane-embedded-example
main
function, I have been using a UDP socket from sockpp to send the "Hello World!" message across, which seems to work since my testFileDescriptor()
method triggers as I previously showed. But I have not been able to read the received message bytes from fd_
in testFileDescriptor()
without getting a ECONNREFUSED
error.
void Embedded::RadioModel::testFileDescriptor()
char buf[20];
ssize_t bytes = read(fd_, buf, sizeof(buf));
if (bytes == -1) {
perror("Error occurred while opening file.\n"); // Connection refused error
Should I be creating another socket instance, or passing a clone of the socket to my Embedded::RadioModel
? I checked /proc/PID/fd
for the file descriptor, and it is there, so I'm not sure why Embedded::RadioModel
can't read from it.
Typically when you are making a shared code model there is already waveform interfaces that exist between components. The goal would be to use the same protocol/mechanism that is used to communicate with the waveform modem subsystem. It does not have to be socket based, since you are embedding the radio model but then you have to be aware of the threading model used in emane. When using message based systems, the recommendation is to integrate with the FileDescriptorService to avoid having to synchronize data access between threads -- the ones you may need to directly create or that are indirectly created by the communication library you are using.
Every radio model has a dedicated thread that works off an API queue, where each API method (virtual function you provide implementation for in your radio model along with timer and file descriptor callbacks) is executed.
The FileDescriptorService provides the ability to register a file descriptor, in this case a socket, with the API queue. There are many tutorials and guides on socket programming with information that would be directly applicable to their use with the FileDescriptorService.
Hello,
I have a question that I could not quite find the answer to on other issues.
I have a MAC layer model (C++ code) that I would like to test in the EMANE environment for the same reasons as others – to benefit from the framework’s scalability and flexibility of large-scale network emulation and test our design’s performance in different scenarios before needing to buy real radio hardware. This model is based on TDMA, and I’ve modified the open-source TDMA radio model slightly and configured the FrameworkPHY layer to match our own physical layer model’s behavior (thanks to your help!). But beyond this, we want to plugin in our MAC layer model into something that can run in EMANE nodes without conflating our MAC layer model’s API with EMANE’s radio model plugin API.
I would like to be able to treat our MAC layer model of code like a black box that does, indeed, generally do what EMANE radio models typically do (e.g. queuing, fragmentation/assembly, TDMA scheduling, etc.) but come time for the model to interact with higher layers (e.g. sending received packets up to the Virtual Transport to reach the user) or lower layers (e.g. sending packets down to the FrameworkPHY for OTA transmission), our model would use a defined API to speak to those surrounding layers for upstream/downstream data/control functionalities.
The reason for us is because we don’t want to over-rely on the EMANE framework or couple our software with EMANE-only constructs resulting in breaking our implementation when we put the same black box MAC layer model onto real radios. However, we also don’t want to have to re-solve challenges that you and other developers at Adjacent Link have already solved when writing the open-source TDMA radio model.
How can we integrate our model with EMANE? (I imagine we can’t just write the name of our MAC layer model's lib file into an EMANE XML, since it would need to adhere to EMANE’s APIs.) I have thought of a few potential solution angles and listed them below. Any insights or recommendations on what solution(s) are possible/feasible/ideal would be greatly appreciated!
Thank you so much!