void L1InterfaceStub::processServiceDeallocateRequest(CDataAccessor & accessor) { UInt32 channel_id = accessor.getChannelID(); LOG4CPLUS_INFO(logger, "L1InterfaceStub::processServiceDeallocateRequest() => " "Channel deallocate request id = " + convertIntegerToString(channel_id)); ConnectivityAgentError ret = deallocateChannel(channel_id ); accessor.setOpCode(E_DEALLOCATE_CHANNEL_RESP); UInt32 data = ret.getCode(); accessor.setData(reinterpret_cast<UInt8 *>(&data), sizeof(UInt32)); sendRequest(accessor); if (ret.isNoError()) { LOG4CPLUS_INFO(logger, "L1InterfaceStub::processServiceDeallocateRequest() => " "channel successfully deallocated. " "Notifying client"); iviLink::Ipc::DirectionID dirId; bool found = false; mRegistryMutex.lock(); tChannelsRegistryMap::iterator iter = mL1ChannelRegistry.find(accessor.getChannelID()); if (mL1ChannelRegistry.end() != iter) { dirId = iter->second.mClientDir; found = true; LOG4CPLUS_INFO(logger, "L1InterfaceStub::processServiceDeallocateRequest() => " "channel found in registry - removing"); mL1ChannelRegistry.erase(accessor.getChannelID()); } mRegistryMutex.unlock(); if (found) { accessor.setOpCode(E_DEALLOCATE_CHANNEL_NTF); UInt8* buf = new UInt8[accessor.getObjectSize()]; accessor.copyToRawArray(buf); BaseError err = mpIpc->asyncRequest(mMsgIdGen.next(), buf, accessor.getObjectSize(), &dirId); if (!err.isNoError()) { LOG4CPLUS_WARN(logger, static_cast<std::string>(err)); } delete[] buf; } } // ret == OK }
bool L1InterfaceStub::processClientDeallocateRequest(CDataAccessor & accessor, const iviLink::Ipc::DirectionID dirId) { UInt32 channel_id = accessor.getChannelID(); if(CA_SERVICE_CHANNEL !=channel_id) { LOG4CPLUS_INFO(logger, "L1InterfaceStub::processClientDeallocateRequest() => " "Deallocate Channel Request: ChID = " + convertIntegerToString(channel_id)); mRegistryMutex.lock(); tChannelsRegistryMap::iterator iter = mL1ChannelRegistry.find(channel_id); if (iter != mL1ChannelRegistry.end()) { iter->second.mState = E_TRANSITION_CLIENT; sendRequest(accessor); assert(mTimeoutManager); mTimeoutManager->addSubscriber(new RequestTimeout(static_cast<tOpCode> (accessor.getOpCode()),channel_id,this ), 250000); // ret = ERR_OK; } else { LOG4CPLUS_INFO(logger, "L1InterfaceStub::processClientDeallocateRequest() " "=> Deallocate Channel Request: ChID = " + convertIntegerToString(channel_id) + " NOT FOUND!"); // ret = ERR_NOTFOUND; } mRegistryMutex.unlock(); } return false; }
ConnectivityAgentError L1InterfaceStub::sendData(CDataAccessor & accessor) { LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__); ConnectivityAgentError result(ConnectivityAgentError::ERROR_NOT_FOUND); mRegistryMutex.lock(); tChannelsRegistryMap::iterator iter = mL1ChannelRegistry.find(accessor.getChannelID()); if (iter != mL1ChannelRegistry.end()) { Buffer buf; UInt32 size = accessor.getDataSize(); assert (size <= MAX_SIZE); LOG4CPLUS_INFO(logger, "L1InterfaceStub::sendData() => Overall data bytes " + convertIntegerToString(size)); buf.reserveSize(size); buf.setFilledSize(size); memcpy(buf.getData(), accessor.getData(), accessor.getDataSize()); result = (iter->second.mpSourceAgent->fillBuffer(buf)); } else { LOG4CPLUS_ERROR(logger, "L1InterfaceStub::sendData() => channel not found!"); result.setErrorCode(ConnectivityAgentError::ERROR_NOT_FOUND); } mRegistryMutex.unlock(); return result; }
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"); } }
bool L1InterfaceStub::processClientAllocateRequest(CDataAccessor & accessor, const iviLink::Ipc::DirectionID dirId) { LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__); const UInt32 channel_id = accessor.getChannelID(); if(CA_SERVICE_CHANNEL == channel_id) { // SEQ_E_5 LOG4CPLUS_WARN(logger, "Channel CA_SERVICE_CHANNEL is not allowed to be open"); accessor.resetData(); accessor.setErrorCode(ConnectivityAgentError::ERROR_CHANNEL_BUSY); return true; } UInt32 prio = 0; memcpy(&prio, accessor.getData(), accessor.getDataSize()); LOG4CPLUS_INFO(logger, "L1InterfaceStub::processClientAllocateRequest() => " "Allocate Channel Request: ChID = " + convertIntegerToString(channel_id) + ", prio = " + convertIntegerToString(prio)); iviLink::Ipc::DirectionID tmpDirId = dirId; ConnectivityAgentError err = ConnectivityAgentError(ConnectivityAgentError::ERROR_OTHER); mRequestedMapMutex.lock(); mRegistryMutex.lock(); { err = beginAllocateChannel(static_cast<TChannelPriority>(prio), channel_id, true, tmpDirId); accessor.setErrorCode(err.getCode()); if (err.isNoError()) { LOG4CPLUS_INFO(logger, "L1InterfaceStub::processClientAllocateRequest() => " "all ok, sending request to other side" ); err = sendRequest(accessor); } } mRegistryMutex.unlock(); mRequestedMapMutex.unlock(); if (err.isNoError()) //> all ok { return false; } else { // something wrong, need message about error // SEQ_E_5 assert(err.getCode() != ConnectivityAgentError::ERROR_DEFERRED); accessor.resetData(); accessor.setErrorCode(err.getCode()); return true; } }
void L1InterfaceStub::processServiceDeallocateResponse(CDataAccessor & accessor) { UInt32 channel_id = accessor.getChannelID(); UInt32 errCode = 0; memcpy(&errCode, accessor.getData(), sizeof(UInt32)); ConnectivityAgentError ret(static_cast<ConnectivityAgentError::AgentErrorCodes>(errCode)); LOG4CPLUS_INFO(logger, "L1InterfaceStub::processServiceDeallocateResponse() => " "Channel deallocated responce id = " + convertIntegerToString(channel_id) + " err = " + convertIntegerToString((int)ret.getCode())); if (ret.isNoError()) { ret = deallocateChannel(channel_id); if (ret.isNoError()) { bool found = false; iviLink::Ipc::DirectionID dirId; mRegistryMutex.lock(); { tChannelsRegistryMap::iterator iter = mL1ChannelRegistry.find(channel_id); if (iter != mL1ChannelRegistry.end()) { dirId = iter->second.mClientDir; found = true; mL1ChannelRegistry.erase(iter); } } mRegistryMutex.unlock(); if (found) { UInt8* buf = new UInt8[accessor.getObjectSize()]; accessor.copyToRawArray(buf); BaseError err = mpIpc->asyncRequest(mMsgIdGen.next(), buf, accessor.getObjectSize(), &dirId); if (!err.isNoError()) { LOG4CPLUS_WARN(logger, static_cast<std::string>(err)); } delete [] buf; } else { LOG4CPLUS_INFO(logger, "Channel " + convertIntegerToString(channel_id) + " is not found. Probably, already deleted"); } } } }
bool L1InterfaceStub::processClientSendRequest(CDataAccessor & accessor, const iviLink::Ipc::DirectionID dirId) { UInt32 channel_id = accessor.getChannelID(); if (CA_SERVICE_CHANNEL !=channel_id) { LOG4CPLUS_INFO(logger, "L1InterfaceStub::processClientSendRequest() => " "Send Data Request: ChID = " + convertIntegerToString(channel_id)); sendData(accessor); } return false; }
void CConnectivityAgentProxy::receiveDataNotification(CDataAccessor & accessor) { LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__); UInt32 channel_id = accessor.getChannelID(); UInt32 data_size = accessor.getDataSize(); LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::receiveDataNotification() => channel " + convertIntegerToString(channel_id) + ", data_size " + convertIntegerToString(data_size)); mRegistryMutex.lockRead(); tChannelsRegistryMap::iterator iter = mChannelRegistry.find(channel_id); if (iter != mChannelRegistry.end()) { Buffer *buf = &(iter->second.mChannelBuffer); UInt32 free_size = buf->getAllocatedSize() - buf->getFilledSize(); if (free_size < data_size) { mCallbackListMutex.lock(); CCallbackWrapper* pCallback = new CBufferOverflowCallback(iter->second.mpClient, channel_id); mCallbackList.push_back(pCallback); mCallbackListMutex.unlock(); mCallbackSema.signal(); LOG4CPLUS_ERROR(logger, "CConnectivityAgentProxy::receiveDataNotification() => overflow!"); //copy or not? } else { buf->appendData(accessor.getData(), data_size); free_size -= data_size; mCallbackListMutex.lock(); CCallbackWrapper* pCallback = new CDataReceivedCallback(iter->second.mpClient, channel_id, data_size); mCallbackList.push_back(pCallback); mCallbackListMutex.unlock(); mCallbackSema.signal(); } } else { LOG4CPLUS_ERROR(logger, "CConnectivityAgentProxy::receiveDataNotification() => unknown channel!"); } mRegistryMutex.unlockRead(); }
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::channelDeletedNotification(CDataAccessor & accessor) { LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__); UInt32 channel_id = accessor.getChannelID(); mRegistryMutex.lockWrite(); { tChannelsRegistryMap::iterator iter = mChannelRegistry.find(channel_id); if (iter == mChannelRegistry.end()) { LOG4CPLUS_INFO(logger, "channel " + convertIntegerToString(channel_id) + " is not found"); if (mChannelOnDeallocSet.find(channel_id) != mChannelOnDeallocSet.end()) { LOG4CPLUS_INFO(logger, "channel is being deallocated from this side, signaling about it"); mDeallocateRequestResultCond.lock(); mDeallocateRequestResultMap[channel_id] = CDataAccessor(); mDeallocateRequestResultCond.broadcast(); mDeallocateRequestResultCond.unlock(); } } else { LOG4CPLUS_INFO(logger, "channel " + convertIntegerToString(channel_id) + " found"); mCallbackListMutex.lock(); { CCallbackWrapper* pCallback = new CChannelDeletedCallback(iter->second.mpClient, channel_id); mCallbackList.push_back(pCallback); mCallbackSema.signal(); } mCallbackListMutex.unlock(); mChannelRegistry.erase(channel_id); } } mRegistryMutex.unlockWrite(); }
bool L1InterfaceStub::processClientDeallocateByWD(CDataAccessor & accessor, const iviLink::Ipc::DirectionID dirId) { LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__); UInt32 channel_id = accessor.getChannelID(); if(CA_SERVICE_CHANNEL !=channel_id) { LOG4CPLUS_INFO(logger, "L1InterfaceStub::processClientDeallocateByWD() => " "Deallocate Channel Request: ChID = " + convertIntegerToString(channel_id)); mRegistryMutex.lock(); tChannelsRegistryMap::iterator iter = mL1ChannelRegistry.find(channel_id); if (iter != mL1ChannelRegistry.end()) { iter->second.mClientDir = dirId; // so that Negotiator receives the response iter->second.mState = E_TRANSITION_CLIENT; accessor.setOpCode(E_DEALLOCATE_CHANNEL); sendRequest(accessor); assert(mTimeoutManager); mTimeoutManager->addSubscriber(new RequestTimeout(static_cast<tOpCode> (accessor.getOpCode()),channel_id,this ), 250000); accessor.setErrorCode(0); } else { LOG4CPLUS_INFO(logger, "L1InterfaceStub::processClientDeallocateByWD() " "=> Deallocate Channel Request: ChID = " + convertIntegerToString(channel_id) + " NOT FOUND!"); accessor.setErrorCode(ConnectivityAgentError::ERROR_NOT_FOUND); } mRegistryMutex.unlock(); } else { accessor.setErrorCode(ConnectivityAgentError::ERROR_OTHER); } return true; }
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(); }
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::deallocateChannel(UInt32 channel_id) { LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__); LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::deallocateChannel(chID = " + convertIntegerToString(channel_id) + ")"); ERROR_CODE ret = ERR_NOTFOUND; mRegistryMutex.lockWrite(); // Channel info will be saved in info and removed from registry here. // In case of some errors, it will be restored in registry. tChannelInfo info; tChannelsRegistryMap::iterator iter = mChannelRegistry.find(channel_id); if (iter == mChannelRegistry.end()) { LOG4CPLUS_ERROR(logger, "CConnectivityAgentProxy::deallocateChannel(chID = " + convertIntegerToString(channel_id) + ") => ERROR: Channel not found! "); } else { ret = ERR_OK; info = iter->second; iter->second.mChannelBuffer.forgetData(); mChannelRegistry.erase(iter); mChannelOnDeallocSet.insert(channel_id); } mRegistryMutex.unlockWrite(); if (ret != ERR_OK) return ret; CDataAccessor requestDA; requestDA.setChannelID(channel_id); requestDA.setOpCode(E_DEALLOCATE_CHANNEL); UInt8* buf = new UInt8[requestDA.getObjectSize()]; requestDA.copyToRawArray(buf); // response will be sent later as a separate request UInt32 respSize = 0; CError err = mpIpc->request(mMsgIdGen.next(), buf, requestDA.getObjectSize(), NULL, respSize); delete[] buf; if (!err.isNoError()) { LOG4CPLUS_WARN(logger, static_cast<std::string>(err)); ret = ERR_FAIL; } else { CDataAccessor responseDA; mDeallocateRequestResultCond.lock(); { LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::deallocateChannel waiting for mLastRequestResultDA"); while (mDeallocateRequestResultMap.find(channel_id) == mDeallocateRequestResultMap.end()) { LOG4CPLUS_INFO(logger, "before wait"); mDeallocateRequestResultCond.wait(); LOG4CPLUS_INFO(logger, "after wait"); } responseDA = mDeallocateRequestResultMap[channel_id]; mDeallocateRequestResultMap.erase(channel_id); } mDeallocateRequestResultCond.unlock(); if (responseDA.getData()) { if ((E_DEALLOCATE_CHANNEL_RESP == responseDA.getOpCode()) && (channel_id == responseDA.getChannelID())) { UInt32 data = 0; memcpy(&data, responseDA.getData(), sizeof(UInt32)); responseDA.resetAll(); ret = static_cast<ERROR_CODE>(data); } else { LOG4CPLUS_ERROR(logger, "CConnectivityAgentProxy::deallocateChannel() => ERROR: wrong response type(" + convertIntegerToString(responseDA.getOpCode()) + ") from Agent !!! "); ret = ERR_WRONG_SEQUENCE; } } else { LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::deallocateChannel() => " "channel already deleted form other side"); ret = ERR_OK; } } if (ret != ERR_OK) { // something gone wrong, we need to restore information in registry mRegistryMutex.lockWrite(); if (mChannelRegistry.find(channel_id) != mChannelRegistry.end()) { LOG4CPLUS_WARN(logger, "CConnectivityAgentProxy::deallocateChannel: " "something gone wrong and I'm unable to restore channel info - " "there is a channel in registry with such id"); } else { mChannelRegistry[channel_id] = info; info.mChannelBuffer.forgetData(); LOG4CPLUS_INFO(logger, "CConnectivityAgentProxy::deallocateChannel:" "unable to delete channel " + convertIntegerToString(channel_id) + ", so channel info is restored"); } mRegistryMutex.unlockWrite(); } mRegistryMutex.lockWrite(); mChannelOnDeallocSet.erase(channel_id); mRegistryMutex.unlockWrite(); return ret; }