示例#1
0
void L1InterfaceStub::processServiceAllocateResponse(CDataAccessor & accessor)
{
    const UInt32 channel_id = accessor.getChannelID();
    ConnectivityAgentError err(static_cast<ConnectivityAgentError::AgentErrorCodes>
            (accessor.getErrorCode()));

    LOG4CPLUS_TRACE_METHOD(logger, "L1InterfaceStub::processServiceAllocateResponse() => "
            "Channel allocated responce id = "
            + convertIntegerToString(channel_id) + ", err = " +
            convertIntegerToString((int)err.getCode()));

    iviLink::Ipc::DirectionID dirId = -1;

    /// @todo better processing of error codes. PIlin, 31.08.12
    /// There is the error case with wrong processing:
    /// 1) if response with error, obtain ERR_DEFERRED from failAllocateChannel and
    ///   begin deallocation procedure.
    /// 2) if there is no known dirId, channel also needs to be deallocated, even
    /// if its allocation was successfull.
    ///
    /// Here we must initialize channel deallocation procedure, because we unable
    /// to send some message - there is no such in existing protocol.

    if (err.isNoError())
    {
        err = endAllocateChannel(channel_id, dirId);

        if (err.getCode() == ConnectivityAgentError::ERROR_DEFERRED)
        {
            LOG4CPLUS_INFO(logger, "L1InterfaceStub::processServiceAllocateResponse() => "
                    "was E_TRANSITION_AGENT, messaging to other side");
            accessor.setErrorCode(BaseError::IVILINK_NO_ERROR);
            err = sendRequest(accessor);
        }
    }

    if (!err.isNoError() || dirId == -1)
    {
        // SEQ_E_4

        LOG4CPLUS_ERROR(logger, "L1InterfaceStub::processServiceAllocateResponse() => "
                "failed channel allocation");

        failAllocateChannel(channel_id, dirId);
        accessor.setErrorCode(err.getCode());
    }

    if (dirId != -1)
    {
        LOG4CPLUS_INFO(logger, "L1InterfaceStub::processServiceAllocateResponse() => "
                "message about allocation result");
        sendIpcNotification(accessor, dirId);
    }
    else
    {
        LOG4CPLUS_ERROR(logger, "L1InterfaceStub::processServiceAllocateResponse() => "
                "unknown client, failing channel");
    }
}
示例#2
0
ConnectivityAgentError L1InterfaceStub::sendRequest( CDataAccessor & accessor)
{
    LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__);
    Buffer buf;
    UInt32 offset = 0;

    accessor.printContent();

    buf.getFilledSize() = accessor.getObjectSize() + sizeof(UInt16);
    buf.reserveSize(buf.getFilledSize());

    *reinterpret_cast<UInt16*> (buf.getData() + offset) =
            ByteOrder::hton16((UInt16)buf.getFilledSize());
    offset += 2;

    *reinterpret_cast<UInt32*> (buf.getData() + offset) =
            ByteOrder::hton32(accessor.getOpCode());
    offset += 4;

    *reinterpret_cast<UInt32*> (buf.getData() + offset) =
            ByteOrder::hton32(accessor.getChannelID());
    offset += 4;

    *reinterpret_cast<UInt32*> (buf.getData() + offset) =
            ByteOrder::hton32(accessor.getDataSize());
    offset += 4;

    *reinterpret_cast<UInt32*> (buf.getData() + offset) =
            ByteOrder::hton32(accessor.getErrorCode());
    offset += 4;

    if (accessor.getDataSize())
    {
        memcpy(buf.getData() + offset,accessor.getData(), accessor.getDataSize() );
    }

    ConnectivityAgentError ret = mL1ChannelRegistry[CA_SERVICE_CHANNEL].
            mpSourceAgent->fillBuffer(buf);

    buf.forgetData();

    return ret;
}
void CConnectivityAgentProxy::receiveAllocateChannelResponse(CDataAccessor & accessor)
{
	UInt32 channel_id = accessor.getChannelID();
	ERROR_CODE err = static_cast<ERROR_CODE>(accessor.getErrorCode());

	LOG4CPLUS_TRACE_METHOD(logger,
			"CConnectivityAgentProxy::receiveAllocateChannelResponse"
					" channel_id = " + convertIntegerToString(channel_id) + " err = "
					+ convertIntegerToString((int) err));

	mAllocateRequestCond.lock();
	{
		tAllocateRequestMap::iterator it = mAllocateRequestMap.find(channel_id);
		if (it == mAllocateRequestMap.end())
		{
			LOG4CPLUS_WARN(logger,
					"CConnectivityAgentProxy::receiveAllocateChannelResponse() => channel is not requested");
		} else
		{
			AllocateRequestInfo & info = it->second;
			info.mRequestDone = true;
			info.mResult = err;

			if (ERR_OK == err)
			{
				mRegistryMutex.lockWrite();
				mChannelRegistry[channel_id].mType = info.mType;
				mChannelRegistry[channel_id].mpClient = info.mpClient;
				mChannelRegistry[channel_id].mChannelBuffer.reserveSize(MAX_SIZE);
				mRegistryMutex.unlockWrite();
			}

			mAllocateRequestCond.broadcast();
		}
	}
	mAllocateRequestCond.unlock();
}
示例#4
0
void L1InterfaceStub::processServiceAllocateRequest(CDataAccessor & accessor)
{
    const UInt32 channel_id = accessor.getChannelID();
    const UInt32 prio = *reinterpret_cast<UInt32*>(accessor.getData());
    ConnectivityAgentError err(static_cast<ConnectivityAgentError::AgentErrorCodes>
            (accessor.getErrorCode()));
    LOG4CPLUS_INFO(logger, "L1InterfaceStub::processServiceAllocateRequest()=>"
            "Allocate channel prio = " + convertIntegerToString(prio) +
            " id =" + convertIntegerToString(accessor.getChannelID()));

    iviLink::Ipc::DirectionID dirId = -1;

    accessor.setOpCode(E_ALLOCATE_CHANNEL_RESP);
    accessor.resetData();

    if (!err.isNoError())
    {
        // SEQ_E_3
        failAllocateChannel(channel_id, dirId);

        accessor.setErrorCode(err.getCode());
    }
    else
    {
        mRequestedMapMutex.lock();
        mRegistryMutex.lock();
        {
            err = beginAllocateChannel(static_cast<TChannelPriority>(prio), channel_id,
                    false, dirId);

            if (err.getCode() != ConnectivityAgentError::ERROR_DEFERRED)
            {
                // sending the result to other side
                // SEQ_E_4 or ok
                accessor.setErrorCode(err.getCode());
                sendRequest(accessor);
            }
        }
        mRegistryMutex.unlock();
        mRequestedMapMutex.unlock();

        if (err.getCode() == ConnectivityAgentError::ERROR_DEFERRED)
        {
            // all ok, we will wait for the client requesting this channel
            // setting timeout

            LOG4CPLUS_INFO(logger, "L1InterfaceStub::processServiceAllocateRequest() => "
                    "channel wasn't requested yet ->set channel to wait and trigger timeout");

            assert(mTimeoutManager);
            mTimeoutManager->addSubscriber(
                    new RequestTimeout(E_ALLOCATE_CHANNEL,channel_id, this), 250000);
            return;
        }
    }

    if (!err.isNoError())
    {
        // messagign about failed channel allocation
        // SEQ_E_4

        if (dirId != -1)
        {
            sendIpcNotification(accessor, dirId);
        }
    }
}
ERROR_CODE CConnectivityAgentProxy::allocateChannel(TChannelPriority prio, UInt32 channel_id,
		IChannelObserver* observer)
{
	LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__);
	LOG4CPLUS_INFO(logger,
			"CConnectivityAgentProxy::allocateChannel(type = " + convertIntegerToString((int) prio)
					+ ", id = " + convertIntegerToString(channel_id) + " ), this = "
					+ convertIntegerToString((intptr_t) this));

	ERROR_CODE ret = ERR_FAIL;
	if ((channel_id > 0) && (channel_id <= 0xFFFF) && (NULL != observer))
	{
		mRegistryMutex.lockWrite();
		bool channel_unknown = mChannelRegistry.find(channel_id) == mChannelRegistry.end();
		mRegistryMutex.unlockWrite();

		if (channel_unknown)
		{
			mAllocateRequestCond.lock();
			bool channel_requested = mAllocateRequestMap.find(channel_id)
					!= mAllocateRequestMap.end();
			if (channel_requested)
			{
				ret = ERR_IN_PROGRESS;
				channel_unknown = false;
				LOG4CPLUS_WARN(logger,
						"CConnectivityAgentProxy::allocateChannel() => ERROR: channel allocation in progress!");
			} else
			{
				LOG4CPLUS_INFO(logger,
						"CConnectivityAgentProxy::allocateChannel() => insert request");
				mAllocateRequestMap.insert(
						std::make_pair(channel_id,
								AllocateRequestInfo(prio, observer, false, ERR_UNKNOWN)));
			}
			mAllocateRequestCond.unlock();
		}

		if (channel_unknown)
		{
			CDataAccessor requestDA;
			requestDA.setChannelID(channel_id);
			requestDA.setOpCode(E_ALLOCATE_CHANNEL);
			UInt32 data = prio;
			requestDA.setData(reinterpret_cast<UInt8 *>(&data), sizeof(UInt32));
			UInt8* buf = new UInt8[requestDA.getObjectSize()];
			requestDA.copyToRawArray(buf);

			UInt8 respBuf[100];
			UInt32 respSize = sizeof(respBuf);
			CError err = mpIpc->request(mMsgIdGen.next(), buf, requestDA.getObjectSize(), respBuf,
					respSize);
			delete[] buf;

			if (!err.isNoError())
			{
				LOG4CPLUS_WARN(logger, static_cast<std::string>(err));
				ret = ERR_FAIL;

				mAllocateRequestCond.lock();
				mAllocateRequestMap.erase(channel_id);
				mAllocateRequestCond.unlock();

				LOG4CPLUS_WARN(logger,
						"CConnectivityAgentProxy::allocateChannel() => ERROR: failed to send request");
			} else
			{
				CDataAccessor responseDA;

				if (respSize > 0)
				{
					responseDA = CDataAccessor(respBuf, respSize);
					ret = static_cast<ERROR_CODE>(responseDA.getErrorCode());

					mAllocateRequestCond.lock();
					mAllocateRequestMap.erase(channel_id);
					mAllocateRequestCond.unlock();

					LOG4CPLUS_WARN(logger,
							"CConnectivityAgentProxy::allocateChannel() => ERROR: got error response");
				} else
				{
					mAllocateRequestCond.lock();
					while (true)
					{
						tAllocateRequestMap::iterator it = mAllocateRequestMap.find(channel_id);
						if (it == mAllocateRequestMap.end())
						{
							ret = ERR_FAIL;
							LOG4CPLUS_WARN(logger,
									"CConnectivityAgentProxy::allocateChannel() => ERROR: request was removed");
							break;
						}

						AllocateRequestInfo & info = it->second;
						if (info.mRequestDone)
						{
							LOG4CPLUS_INFO(logger,
									"CConnectivityAgentProxy::allocateChannel() => request done");
							ret = info.mResult;
							mAllocateRequestMap.erase(it);
							break;
						}

						LOG4CPLUS_INFO(logger,
								"CConnectivityAgentProxy::allocateChannel() => before wait");
						mAllocateRequestCond.wait();
						LOG4CPLUS_INFO(logger,
								"CConnectivityAgentProxy::allocateChannel() => after wait");
					}
					mAllocateRequestCond.unlock();
				} // if response empty
			} // if no ipc err

		} else
		{
			LOG4CPLUS_ERROR(logger,
					"CConnectivityAgentProxy::allocateChannel() => ERROR: channel already exists! ");
			ret = ERR_NUMBER_BUSY;
		}
	}

	return ret;
}