예제 #1
0
ConnectivityAgentError L1InterfaceStub::endAllocateChannel(const UInt32 channel_id,
        DirectionID& dirId)
{
    ConnectivityAgentError result = ConnectivityAgentError::NoError();
    mRegistryMutex.lock();
    {
        tChannelsRegistryMap::iterator iter = mL1ChannelRegistry.find(channel_id);
        if (iter != mL1ChannelRegistry.end())
        {
            tL1ChannelInfo & info = iter->second;

            if (E_TRANSITION_AGENT == info.mState)
            {
                result.setErrorCode(ConnectivityAgentError::ERROR_DEFERRED);
            }

            LOG4CPLUS_INFO(logger, "L1InterfaceStub::endAllocateChannel(): E_OPERATIONAL");
            info.mState = E_OPERATIONAL;

            dirId = info.mClientDir;
        }
        else
        {
            // SEQ_E_4
            result.setErrorCode(ConnectivityAgentError::ERROR_NOT_FOUND);
            LOG4CPLUS_ERROR(logger, "L1InterfaceStub::endAllocateChannel(): ERR_NOTFOUND");
        }
    }
    mRegistryMutex.unlock();

    return result;
}
예제 #2
0
파일: CTarget.cpp 프로젝트: Luxoft/iviLink
ConnectivityAgentError CTarget::receiveFrame(const iviLink::ConnectivityAgent::HAL::Frame& frame)
{
   LOG4CPLUS_TRACE(logger, " CTarget::receiveFrame(): channel " + convertIntegerToString(mChannelID));
   static bool firstFlag = true;
   ConnectivityAgentError result;
   assert(mChannelID == frame.mFrameHeader.channel_id);

   if((!firstFlag)&&(!mCarrierReplaced)&&(frame.mFrameHeader.number != mLastFrameNr + 1))
   {
      LOG4CPLUS_ERROR(logger, "CTarget::receiveFrame error - ERR_WRONG_FRAME_SEQUENCE: frame.mFrameHeader.number = "
          + convertIntegerToString(frame.mFrameHeader.number) + ", mLastFrameNr + 1 = "
          + convertIntegerToString(mLastFrameNr + 1));
      if(frame.mFrameHeader.number<=mLastFrameNr)
      {
         result.setErrorCode(ConnectivityAgentError::ERROR_RESEND_ACK);
      }
      else
      {
         result.setErrorCode(ConnectivityAgentError::ERROR_WRONG_FRAME_SEQUENCE);
      }   
   }
   else if (mBufferQueue.empty())
   {
      LOG4CPLUS_ERROR(logger, "CTarget::receiveFrame error - mBufferQueue.empty()");
      result.setErrorCode(ConnectivityAgentError::ERROR_NO_FREE_BUFFERS_LEFT);      
   }
   else
   {
      mBufferQueueMutex.lock();
      Buffer* buf = mBufferQueue.front();
      mBufferQueue.pop_front();
      mBufferQueueMutex.unlock();
      assert(buf);

      copyFromFrame(frame, *buf);

      assert(mpBufferConsumer);
      result = mpBufferConsumer->consumeBuffer(buf);
      if (result.isNoError())
      {
         if(firstFlag) 
         {
            firstFlag =false;
         }
         if(mCarrierReplaced)
         {
            mCarrierReplaced = false;
         }
         mLastFrameNr = frame.mFrameHeader.number;
      }

   }
   return result;
}
예제 #3
0
ConnectivityAgentError CTransmitDispatcher::openChannel(const UInt32 channel_id,
                                    const TChannelPriority prio,
                                    iviLink::ConnectivityAgent::L1::IBufferProducer& bufferProducer)
{
    CSource* pSource = NULL;
    LOG4CPLUS_TRACE(logger, "CTransmitDispatcher::openChannel(chID = "
                    + convertIntegerToString(channel_id)
                    + ", prio = " + convertIntegerToString((int) prio) + ", bufProd = "
                    + convertIntegerToString((intptr_t) &bufferProducer) + ")");
 	ConnectivityAgentError result = ConnectivityAgentError::NoError();
    mRegistryMutex.lock();
    TSourceList::iterator iter = mRegistry[static_cast<UInt8>(prio)].begin();
    while (iter != mRegistry[static_cast<UInt8>(prio)].end())
    {
        if (channel_id == static_cast<CSource*>(*iter)->getChannelID())
        {
         	result.setErrorCode(ConnectivityAgentError::ERROR_CHANNEL_BUSY);
            break;
        }
        ++iter;
    }
    if (iter == mRegistry[static_cast<UInt8>(prio)].end())
    {
        pSource = new CSource(channel_id, mEventSem);
        LOG4CPLUS_INFO(logger, "CTransmitDispatcher::openChannel() number = "
                        + convertIntegerToString(channel_id)
                        + " prio = " + convertIntegerToString(static_cast<UInt8>(prio))
                        + " opening new channel");
        pSource->registerProducer(&bufferProducer);
        bufferProducer.registerConsumer(pSource);
        mRegistry[prio].push_back(pSource);
    }
    mRegistryMutex.unlock();
    return result;
}
예제 #4
0
ConnectivityAgentError CTcpCarrierAdapter::receiveRawArray(UInt8* pArray, UInt32 & size)
{
   LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__);

   ssize_t n = -1;
   int saved_errno = 0;

   ConnectivityAgentError receiveResult = ConnectivityAgentError::NoError();

   mSocketMutex.lockRead();
   {
      do {
         n = ::recv(mSocket, pArray, size, 0);
      } while (n == -1 && errno == EINTR);

      saved_errno = errno;
   }
   mSocketMutex.unlockRead();

   if (n > 0)
   {
      size = n;
   }
   else
   {
      LOG4CPLUS_WARN(logger, "CTcpCarrierAdapter::receiveRawArray() recv error: "
         + convertIntegerToString(saved_errno) + strerror(saved_errno));
      // connection lost
      mSelfpipe.signal(eGameOver);
      receiveResult.setErrorCode(ConnectivityAgentError::ERROR_BROKEN_PIPE);
   }

   return receiveResult;
}
예제 #5
0
ConnectivityAgentError CTcpCarrierAdapter::CSelfpipe::readSignal(tSignal& signal)
{
   LOG4CPLUS_TRACE(logger, __PRETTY_FUNCTION__);
   ConnectivityAgentError error = ConnectivityAgentError::NoError();
   ssize_t res = -1;

   do {
      res = read(mSelfpipe[0], &signal, sizeof(signal));
   } while (res == -1 && errno == EINTR);

   if (res == -1)
   {
      int saved_errno = errno;
      LOG4CPLUS_ERROR(logger, "selfpipe write error: "
         + convertIntegerToString(saved_errno) + strerror(saved_errno));
      error.setErrorCode(ConnectivityAgentError::ERROR_OTHER);
   }

   return error;
}
예제 #6
0
ConnectivityAgentError CTcpCarrierAdapter::waitHandshakeState(EHandshakeState state)
{
   LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__);

   ConnectivityAgentError waitResult = ConnectivityAgentError::NoError();

   mHandshakeStateCondVar.lock();
   {
      int rc = 0;
      timespec ts = CCondVar::calcAbsTimeout(mHandshakeTimeout);
      while (mHandshakeState != state && rc == 0)
      {
         rc = mHandshakeStateCondVar.waitTimeout(ts);
      }
      if (rc != 0 || mHandshakeState != state)
         waitResult.setErrorCode(ConnectivityAgentError::ERROR_HANDSHAKE_FAILED);
   }
   mHandshakeStateCondVar.unlock();

   return waitResult;
}
예제 #7
0
ConnectivityAgentError L1InterfaceStub::receiveData(Buffer & buffer, UInt32 channel_id)
{
    LOG4CPLUS_TRACE(logger, "L1InterfaceStub::receiveData() => channel " +
            convertIntegerToString(channel_id));

    UInt32 offset = 0;
    CDataAccessor accessor;
    ConnectivityAgentError result;
    // TODO ipc errors processing
    // TODO incorrect data processing

    assert(buffer.getFilledSize() <= buffer.getMaxSize());

    LOG4CPLUS_INFO(logger, "L1InterfaceStub::receiveData() =>  buf size "
    + convertIntegerToString(buffer.getFilledSize()));
    if(channel_id == CA_SERVICE_CHANNEL)
    {
        //> If  data received from service channel - process service request
        do
        {

            UInt32 begin = offset;

            UInt16 buf_length = ByteOrder::ntoh16(*reinterpret_cast<UInt16*>
            (buffer.getData() + offset));
            offset += 2;
            LOG4CPLUS_INFO(logger, "L1InterfaceStub::receiveData() =>  buf_length " +
                    convertIntegerToString(buf_length));
            assert(begin + buf_length <= buffer.getFilledSize());
            
            UInt32 operation = ByteOrder::ntoh32(*reinterpret_cast<UInt32*>
                    (buffer.getData() + offset));
            offset += 4;
            accessor.setOpCode(operation);
            
            UInt32 channel_id = ByteOrder::ntoh32(*reinterpret_cast<UInt32*>
                    (buffer.getData() + offset));
            offset += 4;
            accessor.setChannelID(channel_id);
            
            UInt32 data_size = ByteOrder::ntoh32(*reinterpret_cast<UInt32*>
                    (buffer.getData() + offset));
            offset += 4;
            
            UInt32 error_code = ByteOrder::ntoh32(*reinterpret_cast<UInt32*>
                    (buffer.getData() + offset));
            offset += 4;
            accessor.setErrorCode(error_code);

            accessor.setData(buffer.getData() + offset, data_size);
            offset += data_size;
            
            accessor.printContent();
            ///>Process service request
            tServiceCallbacksMap::iterator iter =
                    mServiceCallbacksMap.find(static_cast<tOpCode>(operation));

            if (iter !=mServiceCallbacksMap.end())
            {
                ///> This funny language structure is just callback invocation.
                ///> Not obvious, huh? =)
                (this->*iter->second)(accessor);
                result.setNoError();
            }
            else
            {
                LOG4CPLUS_WARN(logger, "L1InterfaceStub::receiveData() => "
                        "UNKNOWN SERVICE REQUEST = "
                        + convertIntegerToString(operation) + "!!!");
            }

        } while (offset < buffer.getFilledSize());

        LOG4CPLUS_INFO(logger, "L1InterfaceStub::receiveData() => offset "
                + convertIntegerToString(offset) + "!!!");
        assert(buffer.getFilledSize() == offset);
    }
    else
    {
        //> Or pack to accessor and send to client
        accessor.setOpCode(E_RECEIVE_DATA_NTF);
        accessor.setChannelID(channel_id);
        assert (buffer.getFilledSize() > 0);
        accessor.setData(buffer.getData(),buffer.getFilledSize());
        accessor.printContent();
        UInt8* buf = new UInt8[accessor.getObjectSize()];
        accessor.copyToRawArray(buf);

        BaseError ipcError = mpIpc->asyncRequest(mMsgIdGen.next(),
        buf, accessor.getObjectSize(), &mL1ChannelRegistry[channel_id].mClientDir); // TODO use find, and not []

        delete [] buf;
        if (ipcError.isNoError())
        {
            result.setNoError();
        }
        else
        {
            result.setErrorCode(ConnectivityAgentError::ERROR_REQUEST_FAILED);
        }
    }

    return result;
}
예제 #8
0
ConnectivityAgentError L1InterfaceStub::beginAllocateChannel(const TChannelPriority prio,
        const UInt32 channel_id, const bool client_side, DirectionID& dirId)
{
    LOG4CPLUS_TRACE_METHOD(logger, "L1InterfaceStub::beginAllocateChannel(" +
            convertIntegerToString(channel_id) + ", "
            "client_side" + std::string(client_side ? "true" : "false") +")");
    ConnectivityAgentError result;

    //if channel wasn't opened yet
    if (mL1ChannelRegistry.find(channel_id) == mL1ChannelRegistry.end())
    {
        tRequestedChannelsMap::iterator iter = mRequestedMap.find(channel_id);
        if (iter == mRequestedMap.end()) // if channel wasn't requested yet ->request channel
        {
            // First call on SEQ_A and SEQ_B or SEQ_A DEFERRED

            tRequestedChannelInfo info;
            info.mType =  prio;
            info.mState = (client_side ? E_TRANSITION_CLIENT : E_TRANSITION_AGENT);
            info.mClientDir = dirId;

            assert((client_side && dirId != -1) || (!client_side && dirId == -1));

            LOG4CPLUS_INFO(logger, "L1InterfaceStub::beginAllocateChannel() =>insert request"
                    " channel_id " + convertIntegerToString(channel_id) +
                    " mState " + std::string(info.mState == E_TRANSITION_CLIENT ?
                            "E_TRANSITION_CLIENT" : "E_TRANSITION_AGENT"));

            mRequestedMap.insert(std::pair<UInt32, tRequestedChannelInfo>(channel_id, info));
            
            result = (client_side ? ConnectivityAgentError::NoError() :
                    ConnectivityAgentError(ConnectivityAgentError::ERROR_DEFERRED));
        }
        else
        {
            tRequestedChannelInfo & info = iter->second;

            //if channel was requested by other side
            if (!client_side || (client_side && info.mState == E_TRANSITION_AGENT))
            {
                // SEQ_A DEFERRED or call from other side

                LOG4CPLUS_INFO(logger, "L1InterfaceStub::beginAllocateChannel() =>"
                        "Opening channel locally");

                if (client_side)
                {
                    info.mClientDir = dirId;
                }
                else
                {
                    dirId = info.mClientDir;
                }

                result = allocateChannelLocally(channel_id, info);

                assert(result.getCode() != ConnectivityAgentError::ERROR_DEFERRED);

                mRequestedMap.erase(channel_id);
            }
            else  //channel was requested by Client Application not the first time
            {
                // SEQ_E_1
                LOG4CPLUS_ERROR(logger, "L1InterfaceStub::beginAllocateChannel() => ERROR: "
                        "allocation is in progress! ");
                result.setErrorCode(ConnectivityAgentError::ERROR_ALLOCATION_IN_PROGRESS);
            }
        }
    }
    else //channel already opened
    {
        // SEQ_E_2

        LOG4CPLUS_ERROR(logger, "L1InterfaceStub::beginAllocateChannel() => ERROR: channel "
                "already exists! ");
        result.setErrorCode(ConnectivityAgentError::ERROR_CHANNEL_BUSY);
    }

    return result;
}
예제 #9
0
ConnectivityAgentError CTcpCarrierAdapter::makeHandshake()
{
   LOG4CPLUS_TRACE_METHOD(logger, __PRETTY_FUNCTION__);
   ConnectivityAgentError handshakeResult = ConnectivityAgentError::NoError();

   mHandshakeStateCondVar.lock();
   if (mHandshakeState != eHandshakeBefore)
   {
      LOG4CPLUS_ERROR(logger,"wrong handshake state" );
      handshakeResult.setErrorCode(ConnectivityAgentError::ERROR_HANDSHAKE_FAILED);
   }
   mHandshakeStateCondVar.unlock();

   if (!handshakeResult.isNoError())
      return handshakeResult;

   // will return this in case of any handshake fail
   ConnectivityAgentError failedResult(ConnectivityAgentError::ERROR_HANDSHAKE_FAILED);

   const UInt32 size = 50;
   UInt8 pAddr[size];
   memset(pAddr, 0, size);
   strncpy(reinterpret_cast<char*>(pAddr), this->getRemoteAddress(), size);

   if (mConnectionInfo.serverSocket)
   {
      LOG4CPLUS_INFO(logger, "CTcpCarrierAdapter::makeHandshake(): send AXIS ...");

      handshakeAndVerStrAxis[4] = IVILINK_VERSION_MAJOR;
      handshakeAndVerStrAxis[5] = IVILINK_VERSION_MINOR;
      if (!sendPreparedArray(handshakeAndVerStrAxis, sizeof(handshakeAndVerStrAxis)).isNoError())
      {
         LOG4CPLUS_ERROR(logger,"handshake AXIS send failed" );
         return failedResult;
      }

      if (!waitHandshakeState(eHandshakeA).isNoError())
      {
         LOG4CPLUS_ERROR(logger,"handshake not state A");
         return failedResult;
      }

      if (!sendPreparedArray(pAddr, sizeof(pAddr)).isNoError())
      {
         LOG4CPLUS_ERROR(logger,"handshake send addr failed");
         return failedResult;
      }

      if (!waitHandshakeState(eHandshakeDone).isNoError())
      {
         LOG4CPLUS_ERROR(logger,"handshake not state done");
         return failedResult;
      }

      mGenderType = eServerGender;
   }
   else
   {
      if (!waitHandshakeState(eHandshakeA).isNoError())
      {
         LOG4CPLUS_ERROR(logger,"handshake not state A");
         return failedResult;
      }

      handshakeAndVerStrSixa[4] = IVILINK_VERSION_MAJOR;
      handshakeAndVerStrSixa[5] = IVILINK_VERSION_MINOR;
      if (!sendPreparedArray(handshakeAndVerStrSixa, sizeof(handshakeAndVerStrSixa)).isNoError())
      {
         LOG4CPLUS_ERROR(logger,"handshake SIXA send failed" );
         return failedResult;
      }

      if (!waitHandshakeState(eHandshakeDone).isNoError())
      {
         LOG4CPLUS_ERROR(logger,"handshake not state done");
         return failedResult;
      }

      if (!sendPreparedArray(pAddr, sizeof(pAddr)).isNoError())
      {
         LOG4CPLUS_ERROR(logger,"handshake send addr failed");
         return failedResult;
      }

      mGenderType = eClientGender;
   }

   return ConnectivityAgentError::NoError();
}