summaryrefslogtreecommitdiff
path: root/lib/avtp_pipeline/platform/Linux/avdecc_msg
diff options
context:
space:
mode:
Diffstat (limited to 'lib/avtp_pipeline/platform/Linux/avdecc_msg')
-rw-r--r--lib/avtp_pipeline/platform/Linux/avdecc_msg/CMakeLists.txt2
-rw-r--r--lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_client_osal.c181
-rw-r--r--lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_osal.h64
-rw-r--r--lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_server_osal.c271
4 files changed, 518 insertions, 0 deletions
diff --git a/lib/avtp_pipeline/platform/Linux/avdecc_msg/CMakeLists.txt b/lib/avtp_pipeline/platform/Linux/avdecc_msg/CMakeLists.txt
new file mode 100644
index 00000000..139597f9
--- /dev/null
+++ b/lib/avtp_pipeline/platform/Linux/avdecc_msg/CMakeLists.txt
@@ -0,0 +1,2 @@
+
+
diff --git a/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_client_osal.c b/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_client_osal.c
new file mode 100644
index 00000000..04de29e0
--- /dev/null
+++ b/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_client_osal.c
@@ -0,0 +1,181 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+#ifndef OPENAVB_AVDECC_MSG_CLIENT_OSAL_C
+#define OPENAVB_AVDECC_MSG_CLIENT_OSAL_C
+
+static void socketClose(int socketHandle)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+ if (socketHandle != AVB_AVDECC_MSG_HANDLE_INVALID) {
+ close(socketHandle);
+ }
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+}
+
+static bool openavbAvdeccMsgClntSendToServer(int socketHandle, openavbAvdeccMessage_t *msg)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+
+ if (!msg || socketHandle == AVB_AVDECC_MSG_HANDLE_INVALID) {
+ AVB_LOG_ERROR("Client send: invalid argument passed");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return FALSE;
+ }
+
+ ssize_t nWrite = write(socketHandle, msg, OPENAVB_AVDECC_MSG_LEN);
+ AVB_LOGF_VERBOSE("Sent message, len=%zu, nWrite=%zu", OPENAVB_AVDECC_MSG_LEN, nWrite);
+
+ if (nWrite < OPENAVB_AVDECC_MSG_LEN) {
+ if (nWrite < 0) {
+ AVB_LOGF_ERROR("Client failed to write socket: %s", strerror(errno));
+ }
+ else if (nWrite == 0) {
+ AVB_LOG_ERROR("Client send: socket closed unexpectedly");
+ }
+ else {
+ AVB_LOG_ERROR("Client send: short write");
+ }
+ socketClose(socketHandle);
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return FALSE;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return TRUE;
+}
+
+int openavbAvdeccMsgClntOpenSrvrConnection(void)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+ struct sockaddr_un server;
+ server.sun_family = AF_UNIX;
+ snprintf(server.sun_path, UNIX_PATH_MAX, AVB_AVDECC_MSG_UNIX_PATH);
+
+ int h = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (h < 0) {
+ AVB_LOGF_ERROR("Failed to open socket: %s", strerror(errno));
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return AVB_AVDECC_MSG_HANDLE_INVALID;
+ }
+
+ AVB_LOGF_DEBUG("Connecting to %s", server.sun_path);
+ int rslt = connect(h, (struct sockaddr*)&server, sizeof(struct sockaddr_un));
+ if (rslt < 0) {
+ AVB_LOGF_DEBUG("Failed to connect socket: %s", strerror(errno));
+ socketClose(h);
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return AVB_AVDECC_MSG_HANDLE_INVALID;
+ }
+
+ AVB_LOG_DEBUG("Connected to AVDECC Msg");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return h;
+}
+
+void openavbAvdeccMsgClntCloseSrvrConnection(int socketHandle)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+ socketClose(socketHandle);
+ AVB_LOG_DEBUG("Closed connection to AVDECC Msg");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+}
+
+bool openavbAvdeccMsgClntService(int socketHandle, int timeout)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+ bool rc = FALSE;
+
+ if (socketHandle == AVB_AVDECC_MSG_HANDLE_INVALID) {
+ AVB_LOG_ERROR("Client service: invalid socket");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return FALSE;
+ }
+
+ struct pollfd fds[1];
+ memset(fds, 0, sizeof(struct pollfd));
+ fds[0].fd = socketHandle;
+ fds[0].events = POLLIN;
+
+ AVB_LOG_VERBOSE("Waiting for event...");
+ int pRet = poll(fds, 1, timeout);
+
+ if (pRet == 0) {
+ AVB_LOG_VERBOSE("Poll timeout");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return TRUE;
+ }
+ else if (pRet < 0) {
+ if (errno == EINTR) {
+ AVB_LOG_VERBOSE("Poll interrupted");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return TRUE;
+ }
+ else {
+ AVB_LOGF_ERROR("Poll error: %s", strerror(errno));
+ }
+ }
+ else {
+ AVB_LOGF_DEBUG("Poll returned %d events", pRet);
+ // only one fd, so it's readable.
+ openavbAvdeccMessage_t msgBuf;
+ memset(&msgBuf, 0, OPENAVB_AVDECC_MSG_LEN);
+ ssize_t nRead = read(socketHandle, &msgBuf, OPENAVB_AVDECC_MSG_LEN);
+
+ if (nRead < OPENAVB_AVDECC_MSG_LEN) {
+ // sock closed
+ if (nRead == 0) {
+ AVB_LOG_ERROR("Socket closed unexpectedly");
+ }
+ else if (nRead < 0) {
+ AVB_LOGF_ERROR("Socket read error: %s", strerror(errno));
+ }
+ else {
+ AVB_LOG_ERROR("Socket read to short");
+ }
+ socketClose(socketHandle);
+ }
+ else {
+ // got a message
+ if (openavbAvdeccMsgClntReceiveFromServer(socketHandle, &msgBuf)) {
+ rc = TRUE;
+ }
+ else {
+ AVB_LOG_ERROR("Invalid message received");
+ socketClose(socketHandle);
+ }
+ }
+ }
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return rc;
+}
+
+#endif // OPENAVB_AVDECC_MSG_CLIENT_OSAL_C
diff --git a/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_osal.h b/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_osal.h
new file mode 100644
index 00000000..b68ea38d
--- /dev/null
+++ b/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_osal.h
@@ -0,0 +1,64 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+#ifndef OSAL_AVDECC_MSG_H
+#define OSAL_AVDECC_MSG_H
+
+// should only be included from openavb_avdecc_msg.h
+
+#include <linux/un.h>
+#include <net/if.h>
+#include <unistd.h>
+#include <signal.h>
+
+typedef struct {
+ openavbAvdeccMsgType_t type;
+ AVBStreamID_t streamID;
+ union {
+ // Client-to-Server messages
+ openavbAvdeccMsgParams_VersionRequest_t versionRequest;
+ openavbAvdeccMsgParams_ClientInitIdentify_t clientInitIdentify;
+ openavbAvdeccMsgParams_C2S_TalkerStreamID_t c2sTalkerStreamID;
+ openavbAvdeccMsgParams_ClientChangeNotification_t clientChangeNotification;
+
+ // Server-to-Client messages
+ openavbAvdeccMsgParams_VersionCallback_t versionCallback;
+ openavbAvdeccMsgParams_ListenerStreamID_t listenerStreamID;
+ openavbAvdeccMsgParams_S2C_TalkerStreamID_t s2cTalkerStreamID;
+ openavbAvdeccMsgParams_ClientChangeRequest_t clientChangeRequest;
+ } params;
+} openavbAvdeccMessage_t;
+
+
+bool startAvdeccMsg(int mode, int ifindex, const char* ifname, unsigned mtu, unsigned link_kbit, unsigned nsr_kbit);
+void stopAvdeccMsg();
+
+#endif // OSAL_AVDECC_MSG_H
diff --git a/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_server_osal.c b/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_server_osal.c
new file mode 100644
index 00000000..e73b9701
--- /dev/null
+++ b/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_server_osal.c
@@ -0,0 +1,271 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+#ifndef OPENAVB_AVDECC_MSG_SERVER_OSAL_C
+#define OPENAVB_AVDECC_MSG_SERVER_OSAL_C
+
+#define AVB_AVDECC_LISTEN_FDS 0 // first fds, was last MAX_AVB_STREAMS
+#define SOCK_INVALID (-1)
+#define POLL_FD_COUNT ((MAX_AVB_STREAMS) + 1)
+
+static int lsock = SOCK_INVALID;
+static struct pollfd fds[POLL_FD_COUNT];
+static struct sockaddr_un serverAddr;
+
+static void socketClose(int h)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+
+ if (h < 0 || h >= POLL_FD_COUNT) {
+ AVB_LOG_ERROR("Closing socket; invalid handle");
+ }
+ else {
+ if (h != AVB_AVDECC_LISTEN_FDS) {
+ openavbAvdeccMsgSrvrCloseClientConnection(h);
+ }
+ close(fds[h].fd);
+ fds[h].fd = SOCK_INVALID;
+ fds[h].events = 0;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+}
+
+static bool openavbAvdeccMsgSrvrSendToClient(int h, openavbAvdeccMessage_t *msg)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+
+ if (h < 0 || h >= POLL_FD_COUNT) {
+ AVB_LOG_ERROR("Sending message; invalid handle");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return FALSE;
+ }
+ if (!msg) {
+ AVB_LOG_ERROR("Sending message; invalid argument passed");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return FALSE;
+ }
+
+ int csock = fds[h].fd;
+ if (csock == SOCK_INVALID) {
+ AVB_LOG_ERROR("Socket closed unexpectedly");
+ return FALSE;
+ }
+
+ ssize_t nWrite = write(csock, msg, OPENAVB_AVDECC_MSG_LEN);
+ AVB_LOGF_VERBOSE("Sent message, len=%zu, nWrite=%zu", OPENAVB_AVDECC_MSG_LEN, nWrite);
+ if (nWrite < OPENAVB_AVDECC_MSG_LEN) {
+ if (nWrite < 0) {
+ AVB_LOGF_ERROR("Failed to write socket: %s", strerror(errno));
+ }
+ else if (nWrite == 0) {
+ AVB_LOG_ERROR("Socket closed unexpectedly");
+ }
+ else {
+ AVB_LOG_ERROR("Socket write too short");
+ }
+ socketClose(h);
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+ return FALSE;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return TRUE;
+}
+
+bool openavbAvdeccMsgServerOpen(void)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+ int i;
+
+ // Perform the base initialization.
+ openavbAvdeccMsgInitialize();
+
+ for (i=0; i < POLL_FD_COUNT; i++) {
+ fds[i].fd = SOCK_INVALID;
+ fds[i].events = 0;
+ }
+
+ lsock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (lsock < 0) {
+ AVB_LOGF_ERROR("Failed to open socket: %s", strerror(errno));
+ goto error;
+ }
+ // serverAddr is file static
+ serverAddr.sun_family = AF_UNIX;
+ snprintf(serverAddr.sun_path, UNIX_PATH_MAX, AVB_AVDECC_MSG_UNIX_PATH);
+
+ // try remove old socket
+ if (unlink(serverAddr.sun_path) == -1 && errno != ENOENT) {
+ AVB_LOGF_ERROR("Failed to remove %s: %s", serverAddr.sun_path, strerror(errno));
+ }
+
+ int rslt = bind(lsock, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr_un));
+ if (rslt != 0) {
+ AVB_LOGF_ERROR("Failed to create %s: %s", serverAddr.sun_path, strerror(errno));
+ AVB_LOG_WARNING("** If AVDECC Msg process crashed, run the cleanup script **");
+ goto error;
+ }
+
+ rslt = listen(lsock, 5);
+ if (rslt != 0) {
+ AVB_LOGF_ERROR("Failed to listen on socket: %s", strerror(errno));
+ goto error;
+ }
+ AVB_LOGF_DEBUG("Listening on socket: %s", serverAddr.sun_path);
+
+ fds[AVB_AVDECC_LISTEN_FDS].fd = lsock;
+ fds[AVB_AVDECC_LISTEN_FDS].events = POLLIN;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return TRUE;
+
+ error:
+ if (lsock >= 0) {
+ close(lsock);
+ lsock = -1;
+ }
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return FALSE;
+}
+
+void openavbAvdeccMsgSrvrService(void)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+ struct sockaddr_un addrClient;
+ socklen_t lenAddr;
+ int i, j;
+ int csock;
+
+ int nfds = POLL_FD_COUNT;
+ int pRet;
+
+ AVB_LOG_VERBOSE("Waiting for event...");
+ pRet = poll(fds, nfds, 1000);
+
+ if (pRet == 0) {
+ AVB_LOG_VERBOSE("poll timeout");
+ }
+ else if (pRet < 0) {
+ if (errno == EINTR) {
+ AVB_LOG_VERBOSE("Poll interrupted");
+ }
+ else {
+ AVB_LOGF_ERROR("Poll error: %s", strerror(errno));
+ }
+ }
+ else {
+ AVB_LOGF_VERBOSE("Poll returned %d events", pRet);
+ for (i=0; i<nfds; i++) {
+ if (fds[i].revents != 0) {
+ AVB_LOGF_VERBOSE("%d sock=%d, event=0x%x, revent=0x%x", i, fds[i].fd, fds[i].events, fds[i].revents);
+
+ if (i == AVB_AVDECC_LISTEN_FDS) {
+ // listen sock - indicates new connection from client
+ lenAddr = sizeof(addrClient);
+ csock = accept(lsock, (struct sockaddr*)&addrClient, &lenAddr);
+ if (csock < 0) {
+ AVB_LOGF_ERROR("Failed to accept connection: %s", strerror(errno));
+ }
+ else {
+ for (j = 0; j < POLL_FD_COUNT; j++) {
+ if (fds[j].fd == SOCK_INVALID) {
+ fds[j].fd = csock;
+ fds[j].events = POLLIN;
+ break;
+ }
+ }
+ if (j >= POLL_FD_COUNT) {
+ AVB_LOG_ERROR("Too many client connections");
+ close(csock);
+ }
+ }
+
+ AVB_LOG_INFO("New AVDECC Msg client connection detected");
+ }
+ else {
+ csock = fds[i].fd;
+ openavbAvdeccMessage_t msgBuf;
+ memset(&msgBuf, 0, OPENAVB_AVDECC_MSG_LEN);
+ ssize_t nRead = read(csock, &msgBuf, OPENAVB_AVDECC_MSG_LEN);
+ AVB_LOGF_VERBOSE("Socket read h=%d,fd=%d: read=%zu, expect=%zu", i, csock, nRead, OPENAVB_AVDECC_MSG_LEN);
+
+ if (nRead < OPENAVB_AVDECC_MSG_LEN) {
+ // sock closed
+ if (nRead == 0) {
+ AVB_LOGF_DEBUG("Socket closed, h=%d", i);
+ }
+ else if (nRead < 0) {
+ AVB_LOGF_ERROR("Socket read, h=%d: %s", i, strerror(errno));
+ }
+ else {
+ AVB_LOGF_ERROR("Short read, h=%d", i);
+ }
+ socketClose(i);
+ }
+ else {
+ // got a message
+ if (!openavbAvdeccMsgSrvrReceiveFromClient(i, &msgBuf)) {
+ AVB_LOG_ERROR("Failed to handle message");
+ socketClose(i);
+ }
+ }
+ }
+ }
+ }
+ }
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+}
+
+void openavbAvdeccMsgServerClose(void)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+ int i;
+ for (i = 0; i < POLL_FD_COUNT; i++) {
+ if (fds[i].fd != SOCK_INVALID) {
+ socketClose(i);
+ }
+ }
+ if (lsock != SOCK_INVALID) {
+ close(lsock);
+ }
+
+ if (unlink(serverAddr.sun_path) != 0) {
+ AVB_LOGF_ERROR("Failed to unlink %s: %s", serverAddr.sun_path, strerror(errno));
+ }
+
+ // Perform the base cleanup.
+ openavbAvdeccMsgCleanup();
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+}
+
+#endif // OPENAVB_AVDECC_MSG_SERVER_OSAL_C