summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4d145eb)
raw | patch | inline | side by side (parent: 4d145eb)
author | Justin Sobota <jsobota@ti.com> | |
Fri, 7 Mar 2014 23:48:16 +0000 (18:48 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Fri, 7 Mar 2014 23:48:16 +0000 (18:48 -0500) |
docs/ReleaseNotes_RM.doc | patch | blob | history | |
docs/ReleaseNotes_RM.pdf | patch | blob | history | |
rm.h | patch | blob | history | |
rm_transport.h | patch | blob | history | |
src/rm_transport.c | patch | blob | history | |
test/k2h/armv7/linux/build/makefile | patch | blob | history | |
test/k2h/armv7/linux/rm_server.c | patch | blob | history | |
test/k2h/armv7/linux/rm_server_osal.c | [new file with mode: 0644] | patch | blob |
test/k2h/armv7/linux/serverlogutil.h | [new file with mode: 0644] | patch | blob |
index 8541068ea880b1598989718323f4d913fdfeddbc..ce54c6b372b2ab6ef6de345d257186059718c170 100644 (file)
Binary files a/docs/ReleaseNotes_RM.doc and b/docs/ReleaseNotes_RM.doc differ
Binary files a/docs/ReleaseNotes_RM.doc and b/docs/ReleaseNotes_RM.doc differ
index 8ac3f92c92653405236ac80387ff885ec99a9211..a01a87b9dcbedd9e669144abcba56165d92516e0 100644 (file)
Binary files a/docs/ReleaseNotes_RM.pdf and b/docs/ReleaseNotes_RM.pdf differ
Binary files a/docs/ReleaseNotes_RM.pdf and b/docs/ReleaseNotes_RM.pdf differ
index b2d799f42356c490a018ef501e89e0dfd4e3ad6c..1b897a751f1f7d651ca6db1ebe657e15069dabec 100644 (file)
--- a/rm.h
+++ b/rm.h
#define RM_ERROR_LOST_RESOURCES_ON_CD RM_ERROR_BASE-49
/** The service source inst name and RM packet source instance names are not available
* for the given type of RM packet */
-#define RM_ERROR_PKT_AND_SERVICE_NAME_NOT_AVAIL RM_ERROR_BASE-50
+#define RM_ERROR_PKT_AND_SERVICE_SRC_NOT_AVAIL RM_ERROR_BASE-50
+/** The provided character buffer that will contain the service source inst name or pkt
+ * source inst name is not of size RM_NAME_MAX_CHARS */
+#define RM_ERROR_SRC_NAME_BUF_INVALID_SIZE RM_ERROR_BASE-51
/**
* @brief Maximum number of characters allowed for RM instance, resource, and
diff --git a/rm_transport.h b/rm_transport.h
index 434a73aa8de6095f6c48302c143abd20170d50a2..426a3cbe7117638bce5985353fd492a14d5f79c8 100644 (file)
--- a/rm_transport.h
+++ b/rm_transport.h
Rm_TransportCallouts transportCallouts;
} Rm_TransportReCfg;
-/**
- * @b Description
- * @n
- * This function returns the RM instance name from which the service
- * encapsulated within the RM packet originated
- *
- * Restrictions: This API is only valid for Rm_pktType_RESOURCE_REQUEST
- * and Rm_pktType_NAMESERVER_REQUEST packet types
- *
- * @param[in] pkt
- * RM packet to extract service source instance name from.
- *
- * @param[out] serviceInstName
- * Pointer to a character array that will contain the RM instance name
- * that originated the service request. The character array MUST be
- * at least RM_NAME_MAX_CHARS bytes in length
- *
- * @retval
- * Success - #RM_OK
- * @retval
- * Failure - #RM_ERROR_PKT_AND_SERVICE_NAME_NOT_AVAIL
- */
-int32_t Rm_pktGetServiceSrcName(const Rm_Packet *pkt, char *serviceInstName);
-
-/**
- * @b Description
- * @n
- * This function returns the RM instance name from which the RM packet
- * originated
- *
- * Restrictions: This API is only valid for Rm_pktType_RESOURCE_REQUEST
- * and Rm_pktType_NAMESERVER_REQUEST packet types
- *
- * @param[in] pkt
- * RM packet to extract packet source instance name from.
- *
- * @param[out] pktInstName
- * Pointer to a character array that will contain the RM instance name
- * that originated the RM request packet. The character array MUST be
- * at least RM_NAME_MAX_CHARS bytes in length
- *
- * @retval
- * Success - #RM_OK
- * @retval
- * Failure - #RM_ERROR_PKT_AND_SERVICE_NAME_NOT_AVAIL
- */
-int32_t Rm_pktGetPktSrcName(const Rm_Packet *pkt, char *pktInstName);
-
/**
* @b Description
* @n
@@ -359,6 +311,64 @@ int32_t Rm_transportReconfig (Rm_TransportHandle transportHandle, const Rm_Trans
*/
int32_t Rm_transportUnregister (Rm_TransportHandle transportHandle);
+/**
+ * @b Description
+ * @n
+ * This function returns the RM instance name from which the service
+ * encapsulated within the RM packet originated
+ *
+ * Restrictions: This API is only valid for Rm_pktType_RESOURCE_REQUEST
+ * and Rm_pktType_NAMESERVER_REQUEST packet types
+ *
+ * @param[in] pkt
+ * RM packet to extract service source instance name from.
+ *
+ * @param[out] serviceInstName
+ * Pointer to a character array that will contain the RM instance name
+ * that originated the service request. The character array MUST be
+ * #RM_NAME_MAX_CHARS bytes in length
+ *
+ * @param[in] charBufLen
+ * Length of the provided pktInstName buffer
+ *
+ * @retval
+ * Success - #RM_OK
+ * @retval
+ * Failure - #RM_ERROR_PKT_AND_SERVICE_SRC_NOT_AVAIL
+ * Failure - #RM_ERROR_SRC_NAME_BUF_INVALID_SIZE
+ */
+int32_t Rm_receiveGetPktServiceSrcName(const Rm_Packet *pkt, char *serviceInstName,
+ int32_t charBufLen);
+
+/**
+ * @b Description
+ * @n
+ * This function returns the RM instance name from which the RM packet
+ * originated
+ *
+ * Restrictions: This API is only valid for Rm_pktType_RESOURCE_REQUEST
+ * and Rm_pktType_NAMESERVER_REQUEST packet types
+ *
+ * @param[in] pkt
+ * RM packet to extract packet source instance name from.
+ *
+ * @param[out] pktInstName
+ * Pointer to a character array that will contain the RM instance name
+ * that originated the RM request packet. The character array MUST be
+ * #RM_NAME_MAX_CHARS bytes in length
+ *
+ * @param[in] charBufLen
+ * Length of the provided pktInstName buffer
+ *
+ * @retval
+ * Success - #RM_OK
+ * @retval
+ * Failure - #RM_ERROR_PKT_AND_SERVICE_SRC_NOT_AVAIL
+ * Failure - #RM_ERROR_SRC_NAME_BUF_INVALID_SIZE
+ */
+int32_t Rm_receiveGetPktSrcName(const Rm_Packet *pkt, char *pktInstName,
+ int32_t charBufLen);
+
/**
* @b Description
* @n
diff --git a/src/rm_transport.c b/src/rm_transport.c
index 134a1ef06c79ca3666852321d7ac3315af28e5b8..933f4ffb023685d40af6887dfef0c9de53de065d 100644 (file)
--- a/src/rm_transport.c
+++ b/src/rm_transport.c
@@ -164,45 +164,57 @@ Rm_Transport *rmTransportFindRemoteInstType(Rm_Transport *transports, Rm_InstTyp
return (transports);\r
}\r
\r
-int32_t getPktSrcNames(const Rm_Packet *pkt, char *pktSrc, char *serviceSrc)\r
+/* FUNCTION PURPOSE: Returns RM packet source instance\r
+ ***********************************************************************\r
+ * DESCRIPTION: Can return the RM instance name for one of two things:\r
+ * - RM instance from which provided RM packet originated\r
+ * - RM instance from which the service request contained\r
+ * in the provided RM packet originated\r
+ */\r
+int32_t getPktSrcNames(const Rm_Packet *pkt, char *pktSrc, char *serviceSrc, int32_t bufLen)\r
{\r
int32_t retVal = RM_OK;\r
\r
- switch (pkt->pktType) {\r
- case Rm_pktType_RESOURCE_REQUEST:\r
- {\r
- Rm_ResourceRequestPkt *resourceReqPkt = (Rm_ResourceRequestPkt *)pkt->data;\r
+ if (bufLen != RM_NAME_MAX_CHARS) {\r
+ retVal = RM_ERROR_SRC_NAME_BUF_INVALID_SIZE;\r
+ }\r
+ else {\r
+ switch (pkt->pktType) {\r
+ case Rm_pktType_RESOURCE_REQUEST:\r
+ {\r
+ Rm_ResourceRequestPkt *resourceReqPkt = (Rm_ResourceRequestPkt *)pkt->data;\r
\r
- if (pktSrc){\r
- strncpy(pktSrc, resourceReqPkt->pktSrcInstName, RM_NAME_MAX_CHARS);\r
- }\r
+ if (pktSrc){\r
+ strncpy(pktSrc, resourceReqPkt->pktSrcInstName, RM_NAME_MAX_CHARS);\r
+ }\r
+\r
+ if (serviceSrc) {\r
+ strncpy(serviceSrc, resourceReqPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
+ }\r
\r
- if (serviceSrc) {\r
- strncpy(serviceSrc, resourceReqPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
+ break;\r
}\r
+ case Rm_pktType_NAMESERVER_REQUEST:\r
+ {\r
+ Rm_NsRequestPkt *nsRequestPkt = (Rm_NsRequestPkt *)pkt->data;\r
\r
- break;\r
- }\r
- case Rm_pktType_NAMESERVER_REQUEST:\r
- {\r
- Rm_NsRequestPkt *nsRequestPkt = (Rm_NsRequestPkt *)pkt->data;\r
+ if (pktSrc){\r
+ strncpy(pktSrc, nsRequestPkt->pktSrcInstName, RM_NAME_MAX_CHARS);\r
+ }\r
\r
- if (pktSrc){\r
- strncpy(pktSrc, nsRequestPkt->pktSrcInstName, RM_NAME_MAX_CHARS);\r
- }\r
+ if (serviceSrc) {\r
+ strncpy(serviceSrc, nsRequestPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
+ }\r
\r
- if (serviceSrc) {\r
- strncpy(serviceSrc, nsRequestPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
+ break;\r
+ }\r
+ case Rm_pktType_RESOURCE_RESPONSE:\r
+ case Rm_pktType_NAMESERVER_RESPONSE:\r
+ default:\r
+ {\r
+ retVal = RM_ERROR_PKT_AND_SERVICE_SRC_NOT_AVAIL;\r
+ break;\r
}\r
-\r
- break;\r
- }\r
- case Rm_pktType_RESOURCE_RESPONSE:\r
- case Rm_pktType_NAMESERVER_RESPONSE:\r
- default:\r
- {\r
- retVal = RM_ERROR_PKT_AND_SERVICE_NAME_NOT_AVAIL;\r
- break;\r
}\r
}\r
\r
********************* Application visible APIs ***********************\r
**********************************************************************/\r
\r
-/* FUNCTION PURPOSE: Returns a RM packet's service source instance name\r
- ***********************************************************************\r
- * DESCRIPTION: Returns the RM instance name from which the service\r
- * encapsulated in the RM packet originated.\r
- */\r
-int32_t Rm_pktGetServiceSrcName(const Rm_Packet *pkt, char *serviceInstName)\r
-{\r
- return(getPktSrcNames(pkt, NULL, serviceInstName));\r
-}\r
-\r
-/* FUNCTION PURPOSE: Returns a RM packet's source instance name\r
- ***********************************************************************\r
- * DESCRIPTION: Returns the RM instance name from which the RM packet\r
- * originated.\r
- */\r
-int32_t Rm_pktGetPktSrcName(const Rm_Packet *pkt, char *pktInstName)\r
-{\r
- return(getPktSrcNames(pkt, pktInstName, NULL));\r
-}\r
-\r
/* FUNCTION PURPOSE: Registers an app transport with a RM instance\r
***********************************************************************\r
* DESCRIPTION: Returns a transport handle to the application that\r
return (retVal);\r
}\r
\r
+/* FUNCTION PURPOSE: Returns a RM packet's service source instance name\r
+ ***********************************************************************\r
+ * DESCRIPTION: Returns the RM instance name from which the service\r
+ * encapsulated in the RM packet originated.\r
+ */\r
+int32_t Rm_receiveGetPktServiceSrcName(const Rm_Packet *pkt, char *serviceInstName, \r
+ int32_t charBufLen)\r
+{\r
+ return(getPktSrcNames(pkt, NULL, serviceInstName, charBufLen));\r
+}\r
+\r
+/* FUNCTION PURPOSE: Returns a RM packet's source instance name\r
+ ***********************************************************************\r
+ * DESCRIPTION: Returns the RM instance name from which the RM packet\r
+ * originated.\r
+ */\r
+int32_t Rm_receiveGetPktSrcName(const Rm_Packet *pkt, char *pktInstName, \r
+ int32_t charBufLen)\r
+{\r
+ return(getPktSrcNames(pkt, pktInstName, NULL, charBufLen));\r
+}\r
+\r
/* FUNCTION PURPOSE: Receives RM packets\r
***********************************************************************\r
* DESCRIPTION: The application provides RM packets received on the\r
index e99b69c1557039f2cd33caca147fd9416e9fdebf..bfdc31d408969a8c3aa335d3fa1ef8a3237fa1d0 100644 (file)
@@ -43,16 +43,17 @@ INCDIR := $(PDK_INSTALL_PATH);$(RM_INC_DIR);$(RM_ARM_LIN_TEST_DIR);$(IPC_DEVKIT_
# Libraries
RM_LIB = -lrm
+DAEMON_LIB = -ldaemon
IPC_LIBS = -ltiipc -ltiipcutils
ifeq ($(USEDYNAMIC_LIB), yes)
#presuming ARM executable would depend on dynamic library dependency
EXE_EXTN = _so
-LIBS = $(RM_LIB)
+LIBS = $(RM_LIB) $(DAEMON_LIB)
else
#forcing ARM executable to depend on static LLD libraries
EXE_EXTN =
-LIBS = -static $(RM_LIB) -Wl,-Bdynamic
+LIBS = -static $(RM_LIB) -Wl,-Bdynamic $(DAEMON_LIB)
endif
# Compiler options
#List the Source Files
RM_SERVER_SRC = \
rm_server.c \
- rm_linux_osal.c \
+ rm_server_osal.c \
sockutils.c
RM_LINUX_CLIENT_TEST_SRC = \
index 1b7a31c448dfa1f7e7491b7cbd336e1ea26980d3..fca88ee5211e1fc13c5fca6168f333ed16a1be48 100644 (file)
/*
- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <signal.h>
#include <fcntl.h>
-#include <time.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#include <libdaemon/daemon.h>
/* Socket Includes */
+#include "serverlogutil.h"
#include "sockutils.h"
#include "sockrmmsg.h"
#include <ti/drv/rm/rm.h>
#include <ti/drv/rm/rm_transport.h>
-#define error_msg printf
-#define info_msg printf
+#define RMSERVER_DAEMON_PID_FILE_NAME "/var/run/rmServer/pid"
+#define RMSERVER_DAEMON_LOG_FILE_NAME "/var/log/rmServer.log"
/* Socket timeout */
#define SERVER_SOCK_TIMEOUT_USEC (500)
-/* Seconds since last request to print resources */
-#define SECONDS_SINCE_LAST_REQUEST (5)
-
/* Error checking macro */
#define ERROR_CHECK(checkVal, resultVal, rmInstName, printMsg) \
if (resultVal != checkVal) { \
char errorMsgToPrint[] = printMsg; \
- printf("%s : ", rmInstName); \
- printf("%s with error code : %d\n", errorMsgToPrint, resultVal); \
+ error_msg("%s : ", rmInstName); \
+ error_msg("%s with error code : %d\n", errorMsgToPrint, resultVal); \
exit(EXIT_FAILURE); \
}
+/* logging errors */
+#define error_msg(...) rmsrv_log(LOG_ERR, __func__, __FILE__, __LINE__, __VA_ARGS__);
+/* logging warnings */
+#define warning_msg(...) rmsrv_log(LOG_WARNING, __func__, __FILE__, __LINE__, __VA_ARGS__);
+/* logging information */
+#define info_msg(...) rmsrv_log(LOG_INFO, __func__, __FILE__, __LINE__, __VA_ARGS__);
+/* logging debug information */
+#define debug_msg(...) rmsrv_log(LOG_DEBUG, __func__, __FILE__, __LINE__, __VA_ARGS__);
+
+#define LOG_APPEND(x) \
+ do { \
+ int len; \
+ len = MAX_LOG_LEN - strlen(rmsrv_log_buf); \
+ if (len > 0) { \
+ strncat(rmsrv_log_buf, x, len); \
+ } \
+ else { \
+ return; \
+ } \
+ } while(0)
+
/* RM registered transport mapping structure */
typedef struct trans_map_entry_s {
/* Registered RM transport handle */
/**********************************************************************
********************** Global Variables ******************************
**********************************************************************/
+
/* RM Server instance name (must match with RM Global Resource List (GRL) and policies */
-char server_name[RM_NAME_MAX_CHARS] = "RM_Server";
+char server_name[RM_NAME_MAX_CHARS] = "RM_Server";
+
+Rm_Handle server_h;
+
+sock_h server_sock = NULL;
+
+rmserver_cfg_t rmsrv_cfg;
+
+char rmsrv_log_buf[MAX_LOG_LEN];
+
+/**********************************************************************
+ ********************** External Variables ****************************
+ **********************************************************************/
-sock_h server_sock = NULL;
+extern int optind;
+extern char *optarg;
/**********************************************************************
************************** Server Functions **************************
**********************************************************************/
-
+
+/* RM Server logging utility (need to move it to another file) */
+void rmsrv_log(const int loglevel, const char* functionName, const char* fileName, const int lineNo, const char* format, ...)
+{
+ int len;
+ char lineno_a[32];
+ va_list args;
+
+ sprintf(lineno_a, "%d", lineNo);
+
+ rmsrv_log_buf[0] = 0;
+
+ LOG_APPEND(fileName);
+ LOG_APPEND(":");
+ LOG_APPEND(lineno_a);
+ LOG_APPEND(":");
+ LOG_APPEND(functionName);
+ LOG_APPEND(":");
+
+ len = MAX_LOG_LEN - strlen(rmsrv_log_buf);
+ if (len <= 0) {
+ return;
+ }
+
+ va_start(args, format);
+ vsnprintf(&rmsrv_log_buf[strlen(rmsrv_log_buf)], len, format, args);
+ va_end(args);
+
+ fprintf(rmsrv_cfg.logfile_p, "%s", rmsrv_log_buf);
+ fflush(rmsrv_cfg.logfile_p);
+}
+
Rm_Packet *transportAlloc(Rm_AppTransportHandle appTransport, uint32_t pktSize, Rm_PacketHandle *pktHandle)
{
Rm_Packet *rm_pkt = NULL;
rm_pkt = calloc(1, sizeof(*rm_pkt));
if (!rm_pkt) {
- error_msg("can't malloc for RM send message (err: %s)\n",
+ error_msg("Failed to malloc RM packet (err: %s)\n",
strerror(errno));
return (NULL);
}
void transportFree (Rm_Packet *rm_pkt)
{
- uint32_t pkt_size = rm_pkt->pktLenBytes;
- int32_t status;
+ int32_t status;
if (rm_pkt) {
free (rm_pkt);
@@ -121,21 +188,19 @@ int32_t transportSend (Rm_AppTransportHandle appTransport, Rm_PacketHandle pktHa
Rm_Packet *rm_pkt = (Rm_Packet *)pktHandle;
if (sock_send(server_sock, (char *)rm_pkt, (int) rm_pkt->pktLenBytes, client_sock_name)) {
- error_msg("send data failed\n");
+ error_msg("Failed to send RM packet\n");
+ }
+ else {
+ /* Print resources after sending response */
+ Rm_resourceStatus(server_h, 1);
}
-
+
+ transportFree(rm_pkt);
return (0);
}
-int main(int argc, char *argv[])
+int rm_server_run(void *grl, void *policy, void *lin_dtb, int is_daemon)
{
- int fd;
- time_t old_time;
- struct stat file_stat;
- char *grl_addr;
- char *linux_dtb_addr;
- char *policy_addr;
- Rm_Handle server_h;
Rm_InitCfg rm_init_cfg;
Rm_TransportCfg rm_trans_cfg;
int32_t rm_result;
sock_name_t serv_sock_name;
sock_name_t client_sock_addr;
Rm_Packet *rm_pkt = NULL;
- struct sockaddr_un client_addr;
- struct timeval tv = {0, SERVER_SOCK_TIMEOUT_USEC};
+ char pkt_src[RM_NAME_MAX_CHARS];
+ struct sockaddr_un client_addr;
+ int signal_fd = -1;
char rm_socket_name[] = RM_SERVER_SOCKET_NAME;
- if ((argc < 3) || (argc > 4))
- {
- error_msg("Invalid number of input arguments\n");
- exit(EXIT_FAILURE);
- }
-
- /* mmap the GRL */
- fd = open(argv[1], O_RDONLY);
- if (fd == -1) {
- error_msg("Error opening GRL\n");
- exit(EXIT_FAILURE);
- }
- /* Obtain file size */
- if (fstat(fd, &file_stat) == -1) {
- error_msg("Error getting GRL size\n");
- exit(EXIT_FAILURE);
- }
- grl_addr = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (grl_addr == MAP_FAILED) {
- error_msg("mmap of GRL failed\n");
- exit(EXIT_FAILURE);
- }
-
- /* mmap the Global Policy */
- fd = open(argv[2], O_RDONLY);
- if (fd == -1) {
- error_msg("Error opening Global Policy\n");
- exit(EXIT_FAILURE);
- }
- /* Obtain file size */
- if (fstat(fd, &file_stat) == -1) {
- error_msg("Error getting Global Policy size\n");
- exit(EXIT_FAILURE);
- }
- policy_addr = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (policy_addr == MAP_FAILED) {
- error_msg("mmap of Global Policy failed\n");
- exit(EXIT_FAILURE);
- }
-
- if (argc == 4){
- /* mmap (Example) Linux DTB */
- fd = open(argv[3], O_RDONLY);
- if (fd == -1) {
- error_msg("Error opening Linux DTB\n");
- exit(EXIT_FAILURE);
- }
- /* Obtain file size */
- if (fstat(fd, &file_stat) == -1) {
- error_msg("Error getting Linux DTB size\n");
- exit(EXIT_FAILURE);
- }
- linux_dtb_addr = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (linux_dtb_addr == MAP_FAILED) {
- error_msg("mmap of Linux DTB failed\n");
- exit(EXIT_FAILURE);
- }
+ rmsrv_cfg.logfile_p = fopen(RMSERVER_DAEMON_LOG_FILE_NAME, "w+");
+ if (!rmsrv_cfg.logfile_p) {
+ printf("Error in opening log file %s (%s)", RMSERVER_DAEMON_LOG_FILE_NAME, strerror(errno));
}
+ debug_msg("Starting RM server");
+
/* Create the Server instance */
memset(&rm_init_cfg, 0, sizeof(rm_init_cfg));
rm_init_cfg.instName = server_name;
rm_init_cfg.instType = Rm_instType_SERVER;
- rm_init_cfg.instCfg.serverCfg.globalResourceList = (void *)grl_addr;
- rm_init_cfg.instCfg.serverCfg.linuxDtb = (void *)linux_dtb_addr;
- rm_init_cfg.instCfg.serverCfg.globalPolicy = (void *)policy_addr;
+ rm_init_cfg.instCfg.serverCfg.globalResourceList = grl;
+ rm_init_cfg.instCfg.serverCfg.linuxDtb = lin_dtb;
+ rm_init_cfg.instCfg.serverCfg.globalPolicy = policy;
server_h = Rm_init(&rm_init_cfg, &rm_result);
ERROR_CHECK(RM_OK, rm_result, server_name, "Initialization failed\n");
- printf("\n\nInitialized %s\n\n", server_name);
+ debug_msg("RM Server initialized with name: %s", server_name);
Rm_resourceStatus(server_h, 1);
serv_sock_name.type = sock_name_e;
serv_sock_name.s.name = rm_socket_name;
server_sock = sock_open (&serv_sock_name);
+ if (!server_sock) {
+ error_msg("Error when opening socket %s", rm_socket_name);
+ return -1;
+ }
- old_time = time(NULL);
- info_msg("Begin waiting for messages from Clients\n");
+ if (is_daemon){
+ signal_fd = daemon_signal_fd();
+ }
while(1) {
-
- if ((time(NULL) - old_time) > SECONDS_SINCE_LAST_REQUEST) {
- Rm_resourceStatus(server_h, 1);
- old_time = time(NULL);
- }
-
- retval = sock_wait(server_sock, &length, &tv, -1);
- if (retval == -2) {
- goto loop_continue;
- }
- else if (retval < 0) {
+ info_msg("Waiting for messages from Clients\n");
+ retval = sock_wait(server_sock, &length, NULL, signal_fd);
+ if (retval < 0) {
error_msg("Error in reading from socket\n");
goto loop_continue;
}
goto loop_continue;
}
- info_msg("received RM pkt of size %d bytes from %s\n", length, client_sock_addr.s.addr->sun_path);
+ info_msg("Received RM pkt of size %d bytes from socket %s\n", length, client_sock_addr.s.addr->sun_path);
+ if (Rm_receiveGetPktSrcName(rm_pkt, &pkt_src[0], RM_NAME_MAX_CHARS) == RM_OK) {
+ info_msg(" RM pkt originated from %s instance\n", &pkt_src[0]);
+ }
+ if (Rm_receiveGetPktServiceSrcName(rm_pkt, &pkt_src[0], RM_NAME_MAX_CHARS) == RM_OK) {
+ info_msg(" Service request within RM pkt originated from %s instance\n", &pkt_src[0]);
+ }
map_index = trans_map;
while(map_index != NULL) {
/* Provide packet to RM Server for processing */
if (rm_result = Rm_receivePacket(map_index->trans_handle, rm_pkt)) {
- printf("RM failed to process received packet: %d\n", rm_result);
+ error_msg("RM failed to process received packet: %d\n", rm_result);
}
- transportFree(rm_pkt);
- old_time = time(NULL);
+
loop_continue:
/* Cleanups */
- length = 0;
+ length = 0;
+ transportFree(rm_pkt);
memset(&client_sock_addr, 0, sizeof(sock_name_t));
memset(&client_addr, 0, sizeof(struct sockaddr_un));
+ }
+}
+
+char *get_pid_file_name(void) {
+ static char pid_file_name[] = RMSERVER_DAEMON_PID_FILE_NAME;
+
+ return pid_file_name;
+}
+
+static void print_usage(char *appname)
+{
+ printf ("Usage: %s [OPTION]... [GRL] [POLICY]\n", appname);
+ printf ("Run a resource manager server with the specified [GRL] and [POLICY]\n"
+ "[GRL] and [POLICY] must be device tree blob (DTB) files\n"
+ "Example: rmserver grl.dtb policy.dtb\n\n"
+ "Optional Input:\n"
+ " -l, --lindtb [LINUX_DTB] Optionally, provide a Linux DTB file\n"
+ " that RM will use to reserve resources\n"
+ " for Linux. The GRL must have the\n"
+ " proper Linux DTB resource mappings\n"
+ " for this feature to work\n"
+ "Miscellaneous:\n"
+ " -n, --nodaemon do not daemonize, run in foreground\n"
+ " -k, --kill kill the existing daemon\n"
+ " -h, --help print this message\n"
+ "\n"
+ "rmserver will run as a daemon by default.\n\n");
+}
+
+int main(int argc, char *argv[])
+{
+ int opt;
+ int daemonize = 1, kill = 0;
+ int fd;
+ struct stat file_stat;
+ pid_t pid;
+ char *grl_file;
+ char *policy_file;
+ char *lin_dtb_file = NULL;
+ void *grl;
+ void *policy;
+ void *lin_dtb = NULL;
+
+
+ const struct option longopts[] =
+ {
+ {"nodaemon", no_argument, 0, 'n'},
+ {"kill", no_argument, 0, 'k'},
+ {"help", no_argument, 0, 'h'},
+ {"lindtb", required_argument, 0, 'l'},
+ {0, 0, 0, 0},
+ };
+
+ while((opt = getopt_long(argc, argv, "nkhl:", longopts, NULL)) != -1) {
+ switch (opt) {
+ case 'n':
+ daemonize = 0;
+ break;
+ case 'k':
+ kill = 1;
+ break;
+ case 'l':
+ lin_dtb_file = optarg;
+ break;
+ case 'h':
+ default:
+ print_usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ if (!kill) {
+ /* GRL and Policy must always be provided */
+ if (optind == (argc - 2)) {
+ /* First must be GRL */
+ grl_file = argv[optind++];
+ /* Second must be policy */
+ policy_file = argv[optind++];
+ }
+ else {
+ printf("GRL or policy not provided\n\n");
+ print_usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ /* mmap the GRL */
+ fd = open(grl_file, O_RDONLY);
+ if (fd == -1) {
+ printf("Error opening GRL: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ /* Obtain file size */
+ if (fstat(fd, &file_stat) == -1) {
+ printf("Error getting GRL size\n");
+ exit(EXIT_FAILURE);
+ }
+ grl = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (grl == MAP_FAILED) {
+ printf("mmap of GRL failed\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* mmap the Global Policy */
+ fd = open(policy_file, O_RDONLY);
+ if (fd == -1) {
+ printf("Error opening Global Policy: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ /* Obtain file size */
+ if (fstat(fd, &file_stat) == -1) {
+ printf("Error getting Global Policy size\n");
+ exit(EXIT_FAILURE);
+ }
+ policy = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (policy == MAP_FAILED) {
+ printf("mmap of Global Policy failed\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (lin_dtb_file) {
+ /* mmap the Linux DTB if it was provided */
+ fd = open(lin_dtb_file, O_RDONLY);
+ if (fd == -1) {
+ printf("Error opening Linux DTB: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ /* Obtain file size */
+ if (fstat(fd, &file_stat) == -1) {
+ printf("Error getting Linux DTB size\n");
+ exit(EXIT_FAILURE);
+ }
+ lin_dtb = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (lin_dtb == MAP_FAILED) {
+ printf("mmap of Linux DTB failed\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+
+ if (daemonize) {
+ if (kill) {
+ printf("Killing %s\n", argv[0]);
+ }
+ else {
+ printf("Starting %s\n", argv[0]);
+ }
+
+ /* Reset signal handlers */
+ if (daemon_reset_sigs(-1) < 0) {
+ printf("Failed to reset all signal handlers: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ /* Unblock signals */
+ if (daemon_unblock_sigs(-1) < 0) {
+ printf("Failed to unblock all signals: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (check_and_create_path (get_pid_file_name()) < 0) {
+ printf("Failed to create pid file path: %s\n", get_pid_file_name());
+ exit(EXIT_FAILURE);
+ }
+
+ /* set daemon id string */
+ daemon_log_ident = daemon_ident_from_argv0(argv[0]);
+ daemon_pid_file_proc = (daemon_pid_file_proc_t) get_pid_file_name;
+
+ if (kill) {
+ if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) {
+ printf("Failed to kill daemon: %s\n", strerror(errno));
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ /* Single instance */
+ if ((pid = daemon_pid_file_is_running()) >= 0) {
+ printf("Daemon already running on PID file %u\n", pid);
+ exit(EXIT_FAILURE);
+ }
+
+ if (daemon_retval_init() < 0) {
+ printf("Failed to create pipe.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Do the fork */
+ if ((pid = daemon_fork()) < 0) {
+ daemon_retval_done();
+ printf("Error in daemon fork %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ else if (pid) { /* The parent */
+ int ret;
+
+ /* Wait for 20 seconds for the return value passed from the daemon process */
+ if ((ret = daemon_retval_wait(20)) < 0) {
+ printf("Could not receive return value from daemon process: %s\n", strerror(errno));
+ return -1;
+ }
+
+ printf("Daemon returned %i as return value.\n", ret);
+ return ret;
+ }
+
+ /* Close FDs */
+ if (daemon_close_all(-1) < 0) {
+ printf("Failed to close all file descriptors: %s\n", strerror(errno));
+
+ /* Send the error condition to the parent process */
+ daemon_retval_send(1);
+ goto close_n_exit;
+ }
+
+ /* Create the PID file */
+ if (daemon_pid_file_create() < 0) {
+ printf("Could not create PID file (%s).\n", strerror(errno));
+ daemon_retval_send(2);
+ goto close_n_exit;
+ }
+
+ /* Initialize signal handling */
+ if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
+ printf("Could not register signal handlers (%s).\n", strerror(errno));
+ daemon_retval_send(3);
+ goto close_n_exit;
+ }
+
+ /* Send OK to parent process */
+ daemon_retval_send(0);
}
+
+ rm_server_run(grl, policy, lin_dtb, daemonize);
+
+close_n_exit:
+ printf("Exiting %s daemon\n", argv[0]);
+ if (daemonize) {
+ daemon_retval_send(255);
+ daemon_signal_done();
+ daemon_pid_file_remove();
+ }
}
diff --git a/test/k2h/armv7/linux/rm_server_osal.c b/test/k2h/armv7/linux/rm_server_osal.c
--- /dev/null
@@ -0,0 +1,209 @@
+/**
+ * @file rm_server_osal.c
+ *
+ * @brief
+ * This is the OS abstraction layer used by the RM Server in Linux.
+ *
+ * \par
+ * ============================================================================
+ * @n (C) Copyright 2012-2014, Texas Instruments, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 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.
+ *
+ * \par
+*/
+
+/* Standard Includes */
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "serverlogutil.h"
+
+/**********************************************************************
+ ****************************** Defines *******************************
+ **********************************************************************/
+
+/**********************************************************************
+ ************************** Global Variables **************************
+ **********************************************************************/
+uint32_t rmMallocCounter = 0;
+uint32_t rmFreeCounter = 0;
+
+/**********************************************************************
+ ********************** External Variables ****************************
+ **********************************************************************/
+
+extern char rmsrv_log_buf[MAX_LOG_LEN];
+extern rmserver_cfg_t rmsrv_cfg;
+
+/**********************************************************************
+ *************************** OSAL Functions **************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Allocates memory
+ ***********************************************************************
+ * DESCRIPTION: The function is used to allocate a memory block of the
+ * specified size.
+ */
+void *Osal_rmMalloc (uint32_t num_bytes)
+{
+ /* Increment the allocation counter. */
+ rmMallocCounter++;
+
+ /* Allocate memory. */
+ return calloc(1, num_bytes);
+}
+
+/* FUNCTION PURPOSE: Frees memory
+ ***********************************************************************
+ * DESCRIPTION: The function is used to free a memory block of the
+ * specified size.
+ */
+void Osal_rmFree (void *ptr, uint32_t size)
+{
+ /* Increment the free counter. */
+ rmFreeCounter++;
+ free(ptr);
+}
+
+/* FUNCTION PURPOSE: Critical section enter
+ ***********************************************************************
+ * DESCRIPTION: The function is used to enter a critical section.
+ * Function protects against
+ *
+ * access from multiple cores
+ * and
+ * access from multiple threads on single core
+ */
+void *Osal_rmCsEnter(void)
+{
+ return NULL;
+}
+
+/* FUNCTION PURPOSE: Critical section exit
+ ***********************************************************************
+ * DESCRIPTION: The function is used to exit a critical section
+ * protected using Osal_cppiCsEnter() API.
+ */
+void Osal_rmCsExit(void *CsHandle)
+{
+
+}
+
+/* FUNCTION PURPOSE: Cache invalidate
+ ***********************************************************************
+ * DESCRIPTION: The function is used to indicate that a block of memory is
+ * about to be accessed. If the memory block is cached then this
+ * indicates that the application would need to ensure that the
+ * cache is updated with the data from the actual memory.
+ */
+void Osal_rmBeginMemAccess(void *ptr, uint32_t size)
+{
+ return;
+}
+
+/* FUNCTION PURPOSE: Cache writeback
+ ***********************************************************************
+ * DESCRIPTION: The function is used to indicate that the block of memory has
+ * finished being accessed. If the memory block is cached then the
+ * application would need to ensure that the contents of the cache
+ * are updated immediately to the actual memory.
+ */
+void Osal_rmEndMemAccess(void *ptr, uint32_t size)
+{
+ return;
+}
+
+/* FUNCTION PURPOSE: Creates a task blocking object
+ ***********************************************************************
+ * DESCRIPTION: The function is used to create a task blocking object
+ * capable of blocking the task a RM instance is running
+ * within
+ */
+void *Osal_rmTaskBlockCreate(void)
+{
+ return(NULL);
+}
+
+/* FUNCTION PURPOSE: Blocks a RM instance
+ ***********************************************************************
+ * DESCRIPTION: The function is used to block a task whose context a
+ * RM instance is running within.
+ */
+void Osal_rmTaskBlock(void *handle)
+{
+
+}
+
+/* FUNCTION PURPOSE: unBlocks a RM instance
+ ***********************************************************************
+ * DESCRIPTION: The function is used to unblock a task whose context a
+ * RM instance is running within.
+ */
+void Osal_rmTaskUnblock(void *handle)
+{
+
+}
+
+/* FUNCTION PURPOSE: Deletes a task blocking object
+ ***********************************************************************
+ * DESCRIPTION: The function is used to delete a task blocking object
+ * provided to a RM instance
+ */
+void Osal_rmTaskBlockDelete(void *handle)
+{
+
+}
+
+/* FUNCTION PURPOSE: Prints a variable list
+ ***********************************************************************
+ * DESCRIPTION: The function is used to print a string to the console
+ */
+void Osal_rmLog (char *fmt, ... )
+{
+ va_list ap;
+ int len;
+
+ rmsrv_log_buf[0] = 0;
+
+ len = MAX_LOG_LEN - strlen(rmsrv_log_buf);
+ if (len <= 0) {
+ return;
+ }
+
+ va_start(ap, fmt);
+ vsnprintf(&rmsrv_log_buf[strlen(rmsrv_log_buf)], len, fmt, ap);
+ va_end(ap);
+
+ fprintf(rmsrv_cfg.logfile_p, "%s", rmsrv_log_buf);
+ fflush(rmsrv_cfg.logfile_p);
+}
+
diff --git a/test/k2h/armv7/linux/serverlogutil.h b/test/k2h/armv7/linux/serverlogutil.h
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 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.
+ *
+ */
+
+#ifndef __SERVERLOGUTIL_H__
+#define __SERVERLOGUTIL_H__
+
+#include <stdio.h>
+
+#define MAX_LOG_LEN (65536)
+
+typedef struct rmserver_cfg_tag {
+ FILE *logfile_p;
+} rmserver_cfg_t;
+
+#endif /* __SERVERLOGUTIL_H__ */