summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 053433e)
raw | patch | inline | side by side (parent: 053433e)
author | Justin Sobota <jsobota@ti.com> | |
Fri, 26 Apr 2013 22:20:48 +0000 (18:20 -0400) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Fri, 26 Apr 2013 22:20:48 +0000 (18:20 -0400) |
20 files changed:
index ec58792f2a43566e4136191ddf3aaf0474d79c5f..9b42547b988b8e5c4e9aad1e3637f1683f26c519 100644 (file)
SRCDIR = ./src
UTLSRCDIR = ./util/libfdt
-VPATH=$(SRCDIR) $(UTLSRCDIR)
+VPATH=$(SRCDIR):$(UTLSRCDIR)
#List the COMMONSRC Files
COMMONSRCC = \
index 0bf05bcf8a20ccf81f0717640ed935ea9e88e8b9..c0e309da73f85fbb87e5750e77ffb60707e976f4 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 fd4e991f8b1c32ab9659c4c9b39c02323da1da71..6266324d3d6816dbd69f08c45449deea08e0f905 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
diff --git a/makefile_armv7 b/makefile_armv7
index b6730fdef3ca87c786a98faf9b08175525bf2e26..cfda68a51484ecb7fcd460cef671f0738b39f79f 100644 (file)
--- a/makefile_armv7
+++ b/makefile_armv7
endif
# PHONY Targets
-#.PHONY: all clean lib tests install installbin
-.PHONY: all clean lib install installbin
+.PHONY: all clean lib tests install installbin
# all rule
all: .executables install installbin
-#.executables: lib tests
-.executables: lib
+.executables: lib tests
# Libraries
lib: .libraries
# tests Stub to add tests
-#tests:
-# @$(MAKE) -f ./test/$(DEVICE)/armv7/linux/build/makefile all
+tests:
+ @$(MAKE) -f ./test/$(DEVICE)/armv7/linux/build/makefile all
# examples Stub to add Examples
#examples:
# Rule to clean $(ARMV7LIBDIR)/librm.a library
clean:
@$(MAKE) -f ./build/armv7/librm_aearmv7.mk $@
-# @$(MAKE) -f ./test/$(DEVICE)/armv7/linux/build/makefile $@
+ @$(MAKE) -f ./test/$(DEVICE)/armv7/linux/build/makefile $@
@$(RMDIR) $(ARMV7OBJDIR)/rm
@$(RMDIR) $(ARMV7BINDIR)/rm
@$(RM) $(ARMV7LIBDIR)/librm.a
installbin:
install -d $(INSTALL_BIN_BASE_DIR)
-# install -c -m 755 $(ARMV7BINDIR)/rm/test/rmTest.out $(INSTALL_BIN_BASE_DIR)/rmTest_$(DEVICE).out
-# install -c -m 755 $(ARMV7BINDIR)/rm/test/rmMemTest.out $(INSTALL_BIN_BASE_DIR)/rmMemTest_$(DEVICE).out
-# install -c -m 755 $(ARMV7BINDIR)/rm/test/rmSharedTest.out $(INSTALL_BIN_BASE_DIR)/rmSharedTest_$(DEVICE).out
+ install -c -m 755 $(ARMV7BINDIR)/rm/test/rmServer.out $(INSTALL_BIN_BASE_DIR)/rmServer_$(DEVICE).out
+ install -c -m 755 $(ARMV7BINDIR)/rm/test/rmClientTest.out $(INSTALL_BIN_BASE_DIR)/rmClientTest_$(DEVICE).out
install:
install -d $(INSTALL_INC_BASE_DIR)/ti/drv/rm/include
diff --git a/rm_services.h b/rm_services.h
index 8550ce5c975f1c36a0316050ee1084cc654e9ab8..a00292bf43a20c0efc2e935c96b06c4c90772c06 100644 (file)
--- a/rm_services.h
+++ b/rm_services.h
* #Rm_service_RESOURCE_GET_BY_NAME. If the NameServer name and the base
* and length are not NULL the resource information retrieved from the
* NameServer entry for the name will replace the values present in
- * #resourceBase and #resourceLenth */
+ * #resourceBase and #resourceLength */
const char *resourceNsName;
/** Callback function used by RM to provide responses back to application
* components after a service request resulted in a blocking operation.
diff --git a/src/rm.c b/src/rm.c
index f6abbd6c48d262ed5670a9b69554946c12891171..cfa937e2e484e7d095aa58c78b8470d51bc550bd 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
if ((serviceResponse.serviceState == RM_SERVICE_APPROVED) &&
((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
(transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+ (transaction->type == Rm_service_RESOURCE_FREE) ||
(transaction->type == Rm_service_RESOURCE_STATUS) ||
(transaction->type == Rm_service_RESOURCE_GET_BY_NAME)))
{
diff --git a/test/k2h/armv7/linux/README.txt b/test/k2h/armv7/linux/README.txt
--- /dev/null
@@ -0,0 +1,28 @@
+To run rmServer_k2h.out:
+
+copy the following files from rm/test/dts_files to the install directory containing rmServer_k2h/k.out:
+global-resources.dtb
+server-policy.dtb
+linux-evm.dtb [Optional]
+
+The data contained in the latter DTB files is not required to run the RM Server. A new GRL and policy
+can be written and supplied instead of the latter files.
+
+For information on how to create new GRLs and Policies please see:
+http://processors.wiki.ti.com/index.php/MCSDK_UG_Chapter_Developing_System_Mgmt#Resource_Manager
+
+To run the Server:
+$ ./rmServer_k2h.out global-resources.dtb server-policy.dtb linux-evm.dtb
+
+The Server will wait for Client socket connections and service any requests received via those sockets.
+
+
+To run the rmClientTest_k2h.out:
+
+copy the following files from rm/test/dts_files to the install directory containing rmClientTest_k2h/k.out:
+static-policy.dtb
+
+To execute the Client test:
+$ ./rmClientTest_k2h.out static-policy.dtb
+
+The Client test will establish a socket connection with the Server, request resources and then free all resources requested.
diff --git a/test/k2h/armv7/linux/rm_client_test.c b/test/k2h/armv7/linux/rm_client_test.c
--- /dev/null
@@ -0,0 +1,963 @@
+/*
+ * rm_arm_test.c
+ *
+ * Multi-process Resource Manager test that uses sockets to allow a Linux
+ * User-space application to request RM services from a RM Server,
+ * Client Delegate, and Client.
+ *
+ * ============================================================================
+ *
+ * Copyright (c) 2012-2013, Texas Instruments 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:
+ *
+ * * 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.
+ *
+ */
+
+ /* Standard includes */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* Socket Includes */
+#include "sockutils.h"
+#include "sockrmmsg.h"
+
+/* RM Includes */
+#include <ti/drv/rm/rm.h>
+#include <ti/drv/rm/rm_transport.h>
+#include <ti/drv/rm/rm_services.h>
+
+/**********************************************************************
+ ************************** RM Test Symbols ***************************
+ **********************************************************************/
+
+#define error_msg printf
+#define info_msg printf
+
+/* Test FALSE */
+#define RM_TEST_FALSE 0
+/* Test TRUE */
+#define RM_TEST_TRUE 1
+
+/* Socket timeout */
+#define CLIENT_SOCK_TIMEOUT_USEC (500)
+
+/* Application's registered RM transport indices */
+#define SERVER_TO_CLIENT_MAP_ENTRY 0
+/* Maximum number of registered RM transports */
+#define MAX_MAPPING_ENTRIES 1
+
+/* Size of RM static allocation response queue. Must be greater than number of APPROVED
+ * static allocations */
+#define MAX_STATIC_ALLOCATION_RESPS 5
+
+/* Size of RM service response queue */
+#define MAX_QUEUED_SERVICE_RESPONSES 10
+
+/* Error checking macro */
+#define ERROR_CHECK(checkVal, resultVal, rmInstName, printMsg) \
+ if (resultVal != checkVal) { \
+ char errorMsgToPrint[] = printMsg; \
+ printf("Error Core %d : %s : ", coreNum, rmInstName); \
+ printf("%s with error code : %d\n", errorMsgToPrint, resultVal); \
+ testErrors++; \
+ }
+
+#define POSITIVE_PASS_CHECK(title, core, instName, resName, resStart, resLen, align, state, check) \
+ do { \
+ int32_t start = resStart; \
+ int32_t alignment = align; \
+ char titleMsg[] = title; \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("Core %d : %s\n", core, titleMsg); \
+ printf ("Core %d : - Instance Name: %-32s -\n", core, instName); \
+ printf ("Core %d : - Resource Name: %-32s -\n", core, resName); \
+ if (start == RM_RESOURCE_BASE_UNSPECIFIED) { \
+ printf ("Core %d : - Start: UNSPECIFIED -\n", \
+ core); \
+ printf ("Core %d : - Length: %-16d -\n", \
+ core, resLen); \
+ } \
+ else { \
+ printf ("Core %d : - Start: %-16d -\n", \
+ core, resStart); \
+ printf ("Core %d : - End: %-16d -\n", core, \
+ (start + resLen - 1)); \
+ } \
+ if (alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) { \
+ printf ("Core %d : - Alignment: UNSPECIFIED -\n", \
+ core); \
+ } \
+ else { \
+ printf ("Core %d : - Alignment: %-16d -\n", \
+ core, alignment); \
+ } \
+ printf ("Core %d : - -\n", \
+ core); \
+ if (state == check) { \
+ printf ("Core %d : - PASSED -\n", \
+ core); \
+ } \
+ else { \
+ printf ("Core %d : - FAILED - Denial: %-6d -\n", \
+ core, state); \
+ testErrors++; \
+ } \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("\n"); \
+ } while(0);
+
+#define NEGATIVE_PASS_CHECK(title, core, instName, resName, resStart, resLen, align, state, check) \
+ do { \
+ int32_t start = resStart; \
+ int32_t alignment = align; \
+ char titleMsg[] = title; \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("Core %d : %s\n", core, titleMsg); \
+ printf ("Core %d : - Instance Name: %-32s -\n", core, instName); \
+ printf ("Core %d : - Resource Name: %-32s -\n", core, resName); \
+ if (start == RM_RESOURCE_BASE_UNSPECIFIED) { \
+ printf ("Core %d : - Start: UNSPECIFIED -\n", \
+ core); \
+ printf ("Core %d : - Length: %-16d -\n", \
+ core, resLen); \
+ } \
+ else { \
+ printf ("Core %d : - Start: %-16d -\n", \
+ core, resStart); \
+ printf ("Core %d : - End: %-16d -\n", core, \
+ (start + resLen - 1)); \
+ } \
+ if (alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) { \
+ printf ("Core %d : - Alignment: UNSPECIFIED -\n", \
+ core); \
+ } \
+ else { \
+ printf ("Core %d : - Alignment: %-16d -\n", \
+ core, alignment); \
+ } \
+ printf ("Core %d : - -\n", \
+ core); \
+ if (state != check) { \
+ printf ("Core %d : - PASSED - Denial: %-6d -\n", \
+ core, state); \
+ } \
+ else { \
+ printf ("Core %d : - FAILED - Expected Denial -\n", \
+ core); \
+ testErrors++; \
+ } \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("\n"); \
+ } while(0);
+
+#define STATUS_PASS_CHECK(title, core, instName, resName, resStart, resLen, refCnt, state, check, expectRefCnt) \
+ do { \
+ int32_t start = resStart; \
+ char titleMsg[] = title; \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("Core %d : %s\n", core, titleMsg); \
+ printf ("Core %d : - Instance Name: %-32s -\n", core, instName); \
+ printf ("Core %d : - Resource Name: %-32s -\n", core, resName); \
+ printf ("Core %d : - Start: %-16d -\n", \
+ core, resStart); \
+ printf ("Core %d : - End: %-16d -\n", core, \
+ (start + resLen - 1)); \
+ printf ("Core %d : - Expected Owner Count: %-16d -\n", \
+ core, expectRefCnt); \
+ printf ("Core %d : - Returned Owner Count: %-16d -\n", \
+ core, refCnt); \
+ printf ("Core %d : - -\n", core); \
+ if ((state == check) && (refCnt == expectRefCnt)) { \
+ printf ("Core %d : - PASSED -\n", core); \
+ } \
+ else { \
+ if (refCnt != expectRefCnt) { \
+ printf ("Core %d : - FAILED - Owner Count Mismatch -\n", \
+ core); \
+ } \
+ else { \
+ printf ("Core %d : - FAILED - Denial: %-6d -\n", \
+ core, state); \
+ } \
+ testErrors++; \
+ } \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("\n"); \
+ } while(0);
+
+/**********************************************************************
+ ********************** RM Test Data Structures ***********************
+ **********************************************************************/
+
+/* RM registered transport mapping structure */
+typedef struct trans_map_entry_s {
+ /* Registered RM transport handle */
+ Rm_TransportHandle transportHandle;
+ /* Remote socket tied to the transport handle */
+ sock_name_t *remote_sock;
+} Transport_MapEntry;
+
+/**********************************************************************
+ ********************** Extern Variables ******************************
+ **********************************************************************/
+
+/* Alloc and free OSAL variables */
+extern uint32_t rmMallocCounter;
+extern uint32_t rmFreeCounter;
+
+/**********************************************************************
+ ********************** Global Variables ******************************
+ **********************************************************************/
+
+/* Core number */
+uint16_t coreNum;
+/* Number of errors that occurred during the test */
+uint16_t testErrors;
+
+/* Client instance name (must match with RM Global Resource List (GRL) and policies */
+char rmClientName[RM_NAME_MAX_CHARS] = "RM_Client";
+
+/* Client socket name */
+char rmClientSockName[] = "/tmp/var/run/rm/rm_client";
+
+/* Client socket handle */
+sock_h rmClientSocket;
+
+/* Client instance handles */
+Rm_Handle rmClientHandle = NULL;
+
+/* Client instance service handles */
+Rm_ServiceHandle *rmClientServiceHandle = NULL;
+
+/* Transport map stores the RM transport handle to IPC MessageQ queue mapping */
+Transport_MapEntry rmTransportMap[MAX_MAPPING_ENTRIES];
+
+/* Static allocation response queue */
+Rm_ServiceRespInfo staticResponseQueue[MAX_STATIC_ALLOCATION_RESPS];
+/* Static allocation response queue index */
+uint32_t numStaticResponses;
+
+/* RM response info queue used to store service responses received via the callback function */
+Rm_ServiceRespInfo responseInfoQueue[MAX_QUEUED_SERVICE_RESPONSES];
+
+/* RM resource names (must match resource node names in GRL and policies */
+char resourceNameMemRegion[RM_NAME_MAX_CHARS] = "memory-regions";
+char resourceNameAccumCh[RM_NAME_MAX_CHARS] = "accumulator-ch";
+char resourceNameGpQ[RM_NAME_MAX_CHARS] = "gp-queue";
+char resourceNameAifQ[RM_NAME_MAX_CHARS] = "aif-queue";
+char resourceNameQosCluster[RM_NAME_MAX_CHARS] = "qos-cluster";
+char resourceNameAifRxCh[RM_NAME_MAX_CHARS] = "aif-rx-ch";
+char resourceNameInfraQ[RM_NAME_MAX_CHARS] = "infra-queue";
+
+/* Test RM NameServer name */
+char nameServerNameFavQ[RM_NAME_MAX_CHARS] = "My_Favorite_Queue";
+
+/**********************************************************************
+ *************************** Test Functions ***************************
+ **********************************************************************/
+
+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",
+ strerror(errno));
+ return (NULL);
+ }
+ rm_pkt->pktLenBytes = pktSize;
+ *pktHandle = rm_pkt;
+
+ return(rm_pkt);
+}
+
+void transportFree (Rm_Packet *rm_pkt)
+{
+ uint32_t pkt_size = rm_pkt->pktLenBytes;
+ int32_t status;
+
+ if (rm_pkt) {
+ free (rm_pkt);
+ }
+}
+
+int32_t transportSend (Rm_AppTransportHandle appTransport, Rm_PacketHandle pktHandle)
+{
+ sock_name_t *server_sock_name = (sock_name_t *)appTransport;
+ Rm_Packet *rm_pkt = (Rm_Packet *)pktHandle;
+
+ if (sock_send(rmClientSocket, (char *)rm_pkt, (int) rm_pkt->pktLenBytes, server_sock_name)) {
+ error_msg("send data failed\n");
+ }
+
+ return (0);
+}
+
+void transportReceive (void)
+{
+ int32_t rm_result;
+ int retval;
+ int length = 0;
+ sock_name_t serv_sock_name;
+ sock_name_t server_sock_addr;
+ Rm_Packet *rm_pkt = NULL;
+ struct timeval tv = {0, CLIENT_SOCK_TIMEOUT_USEC};
+ struct sockaddr_un server_addr;
+
+ retval = sock_wait(rmClientSocket, &length, &tv, -1);
+ if (retval == -2) {
+ /* Timeout */
+ return;
+ }
+ else if (retval < 0) {
+ error_msg("Error in reading from socket, error %d\n", retval);
+ return;
+ }
+
+ if (length < sizeof(rm_pkt)) {
+ error_msg("invalid RM message length %d\n", length);
+ return;
+ }
+ rm_pkt = calloc(1, length);
+ if (!rm_pkt) {
+ error_msg("can't malloc for recv'd RM message (err: %s)\n",
+ strerror(errno));
+ return;
+ }
+
+ server_sock_addr.type = sock_addr_e;
+ server_sock_addr.s.addr = &server_addr;
+ retval = sock_recv(rmClientSocket, (char *)rm_pkt, length, &server_sock_addr);
+ if (retval != length) {
+ error_msg("recv RM pkt failed from socket, received = %d, expected = %d\n",
+ retval, length);
+ return;
+ }
+
+ info_msg("received RM pkt of size %d bytes from %s\n", length, server_sock_addr.s.addr->sun_path);
+
+ /* Provide packet to RM Server for processing */
+ if (rm_result = Rm_receivePacket(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle, rm_pkt)) {
+ printf("RM failed to process received packet: %d\n", rm_result);
+ }
+
+ transportFree(rm_pkt);
+}
+
+
+void serviceCallback(Rm_ServiceRespInfo *serviceResponse)
+{
+ uint32_t qIndex = 0;
+
+ /* Populate next free entry in the responseInfoQueue */
+ while (responseInfoQueue[qIndex].serviceId != 0) {
+ qIndex++;
+ if (qIndex == MAX_QUEUED_SERVICE_RESPONSES) {
+ qIndex = 0;
+ }
+ }
+
+ /* Save the response in the response queue for the test task to pick up */
+ memcpy((void *)&responseInfoQueue[qIndex], (void *)serviceResponse, sizeof(Rm_ServiceRespInfo));
+}
+
+void waitForResponse(Rm_ServiceRespInfo *respInfo)
+{
+ uint32_t qIndex = 0;
+
+ if ((respInfo->serviceState == RM_SERVICE_PROCESSING) ||
+ (respInfo->serviceState == RM_SERVICE_PENDING_SERVER_RESPONSE)) {
+ /* Scan responseInfoQueue for the response received via the callback function */
+ while((responseInfoQueue[qIndex].serviceId != respInfo->serviceId) ||
+ (responseInfoQueue[qIndex].rmHandle != respInfo->rmHandle)) {
+ /* Check socket for response packets */
+ transportReceive();
+
+ qIndex++;
+ if (qIndex == MAX_QUEUED_SERVICE_RESPONSES) {
+ qIndex = 0;
+ }
+ }
+
+ memcpy((void *)respInfo, (void *)&responseInfoQueue[qIndex], sizeof(Rm_ServiceRespInfo));
+ memset((void *)&responseInfoQueue[qIndex], 0, sizeof(Rm_ServiceRespInfo));
+ }
+}
+
+void setRmRequest(Rm_ServiceReqInfo *reqInfo, Rm_ServiceType type, const char *resName, int32_t resBase,
+ uint32_t resLen, int32_t resAlign, const char *nsName, int setCallback, Rm_ServiceRespInfo *respInfo)
+{
+ memset((void *)reqInfo, 0, sizeof(Rm_ServiceReqInfo));
+ reqInfo->type = type;
+ reqInfo->resourceName = resName;
+ reqInfo->resourceBase = resBase;
+ reqInfo->resourceLength = resLen;
+ reqInfo->resourceAlignment = resAlign;
+ reqInfo->resourceNsName = nsName;
+ if (setCallback) {
+ reqInfo->callback.serviceCallback = serviceCallback;
+ }
+ memset((void *)respInfo, 0, sizeof(Rm_ServiceRespInfo));
+}
+
+void cleanup(void)
+{
+ Rm_ServiceReqInfo requestInfo;
+ Rm_ServiceRespInfo responseInfo;
+ int32_t result;
+ int32_t finalMallocFree;
+
+ /* Free all allocated resources */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAccumCh,
+ 0, 7, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAccumCh,
+ 40, 2, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameQosCluster,
+ 0, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameQosCluster,
+ 2, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAifQ,
+ 525, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameInfraQ,
+ 800, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameGpQ,
+ 7000, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameGpQ,
+ 7005, 25, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAifRxCh,
+ 0, 6, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAifRxCh,
+ 50, 7, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Cleanup all service ports, transport handles, RM instances, and IPC constructs */
+ result = Rm_serviceCloseHandle(rmClientServiceHandle);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Service handle close failed");
+
+ result = Rm_transportUnregister(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Unregister of Server transport failed");
+
+ sock_close(rmClientSocket);
+
+ result = Rm_delete(rmClientHandle, RM_TEST_TRUE);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Instance delete failed");
+
+ printf ("Core %d : ---------------------------------------------------------\n", coreNum);
+ printf ("Core %d : ------------------ Memory Leak Check --------------------\n", coreNum);
+ printf ("Core %d : - : malloc count | free count -\n", coreNum);
+ printf ("Core %d : - Example Completion : %6d | %6d -\n", coreNum,
+ rmMallocCounter, rmFreeCounter);
+ finalMallocFree = rmMallocCounter - rmFreeCounter;
+ if (finalMallocFree > 0) {
+ printf ("Core %d : - FAILED - %6d unfreed mallocs -\n",
+ coreNum, finalMallocFree);
+ testErrors++;
+ }
+ else if (finalMallocFree < 0) {
+ printf ("Core %d : - FAILED - %6d more frees than mallocs -\n",
+ coreNum, -finalMallocFree);
+ testErrors++;
+ }
+ else {
+ printf ("Core %d : - PASSED -\n",
+ coreNum);
+ }
+ printf ("Core %d : ---------------------------------------------------------\n", coreNum);
+ printf ("\n");
+
+ printf ("Core %d : ---------------------------------------------------------\n", coreNum);
+ printf ("Core %d : ------------------ Example Completion -------------------\n", coreNum);
+ if (testErrors) {
+ printf ("Core %d : - Test Errors: %-32d -\n", coreNum, testErrors);
+ }
+ printf ("Core %d : ---------------------------------------------------------\n", coreNum);
+ printf ("\n");
+}
+
+void client_test(void)
+{
+ Rm_ServiceReqInfo requestInfo;
+ Rm_ServiceRespInfo responseInfo;
+ uint32_t i, j;
+
+ /* Create new NameServer object */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_MAP_TO_NAME, resourceNameGpQ,
+ 1002, 1, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("--------------- Create NameServer Object ----------------",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Retrieve a resource via a NameServer name */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_GET_BY_NAME, NULL,
+ 0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("------- Retrieve Resource Via NameServer Object ---------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ 0, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Allocate the resource returned from the NameServer request */
+ memset((void *)&requestInfo, 0, sizeof(Rm_ServiceReqInfo));
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_INIT;
+ requestInfo.resourceName = responseInfo.resourceName;
+ requestInfo.resourceBase = responseInfo.resourceBase;
+ requestInfo.resourceLength = responseInfo.resourceLength;
+ requestInfo.resourceNsName = NULL;
+ requestInfo.callback.serviceCallback = serviceCallback;
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------- Init Allocate Using Retrieved Resource ---------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Retrieve the resource status via the NameServer name */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_STATUS, NULL,
+ 0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ STATUS_PASS_CHECK("---- Retrieve Resource Status Via NameServer Object -----",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ responseInfo.resourceNumOwners, responseInfo.serviceState, RM_SERVICE_APPROVED, 1);
+
+ /* Free resource via a NameServer name */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, NULL,
+ 0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("--- Free of Retrieved Resource Using NameServer Name ----",
+ coreNum, rmClientName, nameServerNameFavQ,
+ 0, 1, 0, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Delete the NameServer name */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_UNMAP_NAME, NULL,
+ 0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("--------------- Delete NameServer Object ----------------",
+ coreNum, rmClientName, nameServerNameFavQ,
+ 0, 1, 0, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* BEGIN testing expansion/contraction of resource nodes with the AIF RX CH resource */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAifRxCh,
+ 0, 6, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("- Resource Node Expand/Contract Testing (Use Allocate) --",
+ coreNum, rmClientName, resourceNameAifRxCh,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameAifRxCh,
+ 50, 7, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("- Resource Node Expand/Contract Testing (Init Allocate) -",
+ coreNum, rmClientName, resourceNameAifRxCh,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ /* END testing expansion/contraction of resource nodes with the AIF RX CH resource */
+
+ /* BEGIN testing allocations with UNSPECIFIED base and alignment values */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, 5, 4, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------",
+ coreNum, rmClientName, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, 2, 1, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------",
+ coreNum, rmClientName, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, 2, RM_RESOURCE_ALIGNMENT_UNSPECIFIED, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("---- Use Allocation w/ UNSPECIFIED Base & Alignment -----",
+ coreNum, rmClientName, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength,
+ RM_RESOURCE_ALIGNMENT_UNSPECIFIED, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ /* END testing allocations with UNSPECIFIED base and alignment values */
+
+ /* Allocate infrastructure queue shared between Linux kernel and Client */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameInfraQ,
+ 800, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-- Init Allocation of Shared Linux and Client Resource --",
+ coreNum, rmClientName, resourceNameInfraQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* BEGIN Allocating some resources without providing a callback function. RM should block and not return until the result
+ * is returned by the server. */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ,
+ 7000, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("- Init Allocation (RM Blocked Until Resource Returned) --",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameGpQ,
+ 7005, 25, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-- Use Allocation (RM Blocked Until Resource Returned) --",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameGpQ,
+ 7010, 5, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-- Use Allocation (RM Blocked Until Resource Returned) --",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Init allocation of resource already owned by Client should return approved and there should only
+ * be one instance of Client in resource's owner list. */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ,
+ 7011, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("----- Use Allocation of Owned Resource (RM Blocked) -----",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ /* END Allocating some resources without providing a callback function. RM should block and not return
+ * until the result is returned by the Server. */
+
+ /* BEGIN Getting the status of resources from Client and CD */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_STATUS, resourceNameGpQ,
+ 7012, 2, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ STATUS_PASS_CHECK("-- Status Check of Resources from Client (Non-Blocking) -",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ responseInfo.resourceNumOwners, responseInfo.serviceState, RM_SERVICE_APPROVED, 1);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_STATUS, resourceNameGpQ,
+ 4025, 20, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ STATUS_PASS_CHECK("---- Status Check of Resources from Client (Blocking) ---",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ responseInfo.resourceNumOwners, responseInfo.serviceState, RM_SERVICE_APPROVED, 1);
+ /* END Getting the status of resources from Client and CD */
+
+ /* Verify static allocations were validated. Validation responses should have been received after the
+ * first service requests were made on the Client and CD post transport path registration. */
+ while (numStaticResponses > 0) {
+ /* Loop until all static request validations have been received */
+ for (i = 0; i < MAX_STATIC_ALLOCATION_RESPS; i++) {
+ if (staticResponseQueue[i].serviceId != 0) {
+ for (j = 0; j < MAX_QUEUED_SERVICE_RESPONSES; j++) {
+ if ((staticResponseQueue[i].serviceId == responseInfoQueue[j].serviceId) &&
+ (staticResponseQueue[i].rmHandle == responseInfoQueue[j].rmHandle)) {
+ POSITIVE_PASS_CHECK("------------- Static Allocation Validation --------------",
+ coreNum, rmClientName, responseInfoQueue[j].resourceName,
+ responseInfoQueue[j].resourceBase, responseInfoQueue[j].resourceLength,
+ 0, responseInfoQueue[j].serviceState,
+ RM_SERVICE_APPROVED);
+ memset((void *)&staticResponseQueue[i], 0, sizeof(Rm_ServiceRespInfo));
+ memset((void *)&responseInfoQueue[j], 0, sizeof(Rm_ServiceRespInfo));
+ numStaticResponses--;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+#if PRINT_USED_RESOURCES
+ Rm_resourceStatus(rmCdHandle, RM_TEST_TRUE);
+#endif
+}
+
+void connection_setup(void)
+{
+ Rm_TransportCfg rmTransCfg;
+ int32_t rm_result;
+ int i;
+ sock_name_t sock_name;
+ int32_t result = 0;
+ char server_sock_name[] = RM_SERVER_SOCKET_NAME;
+
+ /* Initialize the transport map */
+ for (i = 0; i < MAX_MAPPING_ENTRIES; i++) {
+ rmTransportMap[i].transportHandle = NULL;
+ }
+
+ sock_name.type = sock_name_e;
+ sock_name.s.name = rmClientSockName;
+
+ rmClientSocket = sock_open(&sock_name);
+ if (!rmClientSocket) {
+ error_msg("Client socket open failed\n");
+ exit(EXIT_FAILURE);
+ }
+
+ rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock = calloc(1, sizeof(sock_name_t));
+ rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock->type = sock_name_e;
+ rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock->s.name = calloc(1, strlen(server_sock_name)+1);
+ strncpy(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock->s.name, server_sock_name, strlen(server_sock_name)+1);
+
+ /* Register the Server with the Client instance */
+ rmTransCfg.rmHandle = rmClientHandle;
+ rmTransCfg.appTransportHandle = (Rm_AppTransportHandle) rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock;
+ rmTransCfg.remoteInstType = Rm_instType_SERVER;
+ rmTransCfg.transportCallouts.rmAllocPkt = transportAlloc;
+ rmTransCfg.transportCallouts.rmSendPkt = transportSend;
+ rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle = Rm_transportRegister(&rmTransCfg, &rm_result);
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+ struct stat file_stat;
+ char *static_policy_addr = NULL;
+ Rm_InitCfg rmInitCfg;
+ int status;
+ Rm_ServiceReqInfo requestInfo;
+ Rm_ServiceRespInfo responseInfo;
+ int32_t result;
+
+ printf ("*********************************************************\n");
+ printf ("*************** RM Linux Client Testing *****************\n");
+ printf ("*********************************************************\n");
+
+ printf ("RM Version : 0x%08x\nVersion String: %s\n", Rm_getVersion(), Rm_getVersionStr());
+
+ coreNum = 0;
+ testErrors = 0;
+
+ if (argc > 2)
+ {
+ error_msg("Invalid number of input arguments\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (argc == 2){
+ /* mmap static policy */
+ fd = open(argv[1], O_RDONLY);
+ if (fd == -1) {
+ error_msg("Error opening static policy\n");
+ exit(EXIT_FAILURE);
+ }
+ /* Obtain file size */
+ if (fstat(fd, &file_stat) == -1) {
+ error_msg("Error getting static policy size\n");
+ exit(EXIT_FAILURE);
+ }
+ static_policy_addr = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (static_policy_addr == MAP_FAILED) {
+ error_msg("mmap of static failed\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* Initialize the RM Client - RM must be initialized before anything else in the system */
+ memset(&rmInitCfg, 0, sizeof(rmInitCfg));
+ rmInitCfg.instName = rmClientName;
+ rmInitCfg.instType = Rm_instType_CLIENT;
+ if (static_policy_addr) {
+ rmInitCfg.instCfg.clientCfg.staticPolicy = (void *)static_policy_addr;
+ }
+ rmClientHandle = Rm_init(&rmInitCfg, &result);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Initialization failed");
+
+ printf("\n\nInitialized %s\n\n", rmClientName);
+
+ /* Open Client service handle */
+ rmClientServiceHandle = Rm_serviceOpenHandle(rmClientHandle, &result);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Service handle open failed");
+
+ /* Initialize the static allocation response queue */
+ for (numStaticResponses = 0; numStaticResponses < MAX_STATIC_ALLOCATION_RESPS; numStaticResponses++) {
+ memset((void *)&staticResponseQueue[numStaticResponses], 0, sizeof(Rm_ServiceRespInfo));
+ }
+ numStaticResponses = 0;
+
+ /* Static allocation tests */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameQosCluster,
+ 0, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ POSITIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameQosCluster,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED_STATIC) {
+ memcpy((void *)&staticResponseQueue[numStaticResponses++], (void *)&responseInfo, sizeof(responseInfo));
+ }
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameQosCluster,
+ 2, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ POSITIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameQosCluster,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED_STATIC) {
+ memcpy((void *)&staticResponseQueue[numStaticResponses++], (void *)&responseInfo, sizeof(responseInfo));
+ }
+
+ /* Request resource from Client that can only be allocated to CD according to static policy */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameQosCluster,
+ 1, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ NEGATIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameQosCluster,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+
+ /* Request resource from both Client and CD that is shared according to static policy */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameAifQ,
+ 525, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ POSITIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameAifQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED_STATIC) {
+ memcpy((void *)&staticResponseQueue[numStaticResponses++], (void *)&responseInfo, sizeof(responseInfo));
+ }
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameAifQ,
+ 525, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ POSITIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameAifQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED_STATIC) {
+ memcpy((void *)&staticResponseQueue[numStaticResponses++], (void *)&responseInfo, sizeof(responseInfo));
+ }
+
+ connection_setup();
+ client_test();
+ cleanup();
+
+ return (0);
+}
+
diff --git a/test/k2h/armv7/linux/rm_linux_osal.c b/test/k2h/armv7/linux/rm_linux_osal.c
--- /dev/null
@@ -0,0 +1,188 @@
+/**
+ * @file rm_linux_osal.c
+ *
+ * @brief
+ * This is the OS abstraction layer used by the Resource Manager in Linux.
+ *
+ * \par
+ * ============================================================================
+ * @n (C) Copyright 2012-2013, 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>
+
+/**********************************************************************
+ ****************************** Defines *******************************
+ **********************************************************************/
+
+/**********************************************************************
+ ************************** Global Variables **************************
+ **********************************************************************/
+uint32_t rmMallocCounter = 0;
+uint32_t rmFreeCounter = 0;
+
+/**********************************************************************
+ *************************** 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;
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
diff --git a/test/k2h/armv7/linux/rm_server.c b/test/k2h/armv7/linux/rm_server.c
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+/* Standard includes */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+
+/* Socket Includes */
+#include "sockutils.h"
+#include "sockrmmsg.h"
+
+/* RM includes */
+#include <ti/drv/rm/rm.h>
+#include <ti/drv/rm/rm_transport.h>
+
+#define error_msg printf
+#define info_msg printf
+
+/* 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); \
+ exit(EXIT_FAILURE); \
+ }
+
+/* RM registered transport mapping structure */
+typedef struct trans_map_entry_s {
+ /* Registered RM transport handle */
+ Rm_TransportHandle trans_handle;
+ /* Remote socket tied to the transport handle */
+ sock_name_t *remote_sock;
+ /* Next entry in the transport map */
+ struct trans_map_entry_s *n;
+} trans_map_entry_t;
+
+/**********************************************************************
+ ********************** 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";
+
+sock_h server_sock = NULL;
+
+/**********************************************************************
+ ************************** Server Functions **************************
+ **********************************************************************/
+
+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",
+ strerror(errno));
+ return (NULL);
+ }
+ rm_pkt->pktLenBytes = pktSize;
+ *pktHandle = rm_pkt;
+
+ return(rm_pkt);
+}
+
+void transportFree (Rm_Packet *rm_pkt)
+{
+ uint32_t pkt_size = rm_pkt->pktLenBytes;
+ int32_t status;
+
+ if (rm_pkt) {
+ free (rm_pkt);
+ }
+}
+
+int32_t transportSend (Rm_AppTransportHandle appTransport, Rm_PacketHandle pktHandle)
+{
+ sock_name_t *client_sock_name = (sock_name_t *)appTransport;
+ 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");
+ }
+
+ return (0);
+}
+
+int main(int argc, char *argv[])
+{
+ 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;
+ trans_map_entry_t *trans_map = NULL;
+ trans_map_entry_t *new_map_entry;
+ trans_map_entry_t *map_index;
+ int retval;
+ int length = 0;
+ 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 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);
+ }
+ }
+
+ /* 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;
+ 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);
+
+ 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);
+
+ old_time = time(NULL);
+ info_msg("Begin waiting for messages from Clients\n");
+
+ 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) {
+ error_msg("Error in reading from socket\n");
+ goto loop_continue;
+ }
+
+ if (length < sizeof(rm_pkt)) {
+ error_msg("invalid RM message length %d\n", length);
+ goto loop_continue;
+ }
+ rm_pkt = calloc(1, length);
+ if (!rm_pkt) {
+ error_msg("can't malloc for recv'd RM message (err: %s)\n",
+ strerror(errno));
+ goto loop_continue;
+ }
+
+ client_sock_addr.type = sock_addr_e;
+ client_sock_addr.s.addr = &client_addr;
+ retval = sock_recv(server_sock, (char *)rm_pkt, length, &client_sock_addr);
+ if (retval != length) {
+ error_msg("recv RM pkt failed from socket, received = %d, expected = %d\n",
+ retval, length);
+ goto loop_continue;
+ }
+
+ info_msg("received RM pkt of size %d bytes from %s\n", length, client_sock_addr.s.addr->sun_path);
+
+ map_index = trans_map;
+ while(map_index != NULL) {
+ if (strncmp(map_index->remote_sock->s.addr->sun_path,
+ client_addr.sun_path,
+ sizeof(client_addr.sun_path)) == 0) {
+ break;
+ }
+ map_index = map_index->n;
+ }
+
+ if (!map_index) {
+ new_map_entry = calloc(1, sizeof(*new_map_entry));
+ new_map_entry->remote_sock = calloc(1, sizeof(sock_name_t));
+ new_map_entry->remote_sock->s.addr = calloc(1, sizeof(struct sockaddr_un));
+ new_map_entry->remote_sock->type = sock_addr_e;
+ memcpy(new_map_entry->remote_sock->s.addr, &client_addr, sizeof(struct sockaddr_un));
+
+ /* Register the Client with the Server instance */
+ rm_trans_cfg.rmHandle = server_h;
+ rm_trans_cfg.appTransportHandle = (Rm_AppTransportHandle)new_map_entry->remote_sock;
+ rm_trans_cfg.remoteInstType = Rm_instType_CLIENT;
+ rm_trans_cfg.transportCallouts.rmAllocPkt = transportAlloc;
+ rm_trans_cfg.transportCallouts.rmSendPkt = transportSend;
+ new_map_entry->trans_handle = Rm_transportRegister(&rm_trans_cfg, &rm_result);
+
+ new_map_entry->n = NULL;
+
+ if (trans_map == NULL) {
+ trans_map = new_map_entry;
+ }
+ else {
+ map_index = trans_map;
+
+ while(map_index->n != NULL) {
+ map_index = map_index->n;
+ }
+ map_index->n = new_map_entry;
+ }
+
+ map_index = new_map_entry;
+ }
+
+ /* 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);
+ }
+ transportFree(rm_pkt);
+ old_time = time(NULL);
+loop_continue:
+ /* Cleanups */
+ length = 0;
+ memset(&client_sock_addr, 0, sizeof(sock_name_t));
+ memset(&client_addr, 0, sizeof(struct sockaddr_un));
+ }
+}
+
diff --git a/test/k2h/armv7/linux/sockrmmsg.h b/test/k2h/armv7/linux/sockrmmsg.h
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 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 __SOCKRMMSG_H__
+#define __SOCKRMMSG_H__
+
+#include <stdint.h>
+
+#define RM_SERVER_SOCKET_NAME "/tmp/var/run/rm/rm_server"
+
+#define msg_alloc(p) \
+ do { \
+ p = calloc(1, sizeof(*p)); \
+ if (p) { \
+ p->length = sizeof(*p); \
+ } \
+ } while (0)
+
+#define msg_length(x) ((x) ? (sizeof(*x) + x->length) : 0)
+#define msg_data(x) ((x->length) ? ((char *)x + sizeof(*x)) : NULL)
+
+#endif /* __SOCKRMMSG_H__ */
diff --git a/test/k2h/armv7/linux/sockutils.c b/test/k2h/armv7/linux/sockutils.c
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2013 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.
+ *
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <malloc.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include "sockutils.h"
+
+#define error_msg printf
+
+typedef struct sock_data {
+ struct sockaddr_un addr;
+ fd_set readfds;
+ int fd;
+} sock_data_t;
+
+int check_and_create_path (char *path)
+{
+ char *d = path;
+ if (!d)
+ return -1;
+
+ while (d = strchr(d + 1, '/')) {
+ *d = 0;
+ if (mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
+ if (errno != EEXIST) {
+ *d = '/';
+ error_msg("can't create path %s (error: %s)",
+ path, strerror(errno));
+ return -1;
+ }
+ }
+ *d = '/';
+ }
+ return 0;
+}
+
+sock_h sock_open (sock_name_t *sock_name)
+{
+ sock_data_t *sd = 0;
+ int retval = 0;
+
+ if (!sock_name) {
+ return 0;
+ }
+
+ sd = calloc (1, sizeof(sock_data_t));
+
+ if (sock_name->type == sock_addr_e) {
+ memcpy (&sd->addr, sock_name->s.addr, sizeof(struct sockaddr_un));
+ } else {
+ if (check_and_create_path(sock_name->s.name) < 0) {
+ goto check_n_return;
+ }
+ sd->addr.sun_family = AF_UNIX;
+ strncpy(sd->addr.sun_path, sock_name->s.name, UNIX_PATH_MAX);
+ }
+
+ sd->fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (sd->fd < 0) {
+ error_msg("can't open socket (error: %s)",
+ sd->addr.sun_path, strerror(errno));
+ goto check_n_return;
+ }
+
+ unlink(sd->addr.sun_path);
+ if (bind(sd->fd, (struct sockaddr *) &sd->addr, sizeof(struct sockaddr_un)) < 0) {
+ error_msg("can't bind socket (error: %s)",
+ sd->addr.sun_path, strerror(errno));
+ goto check_n_return;
+ }
+
+ FD_ZERO(&sd->readfds);
+ FD_SET(sd->fd, &sd->readfds);
+
+ retval = (int) sd;
+
+check_n_return:
+ if (!retval) {
+ sock_close ((sock_h) &sd);
+ }
+
+ return ((sock_h) retval);
+}
+
+int sock_close (sock_h handle)
+{
+ sock_data_t *sd = (sock_data_t *) handle;
+
+ if (!sd) {
+ return -1;
+ }
+
+ if (sd->fd)
+ close (sd->fd);
+ free (sd);
+
+ return 0;
+}
+
+int sock_send (sock_h handle, const char *data, int length,
+ sock_name_t *to)
+{
+ int fd;
+ sock_data_t *sd = (sock_data_t *) handle;
+ struct sockaddr_un to_addr;
+
+ if (!to) {
+ return -1;
+ }
+
+ if (to->type == sock_addr_e) {
+ memcpy (&to_addr, to->s.addr, sizeof(struct sockaddr_un));
+ } else {
+ to_addr.sun_family = AF_UNIX;
+ strncpy(to_addr.sun_path, to->s.name, UNIX_PATH_MAX);
+ }
+
+ if (sd) {
+ fd = sd->fd;
+ } else {
+ fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ error_msg("can't open socket (error: %s)",
+ to_addr.sun_path, strerror(errno));
+ return -1;
+ }
+ }
+
+ if (sendto (fd, data, length, 0, (struct sockaddr *) &to_addr,
+ sizeof(struct sockaddr_un)) < 0) {
+ error_msg("can't send data to %s (error: %s)",
+ to_addr.sun_path, strerror(errno));
+ return -1;
+
+ }
+
+ return 0;
+}
+
+int sock_wait (sock_h handle, int *size, struct timeval *timeout, int extern_fd)
+{
+ sock_data_t *sd = (sock_data_t *) handle;
+ int retval;
+ fd_set fds;
+
+ if (!sd) {
+ error_msg("invalid hanlde");
+ return -1;
+ }
+
+ fds = sd->readfds;
+
+ if (extern_fd != -1) {
+ FD_SET(extern_fd, &fds);
+ }
+
+ retval = select(FD_SETSIZE, &fds, NULL, NULL, timeout);
+ if (retval == -1) {
+ error_msg("select failed for %s (error: %s)",
+ sd->addr.sun_path, strerror(errno));
+ return -1;
+ }
+
+ if ((extern_fd != -1) && (FD_ISSET(extern_fd, &fds))) {
+ return 1;
+ }
+
+ if (!FD_ISSET(sd->fd, &fds)) {
+ /* Wait timedout */
+ return -2;
+ }
+
+ if (!retval) {
+ return 0;
+ }
+
+ if (size != 0) {
+ retval = ioctl(sd->fd, FIONREAD, size);
+ if (retval == -1) {
+ error_msg("can't read datagram size for %s (error: %s)",
+ sd->addr.sun_path, strerror(errno));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int sock_recv (sock_h handle, char *data, int length, sock_name_t *from)
+{
+ int size;
+ int retval;
+ fd_set fds;
+ sock_data_t *sd = (sock_data_t *) handle;
+ socklen_t from_length = 0;
+
+ if (!sd) {
+ error_msg("invalid hanlde");
+ return -1;
+ }
+
+ if (from) {
+ if((from->type = sock_addr_e) && (from->s.addr))
+ from_length = sizeof(struct sockaddr_un);
+ else {
+ error_msg("invalid from parameter");
+ return -1;
+ }
+ }
+
+ size = recvfrom(sd->fd, data, length, 0, (struct sockaddr *)((from_length) ? from->s.addr : NULL), &from_length);
+ if (size < 1) {
+ error_msg("can't read datagram from socket for %s (error: %s), size %d",
+ sd->addr.sun_path, strerror(errno), size);
+ return -1;
+ }
+
+ return size;
+
+}
+
diff --git a/test/k2h/armv7/linux/sockutils.h b/test/k2h/armv7/linux/sockutils.h
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 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 __SOCKUTILS_H__
+#define __SOCKUTILS_H__
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 108
+#endif
+
+
+typedef enum {
+ sock_name_e,
+ sock_addr_e
+} sock_name_type;
+
+typedef struct {
+ sock_name_type type;
+ union sock {
+ char *name;
+ struct sockaddr_un *addr;
+ } s;
+} sock_name_t;
+
+#define sock_h void *
+
+sock_h sock_open (sock_name_t *sock_name);
+
+int sock_close (sock_h handle);
+
+int sock_send (sock_h handle, const char *data, int length,
+ sock_name_t *to);
+
+/* Returns: 1 => success (external FD), 0 => success, -1 => error, -2 => timeout */
+int sock_wait (sock_h handle, int *size, struct timeval *timeout, int extern_fd);
+
+int sock_recv (sock_h handle, char *data, int length, sock_name_t *from);
+
+#endif
diff --git a/test/k2k/armv7/linux/README.txt b/test/k2k/armv7/linux/README.txt
--- /dev/null
@@ -0,0 +1,28 @@
+To run rmServer_k2k.out:
+
+copy the following files from rm/test/dts_files to the install directory containing rmServer_k2h/k.out:
+global-resources.dtb
+server-policy.dtb
+linux-evm.dtb [Optional]
+
+The data contained in the latter DTB files is not required to run the RM Server. A new GRL and policy
+can be written and supplied instead of the latter files.
+
+For information on how to create new GRLs and Policies please see:
+http://processors.wiki.ti.com/index.php/MCSDK_UG_Chapter_Developing_System_Mgmt#Resource_Manager
+
+To run the Server:
+$ ./rmServer_k2k.out global-resources.dtb server-policy.dtb linux-evm.dtb
+
+The Server will wait for Client socket connections and service any requests received via those sockets.
+
+
+To run the rmClientTest_k2k.out:
+
+copy the following files from rm/test/dts_files to the install directory containing rmClientTest_k2h/k.out:
+static-policy.dtb
+
+To execute the Client test:
+$ ./rmClientTest_k2k.out static-policy.dtb
+
+The Client test will establish a socket connection with the Server, request resources and then free all resources requested.
diff --git a/test/k2k/armv7/linux/rm_client_test.c b/test/k2k/armv7/linux/rm_client_test.c
--- /dev/null
@@ -0,0 +1,963 @@
+/*
+ * rm_arm_test.c
+ *
+ * Multi-process Resource Manager test that uses sockets to allow a Linux
+ * User-space application to request RM services from a RM Server,
+ * Client Delegate, and Client.
+ *
+ * ============================================================================
+ *
+ * Copyright (c) 2012-2013, Texas Instruments 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:
+ *
+ * * 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.
+ *
+ */
+
+ /* Standard includes */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* Socket Includes */
+#include "sockutils.h"
+#include "sockrmmsg.h"
+
+/* RM Includes */
+#include <ti/drv/rm/rm.h>
+#include <ti/drv/rm/rm_transport.h>
+#include <ti/drv/rm/rm_services.h>
+
+/**********************************************************************
+ ************************** RM Test Symbols ***************************
+ **********************************************************************/
+
+#define error_msg printf
+#define info_msg printf
+
+/* Test FALSE */
+#define RM_TEST_FALSE 0
+/* Test TRUE */
+#define RM_TEST_TRUE 1
+
+/* Socket timeout */
+#define CLIENT_SOCK_TIMEOUT_USEC (500)
+
+/* Application's registered RM transport indices */
+#define SERVER_TO_CLIENT_MAP_ENTRY 0
+/* Maximum number of registered RM transports */
+#define MAX_MAPPING_ENTRIES 1
+
+/* Size of RM static allocation response queue. Must be greater than number of APPROVED
+ * static allocations */
+#define MAX_STATIC_ALLOCATION_RESPS 5
+
+/* Size of RM service response queue */
+#define MAX_QUEUED_SERVICE_RESPONSES 10
+
+/* Error checking macro */
+#define ERROR_CHECK(checkVal, resultVal, rmInstName, printMsg) \
+ if (resultVal != checkVal) { \
+ char errorMsgToPrint[] = printMsg; \
+ printf("Error Core %d : %s : ", coreNum, rmInstName); \
+ printf("%s with error code : %d\n", errorMsgToPrint, resultVal); \
+ testErrors++; \
+ }
+
+#define POSITIVE_PASS_CHECK(title, core, instName, resName, resStart, resLen, align, state, check) \
+ do { \
+ int32_t start = resStart; \
+ int32_t alignment = align; \
+ char titleMsg[] = title; \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("Core %d : %s\n", core, titleMsg); \
+ printf ("Core %d : - Instance Name: %-32s -\n", core, instName); \
+ printf ("Core %d : - Resource Name: %-32s -\n", core, resName); \
+ if (start == RM_RESOURCE_BASE_UNSPECIFIED) { \
+ printf ("Core %d : - Start: UNSPECIFIED -\n", \
+ core); \
+ printf ("Core %d : - Length: %-16d -\n", \
+ core, resLen); \
+ } \
+ else { \
+ printf ("Core %d : - Start: %-16d -\n", \
+ core, resStart); \
+ printf ("Core %d : - End: %-16d -\n", core, \
+ (start + resLen - 1)); \
+ } \
+ if (alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) { \
+ printf ("Core %d : - Alignment: UNSPECIFIED -\n", \
+ core); \
+ } \
+ else { \
+ printf ("Core %d : - Alignment: %-16d -\n", \
+ core, alignment); \
+ } \
+ printf ("Core %d : - -\n", \
+ core); \
+ if (state == check) { \
+ printf ("Core %d : - PASSED -\n", \
+ core); \
+ } \
+ else { \
+ printf ("Core %d : - FAILED - Denial: %-6d -\n", \
+ core, state); \
+ testErrors++; \
+ } \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("\n"); \
+ } while(0);
+
+#define NEGATIVE_PASS_CHECK(title, core, instName, resName, resStart, resLen, align, state, check) \
+ do { \
+ int32_t start = resStart; \
+ int32_t alignment = align; \
+ char titleMsg[] = title; \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("Core %d : %s\n", core, titleMsg); \
+ printf ("Core %d : - Instance Name: %-32s -\n", core, instName); \
+ printf ("Core %d : - Resource Name: %-32s -\n", core, resName); \
+ if (start == RM_RESOURCE_BASE_UNSPECIFIED) { \
+ printf ("Core %d : - Start: UNSPECIFIED -\n", \
+ core); \
+ printf ("Core %d : - Length: %-16d -\n", \
+ core, resLen); \
+ } \
+ else { \
+ printf ("Core %d : - Start: %-16d -\n", \
+ core, resStart); \
+ printf ("Core %d : - End: %-16d -\n", core, \
+ (start + resLen - 1)); \
+ } \
+ if (alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) { \
+ printf ("Core %d : - Alignment: UNSPECIFIED -\n", \
+ core); \
+ } \
+ else { \
+ printf ("Core %d : - Alignment: %-16d -\n", \
+ core, alignment); \
+ } \
+ printf ("Core %d : - -\n", \
+ core); \
+ if (state != check) { \
+ printf ("Core %d : - PASSED - Denial: %-6d -\n", \
+ core, state); \
+ } \
+ else { \
+ printf ("Core %d : - FAILED - Expected Denial -\n", \
+ core); \
+ testErrors++; \
+ } \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("\n"); \
+ } while(0);
+
+#define STATUS_PASS_CHECK(title, core, instName, resName, resStart, resLen, refCnt, state, check, expectRefCnt) \
+ do { \
+ int32_t start = resStart; \
+ char titleMsg[] = title; \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("Core %d : %s\n", core, titleMsg); \
+ printf ("Core %d : - Instance Name: %-32s -\n", core, instName); \
+ printf ("Core %d : - Resource Name: %-32s -\n", core, resName); \
+ printf ("Core %d : - Start: %-16d -\n", \
+ core, resStart); \
+ printf ("Core %d : - End: %-16d -\n", core, \
+ (start + resLen - 1)); \
+ printf ("Core %d : - Expected Owner Count: %-16d -\n", \
+ core, expectRefCnt); \
+ printf ("Core %d : - Returned Owner Count: %-16d -\n", \
+ core, refCnt); \
+ printf ("Core %d : - -\n", core); \
+ if ((state == check) && (refCnt == expectRefCnt)) { \
+ printf ("Core %d : - PASSED -\n", core); \
+ } \
+ else { \
+ if (refCnt != expectRefCnt) { \
+ printf ("Core %d : - FAILED - Owner Count Mismatch -\n", \
+ core); \
+ } \
+ else { \
+ printf ("Core %d : - FAILED - Denial: %-6d -\n", \
+ core, state); \
+ } \
+ testErrors++; \
+ } \
+ printf ("Core %d : ---------------------------------------------------------\n", \
+ core); \
+ printf ("\n"); \
+ } while(0);
+
+/**********************************************************************
+ ********************** RM Test Data Structures ***********************
+ **********************************************************************/
+
+/* RM registered transport mapping structure */
+typedef struct trans_map_entry_s {
+ /* Registered RM transport handle */
+ Rm_TransportHandle transportHandle;
+ /* Remote socket tied to the transport handle */
+ sock_name_t *remote_sock;
+} Transport_MapEntry;
+
+/**********************************************************************
+ ********************** Extern Variables ******************************
+ **********************************************************************/
+
+/* Alloc and free OSAL variables */
+extern uint32_t rmMallocCounter;
+extern uint32_t rmFreeCounter;
+
+/**********************************************************************
+ ********************** Global Variables ******************************
+ **********************************************************************/
+
+/* Core number */
+uint16_t coreNum;
+/* Number of errors that occurred during the test */
+uint16_t testErrors;
+
+/* Client instance name (must match with RM Global Resource List (GRL) and policies */
+char rmClientName[RM_NAME_MAX_CHARS] = "RM_Client";
+
+/* Client socket name */
+char rmClientSockName[] = "/tmp/var/run/rm/rm_client";
+
+/* Client socket handle */
+sock_h rmClientSocket;
+
+/* Client instance handles */
+Rm_Handle rmClientHandle = NULL;
+
+/* Client instance service handles */
+Rm_ServiceHandle *rmClientServiceHandle = NULL;
+
+/* Transport map stores the RM transport handle to IPC MessageQ queue mapping */
+Transport_MapEntry rmTransportMap[MAX_MAPPING_ENTRIES];
+
+/* Static allocation response queue */
+Rm_ServiceRespInfo staticResponseQueue[MAX_STATIC_ALLOCATION_RESPS];
+/* Static allocation response queue index */
+uint32_t numStaticResponses;
+
+/* RM response info queue used to store service responses received via the callback function */
+Rm_ServiceRespInfo responseInfoQueue[MAX_QUEUED_SERVICE_RESPONSES];
+
+/* RM resource names (must match resource node names in GRL and policies */
+char resourceNameMemRegion[RM_NAME_MAX_CHARS] = "memory-regions";
+char resourceNameAccumCh[RM_NAME_MAX_CHARS] = "accumulator-ch";
+char resourceNameGpQ[RM_NAME_MAX_CHARS] = "gp-queue";
+char resourceNameAifQ[RM_NAME_MAX_CHARS] = "aif-queue";
+char resourceNameQosCluster[RM_NAME_MAX_CHARS] = "qos-cluster";
+char resourceNameAifRxCh[RM_NAME_MAX_CHARS] = "aif-rx-ch";
+char resourceNameInfraQ[RM_NAME_MAX_CHARS] = "infra-queue";
+
+/* Test RM NameServer name */
+char nameServerNameFavQ[RM_NAME_MAX_CHARS] = "My_Favorite_Queue";
+
+/**********************************************************************
+ *************************** Test Functions ***************************
+ **********************************************************************/
+
+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",
+ strerror(errno));
+ return (NULL);
+ }
+ rm_pkt->pktLenBytes = pktSize;
+ *pktHandle = rm_pkt;
+
+ return(rm_pkt);
+}
+
+void transportFree (Rm_Packet *rm_pkt)
+{
+ uint32_t pkt_size = rm_pkt->pktLenBytes;
+ int32_t status;
+
+ if (rm_pkt) {
+ free (rm_pkt);
+ }
+}
+
+int32_t transportSend (Rm_AppTransportHandle appTransport, Rm_PacketHandle pktHandle)
+{
+ sock_name_t *server_sock_name = (sock_name_t *)appTransport;
+ Rm_Packet *rm_pkt = (Rm_Packet *)pktHandle;
+
+ if (sock_send(rmClientSocket, (char *)rm_pkt, (int) rm_pkt->pktLenBytes, server_sock_name)) {
+ error_msg("send data failed\n");
+ }
+
+ return (0);
+}
+
+void transportReceive (void)
+{
+ int32_t rm_result;
+ int retval;
+ int length = 0;
+ sock_name_t serv_sock_name;
+ sock_name_t server_sock_addr;
+ Rm_Packet *rm_pkt = NULL;
+ struct timeval tv = {0, CLIENT_SOCK_TIMEOUT_USEC};
+ struct sockaddr_un server_addr;
+
+ retval = sock_wait(rmClientSocket, &length, &tv, -1);
+ if (retval == -2) {
+ /* Timeout */
+ return;
+ }
+ else if (retval < 0) {
+ error_msg("Error in reading from socket, error %d\n", retval);
+ return;
+ }
+
+ if (length < sizeof(rm_pkt)) {
+ error_msg("invalid RM message length %d\n", length);
+ return;
+ }
+ rm_pkt = calloc(1, length);
+ if (!rm_pkt) {
+ error_msg("can't malloc for recv'd RM message (err: %s)\n",
+ strerror(errno));
+ return;
+ }
+
+ server_sock_addr.type = sock_addr_e;
+ server_sock_addr.s.addr = &server_addr;
+ retval = sock_recv(rmClientSocket, (char *)rm_pkt, length, &server_sock_addr);
+ if (retval != length) {
+ error_msg("recv RM pkt failed from socket, received = %d, expected = %d\n",
+ retval, length);
+ return;
+ }
+
+ info_msg("received RM pkt of size %d bytes from %s\n", length, server_sock_addr.s.addr->sun_path);
+
+ /* Provide packet to RM Server for processing */
+ if (rm_result = Rm_receivePacket(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle, rm_pkt)) {
+ printf("RM failed to process received packet: %d\n", rm_result);
+ }
+
+ transportFree(rm_pkt);
+}
+
+
+void serviceCallback(Rm_ServiceRespInfo *serviceResponse)
+{
+ uint32_t qIndex = 0;
+
+ /* Populate next free entry in the responseInfoQueue */
+ while (responseInfoQueue[qIndex].serviceId != 0) {
+ qIndex++;
+ if (qIndex == MAX_QUEUED_SERVICE_RESPONSES) {
+ qIndex = 0;
+ }
+ }
+
+ /* Save the response in the response queue for the test task to pick up */
+ memcpy((void *)&responseInfoQueue[qIndex], (void *)serviceResponse, sizeof(Rm_ServiceRespInfo));
+}
+
+void waitForResponse(Rm_ServiceRespInfo *respInfo)
+{
+ uint32_t qIndex = 0;
+
+ if ((respInfo->serviceState == RM_SERVICE_PROCESSING) ||
+ (respInfo->serviceState == RM_SERVICE_PENDING_SERVER_RESPONSE)) {
+ /* Scan responseInfoQueue for the response received via the callback function */
+ while((responseInfoQueue[qIndex].serviceId != respInfo->serviceId) ||
+ (responseInfoQueue[qIndex].rmHandle != respInfo->rmHandle)) {
+ /* Check socket for response packets */
+ transportReceive();
+
+ qIndex++;
+ if (qIndex == MAX_QUEUED_SERVICE_RESPONSES) {
+ qIndex = 0;
+ }
+ }
+
+ memcpy((void *)respInfo, (void *)&responseInfoQueue[qIndex], sizeof(Rm_ServiceRespInfo));
+ memset((void *)&responseInfoQueue[qIndex], 0, sizeof(Rm_ServiceRespInfo));
+ }
+}
+
+void setRmRequest(Rm_ServiceReqInfo *reqInfo, Rm_ServiceType type, const char *resName, int32_t resBase,
+ uint32_t resLen, int32_t resAlign, const char *nsName, int setCallback, Rm_ServiceRespInfo *respInfo)
+{
+ memset((void *)reqInfo, 0, sizeof(Rm_ServiceReqInfo));
+ reqInfo->type = type;
+ reqInfo->resourceName = resName;
+ reqInfo->resourceBase = resBase;
+ reqInfo->resourceLength = resLen;
+ reqInfo->resourceAlignment = resAlign;
+ reqInfo->resourceNsName = nsName;
+ if (setCallback) {
+ reqInfo->callback.serviceCallback = serviceCallback;
+ }
+ memset((void *)respInfo, 0, sizeof(Rm_ServiceRespInfo));
+}
+
+void cleanup(void)
+{
+ Rm_ServiceReqInfo requestInfo;
+ Rm_ServiceRespInfo responseInfo;
+ int32_t result;
+ int32_t finalMallocFree;
+
+ /* Free all allocated resources */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAccumCh,
+ 0, 7, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAccumCh,
+ 40, 2, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameQosCluster,
+ 0, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameQosCluster,
+ 2, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAifQ,
+ 525, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameInfraQ,
+ 800, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameGpQ,
+ 7000, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameGpQ,
+ 7005, 25, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAifRxCh,
+ 0, 6, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameAifRxCh,
+ 50, 7, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------------------- Resource Cleanup -------------------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Cleanup all service ports, transport handles, RM instances, and IPC constructs */
+ result = Rm_serviceCloseHandle(rmClientServiceHandle);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Service handle close failed");
+
+ result = Rm_transportUnregister(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Unregister of Server transport failed");
+
+ sock_close(rmClientSocket);
+
+ result = Rm_delete(rmClientHandle, RM_TEST_TRUE);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Instance delete failed");
+
+ printf ("Core %d : ---------------------------------------------------------\n", coreNum);
+ printf ("Core %d : ------------------ Memory Leak Check --------------------\n", coreNum);
+ printf ("Core %d : - : malloc count | free count -\n", coreNum);
+ printf ("Core %d : - Example Completion : %6d | %6d -\n", coreNum,
+ rmMallocCounter, rmFreeCounter);
+ finalMallocFree = rmMallocCounter - rmFreeCounter;
+ if (finalMallocFree > 0) {
+ printf ("Core %d : - FAILED - %6d unfreed mallocs -\n",
+ coreNum, finalMallocFree);
+ testErrors++;
+ }
+ else if (finalMallocFree < 0) {
+ printf ("Core %d : - FAILED - %6d more frees than mallocs -\n",
+ coreNum, -finalMallocFree);
+ testErrors++;
+ }
+ else {
+ printf ("Core %d : - PASSED -\n",
+ coreNum);
+ }
+ printf ("Core %d : ---------------------------------------------------------\n", coreNum);
+ printf ("\n");
+
+ printf ("Core %d : ---------------------------------------------------------\n", coreNum);
+ printf ("Core %d : ------------------ Example Completion -------------------\n", coreNum);
+ if (testErrors) {
+ printf ("Core %d : - Test Errors: %-32d -\n", coreNum, testErrors);
+ }
+ printf ("Core %d : ---------------------------------------------------------\n", coreNum);
+ printf ("\n");
+}
+
+void client_test(void)
+{
+ Rm_ServiceReqInfo requestInfo;
+ Rm_ServiceRespInfo responseInfo;
+ uint32_t i, j;
+
+ /* Create new NameServer object */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_MAP_TO_NAME, resourceNameGpQ,
+ 1002, 1, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("--------------- Create NameServer Object ----------------",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, responseInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Retrieve a resource via a NameServer name */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_GET_BY_NAME, NULL,
+ 0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("------- Retrieve Resource Via NameServer Object ---------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ 0, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Allocate the resource returned from the NameServer request */
+ memset((void *)&requestInfo, 0, sizeof(Rm_ServiceReqInfo));
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_INIT;
+ requestInfo.resourceName = responseInfo.resourceName;
+ requestInfo.resourceBase = responseInfo.resourceBase;
+ requestInfo.resourceLength = responseInfo.resourceLength;
+ requestInfo.resourceNsName = NULL;
+ requestInfo.callback.serviceCallback = serviceCallback;
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-------- Init Allocate Using Retrieved Resource ---------",
+ coreNum, rmClientName, responseInfo.resourceName,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Retrieve the resource status via the NameServer name */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_STATUS, NULL,
+ 0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ STATUS_PASS_CHECK("---- Retrieve Resource Status Via NameServer Object -----",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ responseInfo.resourceNumOwners, responseInfo.serviceState, RM_SERVICE_APPROVED, 1);
+
+ /* Free resource via a NameServer name */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, NULL,
+ 0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("--- Free of Retrieved Resource Using NameServer Name ----",
+ coreNum, rmClientName, nameServerNameFavQ,
+ 0, 1, 0, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Delete the NameServer name */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_UNMAP_NAME, NULL,
+ 0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("--------------- Delete NameServer Object ----------------",
+ coreNum, rmClientName, nameServerNameFavQ,
+ 0, 1, 0, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* BEGIN testing expansion/contraction of resource nodes with the AIF RX CH resource */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAifRxCh,
+ 0, 6, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("- Resource Node Expand/Contract Testing (Use Allocate) --",
+ coreNum, rmClientName, resourceNameAifRxCh,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameAifRxCh,
+ 50, 7, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("- Resource Node Expand/Contract Testing (Init Allocate) -",
+ coreNum, rmClientName, resourceNameAifRxCh,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ /* END testing expansion/contraction of resource nodes with the AIF RX CH resource */
+
+ /* BEGIN testing allocations with UNSPECIFIED base and alignment values */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, 5, 4, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------",
+ coreNum, rmClientName, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, 2, 1, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------",
+ coreNum, rmClientName, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, 2, RM_RESOURCE_ALIGNMENT_UNSPECIFIED, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("---- Use Allocation w/ UNSPECIFIED Base & Alignment -----",
+ coreNum, rmClientName, resourceNameAccumCh,
+ RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength,
+ RM_RESOURCE_ALIGNMENT_UNSPECIFIED, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ /* END testing allocations with UNSPECIFIED base and alignment values */
+
+ /* Allocate infrastructure queue shared between Linux kernel and Client */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameInfraQ,
+ 800, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-- Init Allocation of Shared Linux and Client Resource --",
+ coreNum, rmClientName, resourceNameInfraQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* BEGIN Allocating some resources without providing a callback function. RM should block and not return until the result
+ * is returned by the server. */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ,
+ 7000, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("- Init Allocation (RM Blocked Until Resource Returned) --",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameGpQ,
+ 7005, 25, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-- Use Allocation (RM Blocked Until Resource Returned) --",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameGpQ,
+ 7010, 5, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("-- Use Allocation (RM Blocked Until Resource Returned) --",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+ /* Init allocation of resource already owned by Client should return approved and there should only
+ * be one instance of Client in resource's owner list. */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ,
+ 7011, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ POSITIVE_PASS_CHECK("----- Use Allocation of Owned Resource (RM Blocked) -----",
+ coreNum, rmClientName, resourceNameGpQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+ /* END Allocating some resources without providing a callback function. RM should block and not return
+ * until the result is returned by the Server. */
+
+ /* BEGIN Getting the status of resources from Client and CD */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_STATUS, resourceNameGpQ,
+ 7012, 2, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ STATUS_PASS_CHECK("-- Status Check of Resources from Client (Non-Blocking) -",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ responseInfo.resourceNumOwners, responseInfo.serviceState, RM_SERVICE_APPROVED, 1);
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_STATUS, resourceNameGpQ,
+ 4025, 20, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ waitForResponse(&responseInfo);
+ STATUS_PASS_CHECK("---- Status Check of Resources from Client (Blocking) ---",
+ coreNum, rmClientName, responseInfo.resourceName,
+ responseInfo.resourceBase, responseInfo.resourceLength,
+ responseInfo.resourceNumOwners, responseInfo.serviceState, RM_SERVICE_APPROVED, 1);
+ /* END Getting the status of resources from Client and CD */
+
+ /* Verify static allocations were validated. Validation responses should have been received after the
+ * first service requests were made on the Client and CD post transport path registration. */
+ while (numStaticResponses > 0) {
+ /* Loop until all static request validations have been received */
+ for (i = 0; i < MAX_STATIC_ALLOCATION_RESPS; i++) {
+ if (staticResponseQueue[i].serviceId != 0) {
+ for (j = 0; j < MAX_QUEUED_SERVICE_RESPONSES; j++) {
+ if ((staticResponseQueue[i].serviceId == responseInfoQueue[j].serviceId) &&
+ (staticResponseQueue[i].rmHandle == responseInfoQueue[j].rmHandle)) {
+ POSITIVE_PASS_CHECK("------------- Static Allocation Validation --------------",
+ coreNum, rmClientName, responseInfoQueue[j].resourceName,
+ responseInfoQueue[j].resourceBase, responseInfoQueue[j].resourceLength,
+ 0, responseInfoQueue[j].serviceState,
+ RM_SERVICE_APPROVED);
+ memset((void *)&staticResponseQueue[i], 0, sizeof(Rm_ServiceRespInfo));
+ memset((void *)&responseInfoQueue[j], 0, sizeof(Rm_ServiceRespInfo));
+ numStaticResponses--;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+#if PRINT_USED_RESOURCES
+ Rm_resourceStatus(rmCdHandle, RM_TEST_TRUE);
+#endif
+}
+
+void connection_setup(void)
+{
+ Rm_TransportCfg rmTransCfg;
+ int32_t rm_result;
+ int i;
+ sock_name_t sock_name;
+ int32_t result = 0;
+ char server_sock_name[] = RM_SERVER_SOCKET_NAME;
+
+ /* Initialize the transport map */
+ for (i = 0; i < MAX_MAPPING_ENTRIES; i++) {
+ rmTransportMap[i].transportHandle = NULL;
+ }
+
+ sock_name.type = sock_name_e;
+ sock_name.s.name = rmClientSockName;
+
+ rmClientSocket = sock_open(&sock_name);
+ if (!rmClientSocket) {
+ error_msg("Client socket open failed\n");
+ exit(EXIT_FAILURE);
+ }
+
+ rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock = calloc(1, sizeof(sock_name_t));
+ rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock->type = sock_name_e;
+ rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock->s.name = calloc(1, strlen(server_sock_name)+1);
+ strncpy(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock->s.name, server_sock_name, strlen(server_sock_name)+1);
+
+ /* Register the Server with the Client instance */
+ rmTransCfg.rmHandle = rmClientHandle;
+ rmTransCfg.appTransportHandle = (Rm_AppTransportHandle) rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock;
+ rmTransCfg.remoteInstType = Rm_instType_SERVER;
+ rmTransCfg.transportCallouts.rmAllocPkt = transportAlloc;
+ rmTransCfg.transportCallouts.rmSendPkt = transportSend;
+ rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle = Rm_transportRegister(&rmTransCfg, &rm_result);
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+ struct stat file_stat;
+ char *static_policy_addr = NULL;
+ Rm_InitCfg rmInitCfg;
+ int status;
+ Rm_ServiceReqInfo requestInfo;
+ Rm_ServiceRespInfo responseInfo;
+ int32_t result;
+
+ printf ("*********************************************************\n");
+ printf ("*************** RM Linux Client Testing *****************\n");
+ printf ("*********************************************************\n");
+
+ printf ("RM Version : 0x%08x\nVersion String: %s\n", Rm_getVersion(), Rm_getVersionStr());
+
+ coreNum = 0;
+ testErrors = 0;
+
+ if (argc > 2)
+ {
+ error_msg("Invalid number of input arguments\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (argc == 2){
+ /* mmap static policy */
+ fd = open(argv[1], O_RDONLY);
+ if (fd == -1) {
+ error_msg("Error opening static policy\n");
+ exit(EXIT_FAILURE);
+ }
+ /* Obtain file size */
+ if (fstat(fd, &file_stat) == -1) {
+ error_msg("Error getting static policy size\n");
+ exit(EXIT_FAILURE);
+ }
+ static_policy_addr = mmap(NULL, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (static_policy_addr == MAP_FAILED) {
+ error_msg("mmap of static failed\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* Initialize the RM Client - RM must be initialized before anything else in the system */
+ memset(&rmInitCfg, 0, sizeof(rmInitCfg));
+ rmInitCfg.instName = rmClientName;
+ rmInitCfg.instType = Rm_instType_CLIENT;
+ if (static_policy_addr) {
+ rmInitCfg.instCfg.clientCfg.staticPolicy = (void *)static_policy_addr;
+ }
+ rmClientHandle = Rm_init(&rmInitCfg, &result);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Initialization failed");
+
+ printf("\n\nInitialized %s\n\n", rmClientName);
+
+ /* Open Client service handle */
+ rmClientServiceHandle = Rm_serviceOpenHandle(rmClientHandle, &result);
+ ERROR_CHECK(RM_OK, result, rmClientName, "Service handle open failed");
+
+ /* Initialize the static allocation response queue */
+ for (numStaticResponses = 0; numStaticResponses < MAX_STATIC_ALLOCATION_RESPS; numStaticResponses++) {
+ memset((void *)&staticResponseQueue[numStaticResponses], 0, sizeof(Rm_ServiceRespInfo));
+ }
+ numStaticResponses = 0;
+
+ /* Static allocation tests */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameQosCluster,
+ 0, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ POSITIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameQosCluster,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED_STATIC) {
+ memcpy((void *)&staticResponseQueue[numStaticResponses++], (void *)&responseInfo, sizeof(responseInfo));
+ }
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameQosCluster,
+ 2, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ POSITIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameQosCluster,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED_STATIC) {
+ memcpy((void *)&staticResponseQueue[numStaticResponses++], (void *)&responseInfo, sizeof(responseInfo));
+ }
+
+ /* Request resource from Client that can only be allocated to CD according to static policy */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameQosCluster,
+ 1, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ NEGATIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameQosCluster,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+
+ /* Request resource from both Client and CD that is shared according to static policy */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameAifQ,
+ 525, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ POSITIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameAifQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED_STATIC) {
+ memcpy((void *)&staticResponseQueue[numStaticResponses++], (void *)&responseInfo, sizeof(responseInfo));
+ }
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameAifQ,
+ 525, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ POSITIVE_PASS_CHECK("---------------- Static Init Allocation -----------------",
+ coreNum, rmClientName, resourceNameAifQ,
+ requestInfo.resourceBase, requestInfo.resourceLength,
+ requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED_STATIC);
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED_STATIC) {
+ memcpy((void *)&staticResponseQueue[numStaticResponses++], (void *)&responseInfo, sizeof(responseInfo));
+ }
+
+ connection_setup();
+ client_test();
+ cleanup();
+
+ return (0);
+}
+
diff --git a/test/k2k/armv7/linux/rm_linux_osal.c b/test/k2k/armv7/linux/rm_linux_osal.c
--- /dev/null
@@ -0,0 +1,188 @@
+/**
+ * @file rm_linux_osal.c
+ *
+ * @brief
+ * This is the OS abstraction layer used by the Resource Manager in Linux.
+ *
+ * \par
+ * ============================================================================
+ * @n (C) Copyright 2012-2013, 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>
+
+/**********************************************************************
+ ****************************** Defines *******************************
+ **********************************************************************/
+
+/**********************************************************************
+ ************************** Global Variables **************************
+ **********************************************************************/
+uint32_t rmMallocCounter = 0;
+uint32_t rmFreeCounter = 0;
+
+/**********************************************************************
+ *************************** 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;
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
diff --git a/test/k2k/armv7/linux/rm_server.c b/test/k2k/armv7/linux/rm_server.c
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+/* Standard includes */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+
+/* Socket Includes */
+#include "sockutils.h"
+#include "sockrmmsg.h"
+
+/* RM includes */
+#include <ti/drv/rm/rm.h>
+#include <ti/drv/rm/rm_transport.h>
+
+#define error_msg printf
+#define info_msg printf
+
+/* 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); \
+ exit(EXIT_FAILURE); \
+ }
+
+/* RM registered transport mapping structure */
+typedef struct trans_map_entry_s {
+ /* Registered RM transport handle */
+ Rm_TransportHandle trans_handle;
+ /* Remote socket tied to the transport handle */
+ sock_name_t *remote_sock;
+ /* Next entry in the transport map */
+ struct trans_map_entry_s *n;
+} trans_map_entry_t;
+
+/**********************************************************************
+ ********************** 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";
+
+sock_h server_sock = NULL;
+
+/**********************************************************************
+ ************************** Server Functions **************************
+ **********************************************************************/
+
+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",
+ strerror(errno));
+ return (NULL);
+ }
+ rm_pkt->pktLenBytes = pktSize;
+ *pktHandle = rm_pkt;
+
+ return(rm_pkt);
+}
+
+void transportFree (Rm_Packet *rm_pkt)
+{
+ uint32_t pkt_size = rm_pkt->pktLenBytes;
+ int32_t status;
+
+ if (rm_pkt) {
+ free (rm_pkt);
+ }
+}
+
+int32_t transportSend (Rm_AppTransportHandle appTransport, Rm_PacketHandle pktHandle)
+{
+ sock_name_t *client_sock_name = (sock_name_t *)appTransport;
+ 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");
+ }
+
+ return (0);
+}
+
+int main(int argc, char *argv[])
+{
+ 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;
+ trans_map_entry_t *trans_map = NULL;
+ trans_map_entry_t *new_map_entry;
+ trans_map_entry_t *map_index;
+ int retval;
+ int length = 0;
+ 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 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);
+ }
+ }
+
+ /* 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;
+ 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);
+
+ 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);
+
+ old_time = time(NULL);
+ info_msg("Begin waiting for messages from Clients\n");
+
+ 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) {
+ error_msg("Error in reading from socket\n");
+ goto loop_continue;
+ }
+
+ if (length < sizeof(rm_pkt)) {
+ error_msg("invalid RM message length %d\n", length);
+ goto loop_continue;
+ }
+ rm_pkt = calloc(1, length);
+ if (!rm_pkt) {
+ error_msg("can't malloc for recv'd RM message (err: %s)\n",
+ strerror(errno));
+ goto loop_continue;
+ }
+
+ client_sock_addr.type = sock_addr_e;
+ client_sock_addr.s.addr = &client_addr;
+ retval = sock_recv(server_sock, (char *)rm_pkt, length, &client_sock_addr);
+ if (retval != length) {
+ error_msg("recv RM pkt failed from socket, received = %d, expected = %d\n",
+ retval, length);
+ goto loop_continue;
+ }
+
+ info_msg("received RM pkt of size %d bytes from %s\n", length, client_sock_addr.s.addr->sun_path);
+
+ map_index = trans_map;
+ while(map_index != NULL) {
+ if (strncmp(map_index->remote_sock->s.addr->sun_path,
+ client_addr.sun_path,
+ sizeof(client_addr.sun_path)) == 0) {
+ break;
+ }
+ map_index = map_index->n;
+ }
+
+ if (!map_index) {
+ new_map_entry = calloc(1, sizeof(*new_map_entry));
+ new_map_entry->remote_sock = calloc(1, sizeof(sock_name_t));
+ new_map_entry->remote_sock->s.addr = calloc(1, sizeof(struct sockaddr_un));
+ new_map_entry->remote_sock->type = sock_addr_e;
+ memcpy(new_map_entry->remote_sock->s.addr, &client_addr, sizeof(struct sockaddr_un));
+
+ /* Register the Client with the Server instance */
+ rm_trans_cfg.rmHandle = server_h;
+ rm_trans_cfg.appTransportHandle = (Rm_AppTransportHandle)new_map_entry->remote_sock;
+ rm_trans_cfg.remoteInstType = Rm_instType_CLIENT;
+ rm_trans_cfg.transportCallouts.rmAllocPkt = transportAlloc;
+ rm_trans_cfg.transportCallouts.rmSendPkt = transportSend;
+ new_map_entry->trans_handle = Rm_transportRegister(&rm_trans_cfg, &rm_result);
+
+ new_map_entry->n = NULL;
+
+ if (trans_map == NULL) {
+ trans_map = new_map_entry;
+ }
+ else {
+ map_index = trans_map;
+
+ while(map_index->n != NULL) {
+ map_index = map_index->n;
+ }
+ map_index->n = new_map_entry;
+ }
+
+ map_index = new_map_entry;
+ }
+
+ /* 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);
+ }
+ transportFree(rm_pkt);
+ old_time = time(NULL);
+loop_continue:
+ /* Cleanups */
+ length = 0;
+ memset(&client_sock_addr, 0, sizeof(sock_name_t));
+ memset(&client_addr, 0, sizeof(struct sockaddr_un));
+ }
+}
+
diff --git a/test/k2k/armv7/linux/sockrmmsg.h b/test/k2k/armv7/linux/sockrmmsg.h
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 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 __SOCKRMMSG_H__
+#define __SOCKRMMSG_H__
+
+#include <stdint.h>
+
+#define RM_SERVER_SOCKET_NAME "/tmp/var/run/rm/rm_server"
+
+#define msg_alloc(p) \
+ do { \
+ p = calloc(1, sizeof(*p)); \
+ if (p) { \
+ p->length = sizeof(*p); \
+ } \
+ } while (0)
+
+#define msg_length(x) ((x) ? (sizeof(*x) + x->length) : 0)
+#define msg_data(x) ((x->length) ? ((char *)x + sizeof(*x)) : NULL)
+
+#endif /* __SOCKRMMSG_H__ */
diff --git a/test/k2k/armv7/linux/sockutils.c b/test/k2k/armv7/linux/sockutils.c
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2013 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.
+ *
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <malloc.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include "sockutils.h"
+
+#define error_msg printf
+
+typedef struct sock_data {
+ struct sockaddr_un addr;
+ fd_set readfds;
+ int fd;
+} sock_data_t;
+
+int check_and_create_path (char *path)
+{
+ char *d = path;
+ if (!d)
+ return -1;
+
+ while (d = strchr(d + 1, '/')) {
+ *d = 0;
+ if (mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
+ if (errno != EEXIST) {
+ *d = '/';
+ error_msg("can't create path %s (error: %s)",
+ path, strerror(errno));
+ return -1;
+ }
+ }
+ *d = '/';
+ }
+ return 0;
+}
+
+sock_h sock_open (sock_name_t *sock_name)
+{
+ sock_data_t *sd = 0;
+ int retval = 0;
+
+ if (!sock_name) {
+ return 0;
+ }
+
+ sd = calloc (1, sizeof(sock_data_t));
+
+ if (sock_name->type == sock_addr_e) {
+ memcpy (&sd->addr, sock_name->s.addr, sizeof(struct sockaddr_un));
+ } else {
+ if (check_and_create_path(sock_name->s.name) < 0) {
+ goto check_n_return;
+ }
+ sd->addr.sun_family = AF_UNIX;
+ strncpy(sd->addr.sun_path, sock_name->s.name, UNIX_PATH_MAX);
+ }
+
+ sd->fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (sd->fd < 0) {
+ error_msg("can't open socket (error: %s)",
+ sd->addr.sun_path, strerror(errno));
+ goto check_n_return;
+ }
+
+ unlink(sd->addr.sun_path);
+ if (bind(sd->fd, (struct sockaddr *) &sd->addr, sizeof(struct sockaddr_un)) < 0) {
+ error_msg("can't bind socket (error: %s)",
+ sd->addr.sun_path, strerror(errno));
+ goto check_n_return;
+ }
+
+ FD_ZERO(&sd->readfds);
+ FD_SET(sd->fd, &sd->readfds);
+
+ retval = (int) sd;
+
+check_n_return:
+ if (!retval) {
+ sock_close ((sock_h) &sd);
+ }
+
+ return ((sock_h) retval);
+}
+
+int sock_close (sock_h handle)
+{
+ sock_data_t *sd = (sock_data_t *) handle;
+
+ if (!sd) {
+ return -1;
+ }
+
+ if (sd->fd)
+ close (sd->fd);
+ free (sd);
+
+ return 0;
+}
+
+int sock_send (sock_h handle, const char *data, int length,
+ sock_name_t *to)
+{
+ int fd;
+ sock_data_t *sd = (sock_data_t *) handle;
+ struct sockaddr_un to_addr;
+
+ if (!to) {
+ return -1;
+ }
+
+ if (to->type == sock_addr_e) {
+ memcpy (&to_addr, to->s.addr, sizeof(struct sockaddr_un));
+ } else {
+ to_addr.sun_family = AF_UNIX;
+ strncpy(to_addr.sun_path, to->s.name, UNIX_PATH_MAX);
+ }
+
+ if (sd) {
+ fd = sd->fd;
+ } else {
+ fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ error_msg("can't open socket (error: %s)",
+ to_addr.sun_path, strerror(errno));
+ return -1;
+ }
+ }
+
+ if (sendto (fd, data, length, 0, (struct sockaddr *) &to_addr,
+ sizeof(struct sockaddr_un)) < 0) {
+ error_msg("can't send data to %s (error: %s)",
+ to_addr.sun_path, strerror(errno));
+ return -1;
+
+ }
+
+ return 0;
+}
+
+int sock_wait (sock_h handle, int *size, struct timeval *timeout, int extern_fd)
+{
+ sock_data_t *sd = (sock_data_t *) handle;
+ int retval;
+ fd_set fds;
+
+ if (!sd) {
+ error_msg("invalid hanlde");
+ return -1;
+ }
+
+ fds = sd->readfds;
+
+ if (extern_fd != -1) {
+ FD_SET(extern_fd, &fds);
+ }
+
+ retval = select(FD_SETSIZE, &fds, NULL, NULL, timeout);
+ if (retval == -1) {
+ error_msg("select failed for %s (error: %s)",
+ sd->addr.sun_path, strerror(errno));
+ return -1;
+ }
+
+ if ((extern_fd != -1) && (FD_ISSET(extern_fd, &fds))) {
+ return 1;
+ }
+
+ if (!FD_ISSET(sd->fd, &fds)) {
+ /* Wait timedout */
+ return -2;
+ }
+
+ if (!retval) {
+ return 0;
+ }
+
+ if (size != 0) {
+ retval = ioctl(sd->fd, FIONREAD, size);
+ if (retval == -1) {
+ error_msg("can't read datagram size for %s (error: %s)",
+ sd->addr.sun_path, strerror(errno));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int sock_recv (sock_h handle, char *data, int length, sock_name_t *from)
+{
+ int size;
+ int retval;
+ fd_set fds;
+ sock_data_t *sd = (sock_data_t *) handle;
+ socklen_t from_length = 0;
+
+ if (!sd) {
+ error_msg("invalid hanlde");
+ return -1;
+ }
+
+ if (from) {
+ if((from->type = sock_addr_e) && (from->s.addr))
+ from_length = sizeof(struct sockaddr_un);
+ else {
+ error_msg("invalid from parameter");
+ return -1;
+ }
+ }
+
+ size = recvfrom(sd->fd, data, length, 0, (struct sockaddr *)((from_length) ? from->s.addr : NULL), &from_length);
+ if (size < 1) {
+ error_msg("can't read datagram from socket for %s (error: %s), size %d",
+ sd->addr.sun_path, strerror(errno), size);
+ return -1;
+ }
+
+ return size;
+
+}
+
diff --git a/test/k2k/armv7/linux/sockutils.h b/test/k2k/armv7/linux/sockutils.h
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 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 __SOCKUTILS_H__
+#define __SOCKUTILS_H__
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 108
+#endif
+
+
+typedef enum {
+ sock_name_e,
+ sock_addr_e
+} sock_name_type;
+
+typedef struct {
+ sock_name_type type;
+ union sock {
+ char *name;
+ struct sockaddr_un *addr;
+ } s;
+} sock_name_t;
+
+#define sock_h void *
+
+sock_h sock_open (sock_name_t *sock_name);
+
+int sock_close (sock_h handle);
+
+int sock_send (sock_h handle, const char *data, int length,
+ sock_name_t *to);
+
+/* Returns: 1 => success (external FD), 0 => success, -1 => error, -2 => timeout */
+int sock_wait (sock_h handle, int *size, struct timeval *timeout, int extern_fd);
+
+int sock_recv (sock_h handle, char *data, int length, sock_name_t *from);
+
+#endif