/***********************************************************************
*
* Copyright (c) 2006-2007 Broadcom Corporation
* All Rights Reserved
*
* <:label-BRCM:2006:DUAL/GPL:standard
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as published by
* the Free Software Foundation (the "GPL").
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* A copy of the GPL is available at http://www.broadcom.com/licenses/GPLv2.php, or by
* writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* :>
*
************************************************************************/
#include "cms.h"
#include "cms_mem.h"
#include "cms_msg.h"
#include "cms_log.h"
#include "cms_fil.h"
#include "oal.h"
#ifdef DESKTOP_LINUX
UINT16 desktopFakePid = 30;
#endif
#define CMS_MSG_PUTBACK_Q_IS_EMPTY(h) (((CmsMsgHandle *) (h))->putBackQueue == NULL)
/* message API functions go here */
CmsRet cmsMsg_initWithFlags(CmsEntityId eid, UINT32 flags, void **msgHandle)
{
return oalMsg_initWithFlags(eid, flags, msgHandle);
}
CmsRet cmsMsg_init(CmsEntityId eid, void **msgHandle)
{
const CmsEntityInfo *eInfo;
if ((eInfo = cmsEid_getEntityInfo(eid)) == NULL)
{
cmsLog_error("Invalid eid %d", eid);
return CMSRET_INVALID_ARGUMENTS;
}
return oalMsg_initWithFlags(eid,
eInfo->flags & EIF_MULTIPLE_INSTANCES,
msgHandle);
}
void cmsMsg_cleanup(void **msgHandle)
{
CmsMsgHandle *handle = (CmsMsgHandle *) *msgHandle;
CmsMsgHeader *msg;
/* free any queued up messages */
while ((msg = handle->putBackQueue) != NULL)
{
handle->putBackQueue = msg->next;
CMSMEM_FREE_BUF_AND_NULL_PTR(msg);
}
return oalMsg_cleanup(msgHandle);
}
CmsRet cmsMsg_send(void *msgHandle, const CmsMsgHeader *buf)
{
CmsMsgHandle *handle = (CmsMsgHandle *) msgHandle;
#ifdef DESKTOP_LINUX
if (handle->standalone)
{
/* just pretend to have sent the message */
return CMSRET_SUCCESS;
}
#endif
return oalMsg_send(handle->commFd, buf);
}
CmsRet cmsMsg_sendReply(void *msgHandle, const CmsMsgHeader *msg, CmsRet retCode)
{
CmsMsgHandle *handle = (CmsMsgHandle *) msgHandle;
CmsMsgHeader replyMsg = EMPTY_MSG_HEADER;
replyMsg.dst = msg->src;
replyMsg.src = msg->dst;
replyMsg.type = msg->type;
replyMsg.flags_request = 0;
replyMsg.flags_response = 1;
replyMsg.flags_bounceIfNotRunning = msg->flags_bounceIfNotRunning;
/* do we want to copy any other flags? */
replyMsg.wordData = retCode;
return oalMsg_send(handle->commFd, &replyMsg);
}
static CmsRet sendAndGetReply(void *msgHandle, const CmsMsgHeader *buf, UINT32 *timeout)
{
CmsMsgHandle *handle = (CmsMsgHandle *) msgHandle;
CmsMsgType sentType;
CmsMsgHeader *replyMsg=NULL;
UBOOL8 doReceive=TRUE;
CmsRet ret;
#ifdef DESKTOP_LINUX
if (handle->standalone)
{
CmsMsgHeader *msg = (CmsMsgHeader *) buf;
/*
* Standalone mode occurs during unittests.
* Pretend to send out the message and get a successful reply.
*/
if ((msg->type == CMS_MSG_START_APP) || (msg->type == CMS_MSG_RESTART_APP))
{
/* For the START_APP and RESTART_APP messages, the expected return value is the pid. */
return desktopFakePid++;
}
else
{
return CMSRET_SUCCESS;
}
}
#endif
/* remember what msg type we sent out. */
sentType = buf->type;
ret = oalMsg_send(handle->commFd, buf);
if (ret != CMSRET_SUCCESS)
{
return ret;
}
while (doReceive)
{
ret = oalMsg_receive(handle->commFd, &replyMsg, timeout);
if (ret != CMSRET_SUCCESS)
{
if ((timeout == NULL) ||
((timeout != NULL) && (ret != CMSRET_TIMED_OUT)))
{
cmsLog_error("error during get of reply, ret=%d", ret);
}
cmsMem_free(replyMsg);
doReceive = FALSE;
}
else
{
if (replyMsg->type == sentType)
{
ret = replyMsg->wordData;
doReceive = FALSE;
CMSMEM_FREE_BUF_AND_NULL_PTR(replyMsg);
}
else
{
/* we got a mesage, but it was not the reply we were expecting.
* Could be an event msg. Push it back on the put-back queue and
* keep trying to get the message we really want.
*/
cmsMsg_putBack(msgHandle, &replyMsg);
replyMsg = NULL;
/*
* I don't know how much time was used to get this response message
* we weren't expecting, but approximate some elapsed time by
* reducing the timeout by 1/3. This ensures that we will
* eventually timeout if we don't get the response msg we are expecting.
*/
if (timeout != NULL)
{
(*timeout) = (*timeout) / 3;
}
}
}
}
if (!CMS_MSG_PUTBACK_Q_IS_EMPTY(msgHandle))
{
cmsMsg_sendNoop(msgHandle);
}
return ret;
}
static CmsRet sendAndGetReplyBuf(void *msgHandle, const CmsMsgHeader *buf, CmsMsgHeader **replyBuf, UINT32 *timeout)
{
CmsMsgHandle *handle = (CmsMsgHandle *) msgHandle;
CmsMsgType sentType;
CmsMsgHeader *replyMsg=NULL;
UBOOL8 doReceive=TRUE;
CmsRet ret;
/* remember what msg type we sent out. */
sentType = buf->type;
ret = oalMsg_send(handle->commFd, buf);
if (ret != CMSRET_SUCCESS)
{
return ret;
}
while (doReceive)
{
ret = oalMsg_receive(handle->commFd, &replyMsg, timeout);
if (ret != CMSRET_SUCCESS)
{
if ((timeout == NULL) ||
((timeout != NULL) && (ret != CMSRET_TIMED_OUT)))
{
cmsLog_error("error during get of reply, ret=%d", ret);
}
cmsMem_free(replyMsg);
doReceive = FALSE;
}
else
{
if (replyMsg->type == sentType)
{
memcpy((*replyBuf), replyMsg, (sizeof(CmsMsgHeader) + replyMsg->dataLength));
doReceive = FALSE;
CMSMEM_FREE_BUF_AND_NULL_PTR(replyMsg);
}
else
{
/* we got a mesage, but it was not the reply we were expecting.
* Could be an event msg. Push it back on the put-back queue and
* keep trying to get the message we really want.
*/
cmsMsg_putBack(msgHandle, &replyMsg);
replyMsg = NULL;
/*
* I don't know how much time was used to get this response message
* we weren't expecting, but approximate some elapsed time by
* reducing the timeout by 1/3. This ensures that we will
* eventually timeout if we don't get the response msg we are expecting.
*/
if (timeout != NULL)
{
(*timeout) = (*timeout) / 3;
}
}
}
}
if (!CMS_MSG_PUTBACK_Q_IS_EMPTY(msgHandle))
{
cmsMsg_sendNoop(msgHandle);
}
return ret;
}
CmsRet cmsMsg_sendAndGetReply(void *msgHandle, const CmsMsgHeader *buf)
{
return (sendAndGetReply(msgHandle, buf, NULL));
}
CmsRet cmsMsg_sendAndGetReplyWithTimeout(void *msgHandle,
const CmsMsgHeader *buf,
UINT32 timeoutMilliSeconds)
{
UINT32 timeout = timeoutMilliSeconds;
return (sendAndGetReply(msgHandle, buf, &timeout));
}
CmsRet cmsMsg_sendAndGetReplyBuf(void *msgHandle, const CmsMsgHeader *buf, CmsMsgHeader **replyBuf)
{
return (sendAndGetReplyBuf(msgHandle, buf,
评论0