-
Notifications
You must be signed in to change notification settings - Fork 19
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
FD sharing protocol on localhost #82
Changes from 47 commits
9f17ea0
c4d4c45
03539a3
283bbdc
5562d45
3faa07c
8aa655b
bdbc176
4cc25ab
4603388
685245b
43e39d6
011eab6
706eea4
c3f6f3c
204f070
4ce854b
c082504
0fb3d9a
3a3c15a
ffbda08
43d2ced
8c33a71
aa45e40
48b6af8
9fb7537
0878b3b
13a02ab
0a3444a
fa9bfd9
05c8f0c
3c8d502
7fb600a
f87dd85
58a7eb1
53cb90c
77cbf61
0e972c8
cd96e6e
e783d55
d35a4ef
92f17cb
7ab1388
629691f
ec429c3
89a4c13
4e77fc1
741aff6
a0b71c4
fe25ef9
f017c1a
5e89479
62909dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#if defined(__unix__) | ||
|
||
#include <cstring> | ||
#include <cstddef> | ||
#include <fcntl.h> | ||
#include <sys/mman.h> | ||
#include <sys/socket.h> | ||
#include <sys/un.h> | ||
#include <sys/stat.h> | ||
#include <unistd.h> | ||
#include <cassert> | ||
|
||
#include "XLink/XLink.h" | ||
#include "XLink/XLinkPublicDefines.h" | ||
#include "XLink/XLinkLog.h" | ||
|
||
const long MAXIMUM_SHM_SIZE = 4096; | ||
const char *SHARED_MEMORY_NAME = "/xlink_shared_memory_b"; | ||
|
||
XLinkGlobalHandler_t xlinkGlobalHandler = {}; | ||
|
||
int main(int argc, const char** argv){ | ||
xlinkGlobalHandler.protocol = X_LINK_TCP_IP; | ||
|
||
mvLogDefaultLevelSet(MVLOG_ERROR); | ||
|
||
printf("Initializing XLink...\n"); | ||
auto status = XLinkInitialize(&xlinkGlobalHandler); | ||
if(X_LINK_SUCCESS != status) { | ||
printf("Initializing wasn't successful\n"); | ||
return 1; | ||
} | ||
|
||
XLinkHandler_t handler; | ||
handler.devicePath = "127.0.0.1"; | ||
handler.protocol = X_LINK_TCP_IP; | ||
status = XLinkConnect(&handler); | ||
if(X_LINK_SUCCESS != status) { | ||
printf("Connecting wasn't successful\n"); | ||
return 1; | ||
} | ||
|
||
streamPacketDesc_t *packet; | ||
|
||
auto s = XLinkOpenStream(0, "test", 1024); | ||
assert(s != INVALID_STREAM_ID); | ||
|
||
// Read the data packet containing the FD | ||
auto r = XLinkReadData(s, &packet); | ||
assert(r == X_LINK_SUCCESS); | ||
|
||
long receivedFd = packet->fd; | ||
if (receivedFd < 0) { | ||
printf("Not a valid FD, data streamed through message\n"); | ||
return 1; | ||
} | ||
|
||
// Map the shared memory | ||
void *sharedMemAddr = | ||
mmap(NULL, MAXIMUM_SHM_SIZE, PROT_READ, MAP_SHARED, receivedFd, 0); | ||
if (sharedMemAddr == MAP_FAILED) { | ||
perror("mmap"); | ||
return 1; | ||
} | ||
|
||
// Read and print the message from shared memory | ||
printf("Message from Process A: %s\n", static_cast<char *>(sharedMemAddr)); | ||
|
||
const char *normalMessage = "Normal message from Process B"; | ||
auto w = XLinkWriteData(s, (uint8_t*)normalMessage, strlen(normalMessage) + 1); | ||
assert(w == X_LINK_SUCCESS); | ||
|
||
const char *shmName = SHARED_MEMORY_NAME; | ||
long shmFd = shm_open(shmName, O_CREAT | O_RDWR, 0666); | ||
if (shmFd < 0) { | ||
perror("shm_open"); | ||
return 1; | ||
} | ||
|
||
ftruncate(shmFd, MAXIMUM_SHM_SIZE); | ||
|
||
void *addr = mmap(NULL, MAXIMUM_SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmFd, 0); | ||
if (addr == MAP_FAILED) { | ||
perror("mmap"); | ||
close(shmFd); | ||
shm_unlink(shmName); | ||
return 1; | ||
} | ||
|
||
// Write a message to the shared memory | ||
const char *message = "Shared message from Process B!"; | ||
memcpy(addr, message, strlen(message) + 1); | ||
|
||
// Send the FD through the XLinkWriteFd function | ||
w = XLinkWriteFd(s, shmFd); | ||
assert(w == X_LINK_SUCCESS); | ||
|
||
r = XLinkReadData(s, &packet); | ||
assert(w == X_LINK_SUCCESS); | ||
|
||
printf("Message from Process A: %s\n", (char *)(packet->data)); | ||
|
||
|
||
munmap(sharedMemAddr, MAXIMUM_SHM_SIZE); | ||
|
||
munmap(addr, MAXIMUM_SHM_SIZE); | ||
close(shmFd); | ||
unlink(shmName); | ||
|
||
return 0; | ||
} | ||
|
||
#else | ||
|
||
int main() { | ||
return -1; | ||
} | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#if defined(__unix__) | ||
|
||
#include <cstring> | ||
#include <cstddef> | ||
#include <fcntl.h> | ||
#include <sys/mman.h> | ||
#include <sys/socket.h> | ||
#include <sys/un.h> | ||
#include <unistd.h> | ||
#include <cassert> | ||
|
||
#include "XLink/XLink.h" | ||
#include "XLink/XLinkPublicDefines.h" | ||
#include "XLink/XLinkLog.h" | ||
|
||
const long MAXIMUM_SHM_SIZE = 4096; | ||
const char *SHARED_MEMORY_NAME = "/xlink_shared_memory_a"; | ||
|
||
XLinkGlobalHandler_t xlinkGlobalHandler = {}; | ||
|
||
int main(int argc, const char** argv){ | ||
xlinkGlobalHandler.protocol = X_LINK_TCP_IP; | ||
|
||
mvLogDefaultLevelSet(MVLOG_ERROR); | ||
|
||
printf("Initializing XLink...\n"); | ||
auto status = XLinkInitialize(&xlinkGlobalHandler); | ||
if(X_LINK_SUCCESS != status) { | ||
printf("Initializing wasn't successful\n"); | ||
return 1; | ||
} | ||
|
||
XLinkHandler_t handler; | ||
handler.devicePath = "0.0.0.0"; | ||
handler.protocol = X_LINK_TCP_IP; | ||
status = XLinkServerOnly(&handler); | ||
if(X_LINK_SUCCESS != status) { | ||
printf("Connecting wasn't successful\n"); | ||
return 1; | ||
} | ||
|
||
auto s = XLinkOpenStream(0, "test", 1024); | ||
assert(s != INVALID_STREAM_ID); | ||
|
||
const char *shmName = SHARED_MEMORY_NAME; | ||
long shmFd = shm_open(shmName, O_CREAT | O_RDWR, 0666); | ||
if (shmFd < 0) { | ||
perror("shm_open"); | ||
return 1; | ||
} | ||
|
||
ftruncate(shmFd, MAXIMUM_SHM_SIZE); | ||
|
||
void *addr = mmap(NULL, MAXIMUM_SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmFd, 0); | ||
if (addr == MAP_FAILED) { | ||
perror("mmap"); | ||
close(shmFd); | ||
shm_unlink(shmName); | ||
return 1; | ||
} | ||
|
||
// Write a message to the shared memory | ||
const char *message = "Shared message from Process A!"; | ||
memcpy(addr, message, strlen(message) + 1); | ||
|
||
// Send the FD through the XLinkWriteFd function | ||
auto w = XLinkWriteFd(s, shmFd); | ||
assert(w == X_LINK_SUCCESS); | ||
|
||
streamPacketDesc_t *packet; | ||
auto r = XLinkReadData(s, &packet); | ||
assert(w == X_LINK_SUCCESS); | ||
|
||
printf("Message from Process B: %s\n", (char *)(packet->data)); | ||
|
||
// Read the data packet containing the FD | ||
r = XLinkReadData(s, &packet); | ||
assert(r == X_LINK_SUCCESS); | ||
|
||
long receivedFd = packet->fd; | ||
if (receivedFd < 0) { | ||
printf("Not a valid FD, data streamed through message\n"); | ||
return 1; | ||
} | ||
|
||
// Map the shared memory | ||
void *sharedMemAddr = | ||
mmap(NULL, MAXIMUM_SHM_SIZE, PROT_READ, MAP_SHARED, receivedFd, 0); | ||
if (sharedMemAddr == MAP_FAILED) { | ||
perror("mmap"); | ||
return 1; | ||
} | ||
|
||
// Read and print the message from shared memory | ||
printf("Message from Process B: %s\n", static_cast<char *>(sharedMemAddr)); | ||
|
||
const char *normalMessage = "Normal message from Process A"; | ||
w = XLinkWriteData(s, (uint8_t*)normalMessage, strlen(normalMessage) + 1); | ||
assert(w == X_LINK_SUCCESS); | ||
|
||
munmap(sharedMemAddr, MAXIMUM_SHM_SIZE); | ||
|
||
munmap(addr, MAXIMUM_SHM_SIZE); | ||
close(shmFd); | ||
unlink(shmName); | ||
|
||
return 0; | ||
} | ||
|
||
#else | ||
|
||
int main() { | ||
return -1; | ||
} | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,35 +83,42 @@ typedef enum | |
{ | ||
/*USB-X_LINK_PCIE related events*/ | ||
XLINK_WRITE_REQ, | ||
XLINK_WRITE_FD_REQ, // only for the shared mem protocol | ||
XLINK_READ_REQ, | ||
XLINK_READ_REL_REQ, | ||
XLINK_READ_REL_SPEC_REQ, | ||
XLINK_CREATE_STREAM_REQ, | ||
XLINK_CLOSE_STREAM_REQ, | ||
XLINK_PING_REQ, | ||
XLINK_RESET_REQ, | ||
|
||
XLINK_REQUEST_LAST, | ||
//note that is important to separate request and response | ||
XLINK_WRITE_RESP, | ||
XLINK_WRITE_FD_RESP, // only for the shared mem protocol | ||
XLINK_READ_RESP, | ||
XLINK_READ_REL_RESP, | ||
XLINK_READ_REL_SPEC_RESP, | ||
XLINK_CREATE_STREAM_RESP, | ||
XLINK_CLOSE_STREAM_RESP, | ||
XLINK_PING_RESP, | ||
XLINK_RESET_RESP, | ||
|
||
XLINK_RESP_LAST, | ||
|
||
/*X_LINK_IPC related events*/ | ||
IPC_WRITE_REQ, | ||
IPC_WRITE_FD_REQ, | ||
IPC_READ_REQ, | ||
IPC_CREATE_STREAM_REQ, | ||
IPC_CLOSE_STREAM_REQ, | ||
|
||
// | ||
IPC_WRITE_RESP, | ||
IPC_WRITE_FD_RESP, | ||
IPC_READ_RESP, | ||
IPC_CREATE_STREAM_RESP, | ||
IPC_CLOSE_STREAM_RESP, | ||
XLINK_READ_REL_SPEC_REQ, | ||
XLINK_READ_REL_SPEC_RESP, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why removed? Also, all new events MUST GO to the end of enum, otherwise backward compatibility is broken There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I moved them before XLINK_LAST_REQ and XLINK_LAST_RESP, otherwise they will cause this assert to fail:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm - do we need a special type of an event? So lets try to either:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Side note: |
||
} xLinkEventType_t; | ||
|
||
typedef enum | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of doing "if unix" in source code, conditionally add these as examples IFF running on UNIX
Apply this elsewhere as well where needed (where we ifdef out a whole file - is better to make it "platform specific compiliation wise")