Fix MessageQ to support more than 52 instances in QNX
authorvwan@ti.com <vwan@ti.com>
Wed, 16 Apr 2014 22:36:35 +0000 (15:36 -0700)
committerChris Ring <cring@ti.com>
Wed, 14 May 2014 22:26:19 +0000 (15:26 -0700)
This fix changes MessageQ to obtain a port number assignment from MessageQCopy
and use it as local queue id as opposed to having MessageQ manage the ids
itself. This ensures the port number to be above 1024, so that it does not
collide with any reserved port such as the one for the Name Service.

This addresses CQ SDOCM00104834.

Signed-off-by: VW <vwan@ti.com>
qnx/include/TiIpcFxns.h
qnx/src/api/MessageQ.c
qnx/src/ipc3x_dev/ti/syslink/inc/_MessageQ_daemon.h [new file with mode: 0644]
qnx/src/ipc3x_dev/ti/syslink/ipc/hlos/knl/MessageQ_daemon.c
qnx/src/ipc3x_dev/ti/syslink/ipc/hlos/knl/Qnx/messageq_devctl.c
qnx/src/utils/TiIpcFxns.c

index 8b81b865f94b5d4fbe27cdfcd5130d06bb2452dc..9128059af5642a63a93f18b99e6de5d30d1fd7c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Texas Instruments Incorporated
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,4 +31,4 @@
  */
 
 extern int Connect(int fd, UInt16 procId, int dst);
-extern int BindAddr(int fd, UInt32 localAddr);
+extern int BindAddr(int fd, UInt32 localAddr);
index d225ec432f0e18f78daaac4f9005b996bd7b5ef8..397ec49b8f0f1ab29bdae9f41b597fbc33eb1f8b 100644 (file)
 
 /* More magic rpmsg port numbers: */
 #define MESSAGEQ_RPMSG_PORT       61
-#define MESSAGEQ_RPMSG_MAXSIZE   512
+#define MESSAGEQ_RPMSG_MAXSIZE    512
 #define RPMSG_RESERVED_ADDRESSES  (1024)
 
+/* MessageQ needs local address bound to be a 16-bit value */
+#define MAX_LOCAL_ADDR            0x10000
+
 /* Trace flag settings: */
 #define TRACESHIFT    12
 #define TRACEMASK     0x1000
@@ -238,7 +241,7 @@ MessageQ_ModuleObject * MessageQ_module = &MessageQ_state;
  */
 
 /* This is a helper function to initialize a message. */
-static Int transportCreateEndpoint(int * fd, UInt16 queueIndex);
+static Int transportCreateEndpoint(int * fd, UInt16 queueIndex);
 static Int transportCloseEndpoint(int fd);
 static Int transportGet(int fd, MessageQ_Msg * retMsg);
 static Int transportPut(MessageQ_Msg msg, UInt16 dstId, UInt16 dstProcId);
@@ -349,33 +352,43 @@ MessageQ_Handle MessageQ_create (String name, const MessageQ_Params * params)
         cmdArgs.args.create.nameLen = 0;
     }
 
+    /* Create the generic obj */
+    obj = (MessageQ_Object *)calloc(1, sizeof (MessageQ_Object));
+    if (obj == NULL) {
+        PRINTVERBOSE0("MessageQ_create: memory allocation failed\n")
+        return NULL;
+    }
+
+    PRINTVERBOSE2("MessageQ_create: creating endpoint for: %s, \
+       queueIndex: %d\n", name, queueIndex)
+    status = transportCreateEndpoint(&obj->ipcFd, &queueIndex);
+    if (status < 0) {
+        goto cleanup;
+    }
+
+    /*
+     * We expect the endpoint creation to return a port number from
+     * the MessageQCopy layer. This port number will be greater than
+     * 1024 and less than 0x10000. Use this number as the queueIndex.
+     */
+    cmdArgs.args.create.queueId = queueIndex;
+
     status = MessageQDrv_ioctl (CMD_MESSAGEQ_CREATE, &cmdArgs);
     if (status < 0) {
         PRINTVERBOSE1("MessageQ_create: API (through IOCTL) failed, \
             status=%d\n", status)
-        return NULL;
+        goto cleanup;
     }
 
-    /* Create the generic obj */
-    obj = (MessageQ_Object *)calloc(1, sizeof (MessageQ_Object));
-
     if (params != NULL) {
        /* Populate the params member */
         memcpy((Ptr) &obj->params, (Ptr)params, sizeof (MessageQ_Params));
     }
 
     procId = MultiProc_self();
-    queueIndex = (MessageQ_QueueIndex)cmdArgs.args.create.queueId;
     obj->queue = cmdArgs.args.create.queueId;
     obj->serverHandle = cmdArgs.args.create.handle;
 
-    PRINTVERBOSE2("MessageQ_create: creating endpoint for: %s, \
-       queueIndex: %d\n", name, queueIndex)
-    status = transportCreateEndpoint(&obj->ipcFd, queueIndex);
-    if (status < 0) {
-       goto cleanup;
-    }
-
     /*
      * Now, to support MessageQ_unblock() functionality, create an event object.
      * Writing to this event will unblock the select() call in MessageQ_get().
@@ -384,9 +397,12 @@ MessageQ_Handle MessageQ_create (String name, const MessageQ_Params * params)
         printf ("MessageQ_create: pipe creation failed: %d, %s\n",
                    errno, strerror(errno));
         status = MessageQ_E_FAIL;
+        obj->unblockFdW = obj->unblockFdR = -1;
+    }
+    else {
+        obj->unblockFdW = fildes[1];
+        obj->unblockFdR = fildes[0];
     }
-    obj->unblockFdW = fildes[1];
-    obj->unblockFdR = fildes[0];
 
 cleanup:
     /* Cleanup if fail: */
@@ -408,21 +424,31 @@ Int MessageQ_delete (MessageQ_Handle * handlePtr)
     MessageQ_Object * obj       = NULL;
     MessageQDrv_CmdArgs cmdArgs;
 
+    assert(handlePtr != NULL);
     obj = (MessageQ_Object *) (*handlePtr);
-
-    cmdArgs.args.deleteMessageQ.handle = obj->serverHandle;
-    status = MessageQDrv_ioctl (CMD_MESSAGEQ_DELETE, &cmdArgs);
-    if (status < 0) {
-        PRINTVERBOSE1("MessageQ_delete: API (through IOCTL) failed, \
-            status=%d\n", status)
+    assert(obj != NULL);
+
+    if (obj->serverHandle != NULL) {
+        cmdArgs.args.deleteMessageQ.handle = obj->serverHandle;
+        status = MessageQDrv_ioctl (CMD_MESSAGEQ_DELETE, &cmdArgs);
+        if (status < 0) {
+            PRINTVERBOSE1("MessageQ_delete: API (through IOCTL) failed, \
+                status=%d\n", status)
+        }
     }
 
     /* Close the fds used for MessageQ_unblock(): */
-    close(obj->unblockFdW);
-    close(obj->unblockFdR);
+    if (obj->unblockFdW >= 0) {
+        close(obj->unblockFdW);
+    }
+    if (obj->unblockFdR >= 0) {
+        close(obj->unblockFdR);
+    }
 
     /* Close the communication endpoint: */
-    status = transportCloseEndpoint(obj->ipcFd);
+    if (obj->ipcFd >= 0) {
+        transportCloseEndpoint(obj->ipcFd);
+    }
 
     /* Now free the obj */
     free (obj);
@@ -721,6 +747,7 @@ SizeT MessageQ_sharedMemReq (Ptr sharedAddr)
 Int MessageQ_attach (UInt16 remoteProcId, Ptr sharedAddr)
 {
     Int     status = MessageQ_S_SUCCESS;
+    UInt32  localAddr;
     int     ipcFd;
     int     err;
 
@@ -751,7 +778,7 @@ Int MessageQ_attach (UInt16 remoteProcId, Ptr sharedAddr)
              * local endpoint
              */
             Connect(ipcFd, remoteProcId, MESSAGEQ_RPMSG_PORT);
-            err = BindAddr(ipcFd, TIIPC_ADDRANY);
+            err = BindAddr(ipcFd, &localAddr);
             if (err < 0) {
                 status = MessageQ_E_FAIL;
                 printf ("MessageQ_attach: bind failed: %d, %s\n",
@@ -829,10 +856,11 @@ Void MessageQ_msgInit (MessageQ_Msg msg)
  *
  * Create a communication endpoint to receive messages.
  */
-static Int transportCreateEndpoint(int * fd, UInt16 queueIndex)
+static Int transportCreateEndpoint(int * fd, UInt16 queueIndex)
 {
     Int          status    = MessageQ_S_SUCCESS;
     int          err;
+    UInt32       localAddr;
 
     /* Create a fd to the ti-ipc to receive messages for this messageQ */
     *fd= open("/dev/tiipc", O_RDWR);
@@ -846,13 +874,27 @@ static Int transportCreateEndpoint(int * fd, UInt16 queueIndex)
 
     PRINTVERBOSE1("transportCreateEndpoint: opened fd: %d\n", *fd)
 
-    err = BindAddr(*fd, (UInt32)queueIndex);
+    err = BindAddr(*fd, &localAddr);
     if (err < 0) {
         status = MessageQ_E_FAIL;
-        printf ("transportCreateEndpoint: bind failed: %d, %s\n",
+        printf("transportCreateEndpoint: bind failed: %d, %s\n",
                   errno, strerror(errno));
+
+        close(*fd);
+        goto exit;
+    }
+
+    if (localAddr >= MAX_LOCAL_ADDR) {
+        status = MessageQ_E_FAIL;
+        printf("transportCreateEndpoint: local address returned is"
+            "by BindAddr is greater than max supported\n");
+
+        close(*fd);
+        goto exit;
     }
 
+    *queueIndex = localAddr;
+
 exit:
     return (status);
 }
diff --git a/qnx/src/ipc3x_dev/ti/syslink/inc/_MessageQ_daemon.h b/qnx/src/ipc3x_dev/ti/syslink/inc/_MessageQ_daemon.h
new file mode 100644 (file)
index 0000000..7e6fc7b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+/*
+ *  ======== _MessageQ_daemon.h ========
+ *
+ *  Internal header
+ *
+ */
+
+#ifndef _MESSAGEQ_DAEMON_H
+#define _MESSAGEQ_DAEMON_H
+
+#include <ti/ipc/MessageQ.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * Internal MessageQ_create function that accepts a local queueId assignment
+ * (i.e. bottom 16-bit of its queueId)
+ */
+MessageQ_Handle MessageQ_createWithQueueId(String name, const
+    MessageQ_Params * params, UInt32 localQueueId);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* _MESSAGEQ_DAEMON_H */
index 8a46478c2be7304c5b059d5d6b83fa78511de894..7a96268c46de319de14e69bc179dc555fd2f125c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Texas Instruments Incorporated
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -198,6 +198,8 @@ typedef struct MessageQ_Object {
     /*! Instance specific creation parameters */
     MessageQ_QueueId        queue;
     /* Unique id */
+    MessageQ_QueueIndex     queueIndex;
+    /* 16-bit index into the queues array */
     Ptr                     nsKey;
     /* NameServer key */
     Int                     ownerPid;
@@ -357,10 +359,13 @@ Void MessageQ_Params_init(MessageQ_Params * params)
     return;
 }
 
+
+
 /*
  *   Function to create a MessageQ object for receiving.
  */
-MessageQ_Handle MessageQ_create(String name, const MessageQ_Params * params)
+MessageQ_Handle MessageQ_createWithQueueId(String name, const MessageQ_Params * params,
+    UInt32 queueId)
 {
     Int                 status    = MessageQ_S_SUCCESS;
     MessageQ_Object   * obj    = NULL;
@@ -403,8 +408,9 @@ MessageQ_Handle MessageQ_create(String name, const MessageQ_Params * params)
     }
 
     procId = MultiProc_self();
-    /* create globally unique messageQ ID: */
-    obj->queue = (MessageQ_QueueId)(((UInt32)procId << 16) | queueIndex);
+    obj->queueIndex = queueIndex;
+    /* create globally unique messageQ ID */
+    obj->queue = (MessageQ_QueueId)(((UInt32)procId << 16) | queueId);
     obj->ownerPid = 0;
 
     if (name != NULL) {
@@ -422,6 +428,7 @@ MessageQ_Handle MessageQ_create(String name, const MessageQ_Params * params)
     return ((MessageQ_Handle)obj);
 }
 
+
 /*
  * Function to delete a MessageQ object for a specific slave processor.
  */
@@ -435,9 +442,9 @@ Int MessageQ_delete(MessageQ_Handle * handlePtr)
 
     LOG1("MessageQ_delete: deleting %p\n", obj)
 
-    queue = MessageQ_module->queues[(MessageQ_QueueIndex)(obj->queue)];
+    queue = MessageQ_module->queues[obj->queueIndex];
     if (queue != obj) {
-        LOG1("    ERROR: obj != MessageQ_module->queues[%d]\n", (MessageQ_QueueIndex)(obj->queue))
+        LOG1("    ERROR: obj != MessageQ_module->queues[%d]\n", (MessageQ_QueueIndex)(obj->queueIndex))
     }
 
     if (obj->nsKey != NULL) {
@@ -456,7 +463,7 @@ Int MessageQ_delete(MessageQ_Handle * handlePtr)
     pthread_mutex_lock(&(MessageQ_module->gate));
 
     /* Clear the MessageQ obj from array. */
-    MessageQ_module->queues[(MessageQ_QueueIndex)(obj->queue)] = NULL;
+    MessageQ_module->queues[(MessageQ_QueueIndex)obj->queueIndex] = NULL;
 
     /* Release the local lock */
     pthread_mutex_unlock(&(MessageQ_module->gate));
index d06568fb1f91535787c9841404153e11322f0ae2..7c6c0b82d502ac7ec5e7707ff18372c09dca3214 100644 (file)
@@ -6,7 +6,7 @@
  *
  *  ============================================================================
  *
- *  Copyright (c) 2013, Texas Instruments Incorporated
+ *  Copyright (c) 2013-2014, Texas Instruments Incorporated
  *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that the following conditions
@@ -61,6 +61,7 @@
 /* Module specific header files */
 #include <ti/ipc/MessageQ.h>
 #include <ti/syslink/inc/MessageQDrvDefs.h>
+#include <ti/syslink/inc/_MessageQ_daemon.h>
 
 /* Function prototypes */
 int syslink_messageq_getconfig(resmgr_context_t *ctp, io_devctl_t *msg,
@@ -154,6 +155,8 @@ int syslink_messageq_create(resmgr_context_t *ctp, io_devctl_t *msg,
         (_DEVCTL_DATA (msg->o));
     MessageQ_Params *local_createparams = NULL;
     String local_createname = NULL;
+    UInt32 local_queueId;
+
     out->apiStatus = MessageQ_S_SUCCESS;
 
     if (cargs->args.create.params) {
@@ -166,8 +169,11 @@ int syslink_messageq_create(resmgr_context_t *ctp, io_devctl_t *msg,
             local_createname = (String)(cargs+1);
     }
 
-    out->args.create.handle = MessageQ_create (local_createname,
-        local_createparams);
+    local_queueId = cargs->args.create.queueId;
+
+    /* Force MessageQ to use the id passed in as the bottom 16-bit of its queue id */
+    out->args.create.handle = MessageQ_createWithQueueId(local_createname,
+        local_createparams, local_queueId);
     GT_assert (curTrace, (out->args.create.handle != NULL));
 
     /* Set failure status if create has failed. */
index 5df1065184df737c25834de16dc225321cdc0f9c..ea0f4e65910d9ffd7c1da354334f67b9da733ffa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Texas Instruments Incorporated
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -77,19 +77,21 @@ int Connect(int fd, UInt16 procId, int dst)
     return(0);
 }
 
-int BindAddr(int fd, UInt32 localAddr)
+int BindAddr(int fd, UInt32 localAddr)
 {
     tiipc_local_params src_addr;
     int         err;
 
-    src_addr.local_addr = localAddr;
+    src_addr.local_addr = TIIPC_ADDRANY;
 
     /* This calls MessageQCopy_create():  */
     err = ioctl(fd, TIIPC_IOCSETLOCAL, &src_addr);
     if (err >= 0) {
         PRINTVERBOSE2("IOCSETLOCAL: bound fd: %d, src addr: %d\n",
-                      fd, localAddr)
+                      fd, src_addr.local_addr)
     }
 
+    *localAddr = src_addr.local_addr;
+
     return (err);
 }