/*
 * Apply buffer containing full encoded message to cache
 */
RsslRet applyMsgBufferToCache(RsslUInt8 majorVersion, RsslUInt8 minorVersion, RsslPayloadEntryHandle* pCacheEntryHandle, RsslVACacheInfo* pCacheInfo, RsslBuffer *pBuffer)
{
    RsslDecodeIterator dIter;
    RsslMsg msg;
    RsslRet ret;

    if (*pCacheEntryHandle == 0)
    {
        /* allocate cache entry */
        *pCacheEntryHandle = rsslPayloadEntryCreate(pCacheInfo->cacheHandle, &pCacheInfo->cacheErrorInfo);
        if (*pCacheEntryHandle == 0)
        {
            printf("Failed to create cache entry.\n\tError (%d): %s\n",
                   pCacheInfo->cacheErrorInfo.rsslErrorId, pCacheInfo->cacheErrorInfo.text);

            return RSSL_RET_FAILURE;
        }
    }

    rsslClearDecodeIterator(&dIter);
    rsslSetDecodeIteratorRWFVersion(&dIter, majorVersion, minorVersion);

    if((ret = rsslSetDecodeIteratorBuffer(&dIter, pBuffer)) != RSSL_RET_SUCCESS)
    {
        printf("Failed to set iterator on data buffer: Error (%d)", ret);
        return ret;
    }

    rsslClearMsg(&msg);
    if ((ret = rsslDecodeMsg(&dIter, &msg)) != RSSL_RET_SUCCESS)
    {
        printf("Failed to decode message: Error (%d)", ret);
        return ret;
    }

    if ((ret = rsslPayloadEntryApply(*pCacheEntryHandle,
                                     &dIter,
                                     &msg,
                                     &pCacheInfo->cacheErrorInfo)) != RSSL_RET_SUCCESS)
    {
        printf("Failed to apply payload data to cache.\n\tError (%d): %s\n",
               pCacheInfo->cacheErrorInfo.rsslErrorId, pCacheInfo->cacheErrorInfo.text);

        return ret;
    }

    return RSSL_RET_SUCCESS;
}
/*
 * Processes a response from a channel.  This consists of
 * performing a high level decode of the message and then
 * calling the applicable specific function for further
 * processing.
 * chnl - The channel of the response
 * buffer - The message buffer containing the response
 */
static RsslRet processResponse(RsslChannel* chnl, RsslBuffer* buffer)
{
	RsslRet ret = 0;
	RsslMsg msg = RSSL_INIT_MSG;
	RsslDecodeIterator dIter;
	RsslLoginResponseInfo *loginRespInfo = NULL;
	
	/* clear decode iterator */
	rsslClearDecodeIterator(&dIter);
	
	/* set version info */
	rsslSetDecodeIteratorRWFVersion(&dIter, chnl->majorVersion, chnl->minorVersion);

	if((ret = rsslSetDecodeIteratorBuffer(&dIter, buffer)) != RSSL_RET_SUCCESS)
	{
		printf("\nrsslSetDecodeIteratorBuffer() failed with return code: %d\n", ret);
		return RSSL_RET_FAILURE;
	}
	ret = rsslDecodeMsg(&dIter, &msg);				
	if (ret != RSSL_RET_SUCCESS)
	{
		printf("\nrsslDecodeMsg(): Error %d on SessionData fd="SOCKET_PRINT_TYPE" Size %d \n", ret, chnl->socketId, buffer->length);	
		return RSSL_RET_FAILURE;
	}

	switch ( msg.msgBase.domainType )
	{
		case RSSL_DMT_LOGIN:
			if (processLoginResponse(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
			{
				if (isLoginStreamClosed())
				{
					return RSSL_RET_FAILURE;
				}
				else if (isLoginStreamClosedRecoverable())
				{
					recoverConnection();
				}
				else if (isLoginStreamSuspect())
				{
					loginRespInfo = getLoginResponseInfo();
					/* if not single open provider, close source directory stream and item streams */
					if (!loginRespInfo->SingleOpen)
					{
						if (closeSourceDirectoryStream(rsslConsumerChannel) != RSSL_RET_SUCCESS)
							return RSSL_RET_FAILURE;

						if (closeSymbolListStream(rsslConsumerChannel) != RSSL_RET_SUCCESS)
							return RSSL_RET_FAILURE;

						if (closeYieldCurveItemStreams(rsslConsumerChannel) != RSSL_RET_SUCCESS)
							return RSSL_RET_FAILURE;

						if (closeMarketPriceItemStreams(rsslConsumerChannel) != RSSL_RET_SUCCESS)
							return RSSL_RET_FAILURE;

						if (closeMarketByOrderItemStreams(rsslConsumerChannel) != RSSL_RET_SUCCESS)
							return RSSL_RET_FAILURE;

						if (closeMarketByPriceItemStreams(rsslConsumerChannel) != RSSL_RET_SUCCESS)
							return RSSL_RET_FAILURE;
					}
					isInLoginSuspectState = RSSL_TRUE;
				}
			}
			else
			{
				if (isInLoginSuspectState)
				{
					isInLoginSuspectState = RSSL_FALSE;
				}
			}
			break;
		case RSSL_DMT_SOURCE:
			if (processSourceDirectoryResponse(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
				return RSSL_RET_FAILURE;

			/* if we have loaded the dictionaries, now that we have the directory, set up posting if its enabled */
			if ((isFieldDictionaryLoaded() || isEnumTypeDictionaryLoaded()) && ((onPostEnabled || offPostEnabled) && !postInit))
			{
				/* Initialize Post Processing after sending the login request message */
				/* ensure that provider supports posting - if not, disable posting */
				RsslLoginResponseInfo* loginInfo = getLoginResponseInfo();
					
				if (loginInfo->SupportOMMPost == RSSL_TRUE)
				{
					/* This sets up our basic timing so post messages will be sent periodically */
					initPostHandler();
					/* posting has been initialized */
					postInit = RSSL_TRUE;
				}
				else
				{
					/* provider does not support posting, disable it */
					onPostEnabled = RSSL_FALSE;
					offPostEnabled = RSSL_FALSE;
					disableOnstreamPost();
					disableOffstreamPost();
					printf("\nConnected Provider does not support OMM Posting.  Disabling Post functionality.\n");
				}
			}

			break;
		case RSSL_DMT_DICTIONARY:
			if (processDictionaryResponse(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
				return RSSL_RET_FAILURE;

			/* Now that we have downloaded dictionaries and directory set up posting if its enabled */
			if ((onPostEnabled || offPostEnabled) && !postInit)
			{
				/* Initialize Post Processing after sending the login request message */
				/* ensure that provider supports posting - if not, disable posting */
				RsslLoginResponseInfo* loginInfo = getLoginResponseInfo();
					
				if (loginInfo->SupportOMMPost == RSSL_TRUE)
				{
					/* This sets up our basic timing so post messages will be sent periodically */
					initPostHandler();
					/* posting has been initialized */
					postInit = RSSL_TRUE;
				}
				else
				{
					/* provider does not support posting, disable it */
					onPostEnabled = RSSL_FALSE;
					offPostEnabled = RSSL_FALSE;
					disableOnstreamPost();
					disableOffstreamPost();
					printf("\nConnected Provider does not support OMM Posting.  Disabling Post functionality.\n");
				}
			}

			break;
		case RSSL_DMT_MARKET_PRICE:
			if (!isInLoginSuspectState)
			{
				if (processMarketPriceResponse(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
					return RSSL_RET_FAILURE;
			}
			break;
		case RSSL_DMT_MARKET_BY_ORDER:
			if (!isInLoginSuspectState)
			{
				if (processMarketByOrderResponse(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
					return RSSL_RET_FAILURE;
			}
			break;
		case RSSL_DMT_MARKET_BY_PRICE:
			if (!isInLoginSuspectState)
			{
				if (processMarketByPriceResponse(chnl, &msg, &dIter)  != RSSL_RET_SUCCESS)
					return RSSL_RET_FAILURE;
			}
			break;
		case RSSL_DMT_YIELD_CURVE:
			if(!isInLoginSuspectState)
			{
				if (processYieldCurveResponse(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
					return RSSL_RET_FAILURE;
			}
			break;
		case RSSL_DMT_SYMBOL_LIST:
			if(!isInLoginSuspectState)
			{
				if (processSymbolListResponse(&msg, &dIter) != RSSL_RET_SUCCESS)
					return RSSL_RET_FAILURE;
			}
			break;
		default:
			printf("Unhandled Domain Type: %d\n", msg.msgBase.domainType);
			break;
	}

	return RSSL_RET_SUCCESS;
}
Exemple #3
0
// Process a channel response
// Decode the higher level message elements that when we have determined the message type
// pass to the appropriate handler
RsslRet UPAConsumer::ProcessResponse(RsslChannel* chnl, RsslBuffer* buffer)
{
   RsslRet ret = 0;
   RsslMsg msg = RSSL_INIT_MSG;
   RsslDecodeIterator dIter;
   UPALogin::RsslLoginResponseInfo *loginRespInfo = NULL;

   // bump counter
   //++incomingMessageCount_;
   statsLogger_->IncIncomingMessageCount();

   // reset the decode iterator
   rsslClearDecodeIterator(&dIter);

   // set version info 
   rsslSetDecodeIteratorRWFVersion(&dIter, chnl->majorVersion, chnl->minorVersion);

   if ((ret = rsslSetDecodeIteratorBuffer(&dIter, buffer)) != RSSL_RET_SUCCESS)
   {
      t42log_error("rsslSetDecodeIteratorBuffer() failed with return code: %d\n", ret);
      return RSSL_RET_FAILURE;
   }

   // Decode the message - note this only decode the outer parts of the message
   ret = rsslDecodeMsg(&dIter, &msg);				
   if (ret != RSSL_RET_SUCCESS)
   {
      t42log_error("rsslDecodeMsg(): Error %d on SessionData fd=%d  Size %d \n", ret, chnl->socketId, buffer->length);
      return RSSL_RET_FAILURE;
   }

   switch ( msg.msgBase.domainType )
   {
   case RSSL_DMT_LOGIN:
      if (login_->processLoginResponse(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
      {
		 t42log_info("ProcessResponse: cl=%d, rec=%d sus=%d notentitled=%d",
		 	login_->IsClosed(), login_->IsClosedRecoverable(), login_->IsSuspect(), login_->IsNotEntitled());
         if (login_->IsNotEntitled())
         {
		 	shouldRecoverConnection_ = RSSL_FALSE;
            return RSSL_RET_FAILURE;
         }
         else if (login_->IsClosed())
         {
            return RSSL_RET_FAILURE;
         }
         else if (login_->IsClosedRecoverable())
         {
            RecoverConnection();
         }
         else if (login_->IsSuspect())
         {
            isInLoginSuspectState_ = RSSL_TRUE;
         }
      }
      else
      {
         if (isInLoginSuspectState_)
         {
            isInLoginSuspectState_ = RSSL_FALSE;
         }
      }
      break;
   case RSSL_DMT_SOURCE:
      //			if (processSourceDirectoryResponse(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
      if (sourceDirectory_->ProcessSourceDirectoryResponse( &msg, &dIter) != RSSL_RET_SUCCESS)
         return RSSL_RET_FAILURE;

      break;
   case RSSL_DMT_DICTIONARY:
      if (upaDictionary_->ProcessDictionaryResponse(&msg, &dIter) != RSSL_RET_SUCCESS)
         return RSSL_RET_FAILURE;

      //TODO check that dictionary processing failure results in connection failure notification



      break;
   case RSSL_DMT_MARKET_PRICE:
      if (!isInLoginSuspectState_)
      {

         // lookup the subscription from the stream id
         RsslUInt32 streamId = msg.msgBase.streamId;


         if (streamId >= 16)
            // its either a regular mp update or an onstream ack
         {
            UPAItem_ptr_t item = streamManager_.GetItem(streamId); 	
            if (item.get() == 0)
            {
               // the item has been released - just ignore the update
               return RSSL_RET_SUCCESS;
            }

            if (item->Subscription()->ProcessMarketPriceResponse(&msg, &dIter) != RSSL_RET_SUCCESS)

               return RSSL_RET_FAILURE;
         }

         // otherwise is an ack or nak to an offstream post
         if (streamId == login_->StreamId())
         {
            // this isnt associated with a subscription so just have to process it here
            if (ProcessOffStreamResponse(&msg, &dIter) != RSSL_RET_SUCCESS)
            {
               return RSSL_RET_FAILURE;
            }
         }


      }
      break;
   case RSSL_DMT_MARKET_BY_ORDER:
      if (!isInLoginSuspectState_)
      {
         // lookup the subscription from the stream id
         RsslUInt32 streamId = msg.msgBase.streamId;

         UPAItem_ptr_t item = streamManager_.GetItem(streamId); 


         if (item.get() == 0)
         {
            // the item has been released - just ignore the update
            return RSSL_RET_SUCCESS;
         }

         if (item->Subscription()->ProcessMarketByOrderResponse(&msg, &dIter) != RSSL_RET_SUCCESS)
            return RSSL_RET_FAILURE;
      }
      break;
   case RSSL_DMT_MARKET_BY_PRICE:
      if (!isInLoginSuspectState_)
      {
         // lookup the subscription from the stream id
         RsslUInt32 streamId = msg.msgBase.streamId;

         UPAItem_ptr_t item = streamManager_.GetItem(streamId); 


         if (item.get() == 0)
         {
            // the item has been released - just ignore the update
            return RSSL_RET_SUCCESS;
         }

         if (item->Subscription()->ProcessMarketByPriceResponse(&msg, &dIter) != RSSL_RET_SUCCESS)
            return RSSL_RET_FAILURE;
      }
      break;
   case RSSL_DMT_YIELD_CURVE:

      break;
   case RSSL_DMT_SYMBOL_LIST:

      break;
   default:
      t42log_warn("Unhandled Domain Type: %d\n", msg.msgBase.domainType);
      break;
   }

   return RSSL_RET_SUCCESS;
}
static RsslRet snapshotSessionProcessMessage(SnapshotSession *pSession, RsslBuffer *pBuffer)
{
	RsslDecodeIterator decodeIter;
	RsslRet ret;
	RsslErrorInfo rsslErrorInfo;
	RsslMsg rsslMsg;
	char tempMem[1024];
	RsslBuffer tempBuffer;
	Item *pItem;

	printf("<%s> Received message:\n", pSession->name);

	/* Decode the message header. */
	rsslClearDecodeIterator(&decodeIter);
	rsslSetDecodeIteratorRWFVersion(&decodeIter, pSession->pRsslChannel->majorVersion,
			pSession->pRsslChannel->minorVersion);
	rsslSetDecodeIteratorBuffer(&decodeIter, pBuffer);
	if ((ret = rsslDecodeMsg(&decodeIter, &rsslMsg)) != RSSL_RET_SUCCESS)
	{
		printf("<%s> rsslDecodeMsg() failed: %d(%s).\n\n", 
				pSession->name, ret, rsslRetCodeToString(ret));
		return ret;
	}

	switch(rsslMsg.msgBase.domainType)
	{
		case RSSL_DMT_LOGIN:
		{
			/* Decode the message using the RDM package decoder utility. */
			RsslRDMLoginMsg loginMsg;

			tempBuffer.data = tempMem;
			tempBuffer.length = sizeof(tempMem);

			if ((ret = rsslDecodeRDMLoginMsg(&decodeIter, &rsslMsg, &loginMsg, &tempBuffer, 
							&rsslErrorInfo)) != RSSL_RET_SUCCESS)
			{
				printf(	"<%s> rsslDecodeRDMLoginMsg() failed: %d (%s -- %s)\n"
						"  at %s.\n\n",
						pSession->name,
						ret, rsslRetCodeToString(ret), rsslErrorInfo.rsslError.text,
						rsslErrorInfo.errorLocation);
				return ret;
			}

			switch(loginMsg.rdmMsgBase.rdmMsgType)
			{
				case RDM_LG_MT_REFRESH:
					printf("<%s> Received login refresh.\n\n",
							pSession->name,
							ret, rsslRetCodeToString(ret), rsslErrorInfo.rsslError.text);

					if (pSession->state == SNAPSHOT_STATE_LOGIN_REQUESTED)
					{
						if (snapshotSessionSendSymbolListRequest(pSession) != RSSL_RET_SUCCESS)
							return ret;
					}

					break;

				default:
					printf("<%s> Received unhandled RDM Login Message Type %d.\n\n",
							pSession->name, loginMsg.rdmMsgBase.rdmMsgType);
					return RSSL_RET_FAILURE;
			}
			return RSSL_RET_SUCCESS;
		}

		case RSSL_DMT_SYMBOL_LIST:
		{
			processSymbolListResponse(pSession, &rsslMsg, &decodeIter);

			if (rsslMsg.refreshMsg.flags & RSSL_RFMF_REFRESH_COMPLETE)
			{
				pSession->state = SNAPSHOT_STATE_SYMBOL_LIST_RECEIVED;
			}
		}
		break;

		default:
		{
			if ((pItem = itemListGetItemBySnapStreamID(&itemList, rsslMsg.msgBase.streamId, rsslMsg.msgBase.domainType))
					== NULL)
			{
				printf("<%s> Received unhandled message with snapshot stream ID %d, and domain %d(%s).\n\n",
						pSession->name,
						rsslMsg.msgBase.streamId,
						rsslMsg.msgBase.domainType,
						rsslDomainTypeToString(rsslMsg.msgBase.domainType));

				return RSSL_RET_SUCCESS;
			}

			return itemProcessMsg(pItem, &decodeIter, &rsslMsg, RSSL_TRUE);
		}

	}

	return RSSL_RET_SUCCESS;
}
RsslRet processMsg(ChannelHandler *pChannelHandler, ChannelInfo* pChannelInfo, RsslBuffer* pBuffer)
{
	RsslRet ret = RSSL_RET_SUCCESS; RsslMsg msg = RSSL_INIT_MSG;
	RsslDecodeIterator dIter;
	ProviderThread *pProvThread = (ProviderThread*)pChannelHandler->pUserSpec;
	RsslChannel *pChannel = pChannelInfo->pChannel;
	
	/* clear decode iterator */
	rsslClearDecodeIterator(&dIter);
	
	/* set version info */
	rsslSetDecodeIteratorRWFVersion(&dIter, pChannel->majorVersion, pChannel->minorVersion);

	rsslSetDecodeIteratorBuffer(&dIter, pBuffer);

	ret = rsslDecodeMsg(&dIter, &msg);				
	if (ret != RSSL_RET_SUCCESS)
	{
		printf("\nrsslDecodeMsg(): Error %d on SessionData fd=%d  Size %d \n", ret, pChannel->socketId, pBuffer->length);
		cleanUpAndExit();
	}

	switch ( msg.msgBase.domainType )
	{
		case RSSL_DMT_LOGIN:
			ret = processLoginRequest(pChannelHandler, pChannelInfo, &msg, &dIter);
			break;
		case RSSL_DMT_SOURCE:
			ret = processDirectoryRequest(pChannelHandler, pChannelInfo, &msg, &dIter);
			break;
		case RSSL_DMT_DICTIONARY:
			ret = processDictionaryRequest(pChannelHandler, pChannelInfo, &msg, &dIter);
			break;
		case RSSL_DMT_MARKET_PRICE:
			if (xmlMsgDataHasMarketPrice)
				ret = processItemRequest(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, &msg, &dIter);
			else
				ret = sendItemRequestReject(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, 
						msg.msgBase.streamId, msg.msgBase.domainType, DOMAIN_NOT_SUPPORTED);
			break;
		case RSSL_DMT_MARKET_BY_ORDER:
			if (xmlMsgDataHasMarketByOrder)
				ret = processItemRequest(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, &msg, &dIter);
			else
				ret = sendItemRequestReject(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, 
						msg.msgBase.streamId, msg.msgBase.domainType, DOMAIN_NOT_SUPPORTED);
			break;
		default:
			ret = sendItemRequestReject(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, 
					msg.msgBase.streamId, msg.msgBase.domainType, DOMAIN_NOT_SUPPORTED);
			break;
	}


	if (ret < RSSL_RET_SUCCESS) 
	{
		printf("Failed to process request from domain %d: %d\n", msg.msgBase.domainType, ret);
	}
	else if (ret > RSSL_RET_SUCCESS)
	{
		/* The function sent a message and indicated that we need to flush. */
		providerThreadRequestChannelFlush(pProvThread, pChannelInfo);
	}

	return ret;
}
static RsslRet reflectPostMsg(ProviderThread *pProvThread, RsslDecodeIterator *pIter, ProviderSession *pProvSession, RsslPostMsg *pPostMsg)
{
	RsslRet ret;
	RsslChannel *pChannel = pProvSession->pChannelInfo->pChannel;

	RsslMsg msgToReflect;
	RsslEncodeIterator eIter;


	switch(pPostMsg->msgBase.containerType)
	{
		case RSSL_DT_MSG:
			if ((ret = rsslDecodeMsg(pIter, &msgToReflect)) != RSSL_RET_SUCCESS)
				return ret;
			break;
		default:
			/* It's a container(e.g. field list). Add an update header for reflecting. */
			rsslClearUpdateMsg(&msgToReflect.updateMsg);
			msgToReflect.updateMsg.msgBase.containerType = pPostMsg->msgBase.containerType;
			msgToReflect.updateMsg.msgBase.domainType = pPostMsg->msgBase.domainType;
			msgToReflect.updateMsg.msgBase.encDataBody = pPostMsg->msgBase.encDataBody;
			break;
	}

	/* get a buffer for the response */
	if (rtrUnlikely((ret = getItemMsgBuffer(pProvThread, pProvSession, 128 + msgToReflect.msgBase.encDataBody.length)) 
				< RSSL_RET_SUCCESS))
		return ret;

	/* Add the post user info from the post message to the nested message and re-encode. */
	rsslClearEncodeIterator(&eIter);
	rsslSetEncodeIteratorRWFVersion(&eIter, pChannel->majorVersion, pChannel->minorVersion);
	rsslSetEncodeIteratorBuffer(&eIter, pProvSession->pWritingBuffer);

	/* Add stream ID of PostMsg to nested message. */
	msgToReflect.msgBase.streamId = pPostMsg->msgBase.streamId;

	/* Add PostUserInfo of PostMsg to nested message. */
	switch(msgToReflect.msgBase.msgClass)
	{
		case RSSL_MC_REFRESH:
			msgToReflect.refreshMsg.postUserInfo = pPostMsg->postUserInfo;
			msgToReflect.refreshMsg.flags |= RSSL_RFMF_HAS_POST_USER_INFO;
			msgToReflect.refreshMsg.flags &= ~RSSL_RFMF_SOLICITED;
			break;
		case RSSL_MC_UPDATE:
			msgToReflect.updateMsg.postUserInfo = pPostMsg->postUserInfo;
			msgToReflect.updateMsg.flags |= RSSL_UPMF_HAS_POST_USER_INFO;
			break;
		case RSSL_MC_STATUS:
			msgToReflect.statusMsg.postUserInfo = pPostMsg->postUserInfo;
			msgToReflect.statusMsg.flags |= RSSL_STMF_HAS_POST_USER_INFO;
			break;
		default:
			printf("Error: Unhandled message class in post: %s(%u)\n", 
					rsslMsgClassToString(msgToReflect.msgBase.msgClass),
					msgToReflect.msgBase.msgClass);
			return RSSL_RET_FAILURE;
	}

	/* Other header members & data body should be properly set, so re-encode. */
	if (ret = rsslEncodeMsg(&eIter, &msgToReflect) != RSSL_RET_SUCCESS)
		return ret;

	pProvSession->pWritingBuffer->length = rsslGetEncodedBufferLength(&eIter);

	return sendItemMsgBuffer(pProvThread, pProvSession, RSSL_FALSE);
}
RsslRet processMsg(ChannelHandler *pChannelHandler, ChannelInfo* pChannelInfo, RsslBuffer* pBuffer)
{
	RsslRet ret = RSSL_RET_SUCCESS;
	RsslMsg msg = RSSL_INIT_MSG;
	RsslDecodeIterator dIter;
	RsslChannel *chnl = pChannelInfo->pChannel;
	ProviderThread *pProviderThread = (ProviderThread*)pChannelHandler->pUserSpec;
	
	/* clear decode iterator */
	rsslClearDecodeIterator(&dIter);
	
	/* set version info */
	rsslSetDecodeIteratorRWFVersion(&dIter, chnl->majorVersion, chnl->minorVersion);

	rsslSetDecodeIteratorBuffer(&dIter, pBuffer);

	ret = rsslDecodeMsg(&dIter, &msg);				
	if (ret != RSSL_RET_SUCCESS)
	{
		printf("\nrsslDecodeMsg(): Error %d on SessionData fd=%d  Size %d \n", ret, chnl->socketId, pBuffer->length);
		cleanUpAndExit();
	}

	switch ( msg.msgBase.domainType )
	{
		case RSSL_DMT_LOGIN:
		{
			RsslRDMLoginMsg loginMsg;
			char memoryChar[1024];
			RsslBuffer memoryBuffer = { sizeof(memoryChar), memoryChar };
			RsslErrorInfo errorInfo;
			RsslState *pState = NULL;

			if ((ret = rsslDecodeRDMLoginMsg(&dIter, &msg, &loginMsg, &memoryBuffer, &errorInfo)) != RSSL_RET_SUCCESS)
			{
				printf("rsslDecodeRDMLoginMsg() failed: %d(%s)\n", ret, errorInfo.rsslError.text);
				ret = RSSL_RET_FAILURE;
				break;
			}

			switch(loginMsg.rdmMsgBase.rdmMsgType)
			{
				case RDM_LG_MT_REFRESH:
					pState = &loginMsg.refresh.state;

					printf(	"Received login refresh.\n");
					if (loginMsg.refresh.flags &
							RDM_LG_RFF_HAS_APPLICATION_NAME)
						printf( "  ApplicationName: %.*s\n",
								loginMsg.refresh.applicationName.length,
								loginMsg.refresh.applicationName.data);
					printf("\n");

					break;

				case RDM_LG_MT_STATUS:
					printf("Received login status message.\n");
					if (loginMsg.status.flags & RDM_LG_STF_HAS_STATE)
						pState = &loginMsg.status.state;
					break;

				default:
					printf("Received unhandled login message class: %d.\n", msg.msgBase.msgClass);
					break;
			}

			if (pState)
			{
				if (pState->streamState == RSSL_STREAM_OPEN)
				{
					ProviderSession *pProvSession = (ProviderSession*)pChannelInfo->pUserSpec;

					ret = publishDirectoryRefresh(pChannelHandler, pChannelInfo, -1);

					if (ret < RSSL_RET_SUCCESS)
					{
						printf("publishDirectoryRefresh() failed: %d.\n", ret);
						return ret;
					}

					if (niProvPerfConfig.itemPublishCount > 0)
					{
						RsslInt32 itemListUniqueIndex;
						RsslInt32 itemListCount;
						RsslInt32 itemListCountRemainder;

						/* If there are multiple connections, determine which items are
						 * to be published on this connection.
						 * If any items are common to all connections, they are taken from the first
						 * items in the item list.  The rest of the list is then divided to provide a unique
						 * item list for each connection. */

						/* Determine where items unique to this connection start. */
						itemListUniqueIndex = niProvPerfConfig.commonItemCount;
						itemListUniqueIndex += ((niProvPerfConfig.itemPublishCount - niProvPerfConfig.commonItemCount)
							/ providerThreadConfig.threadCount) * (pProviderThread->providerIndex);

						/* Account for remainder. */
						itemListCount = niProvPerfConfig.itemPublishCount / providerThreadConfig.threadCount;
						itemListCountRemainder = niProvPerfConfig.itemPublishCount % providerThreadConfig.threadCount;

						if (pProviderThread->providerIndex < itemListCountRemainder)
						{
							/* This provider publishes an extra item */
							itemListCount += 1;

							/* Shift index by one for each provider before this one, since they publish extra items too. */
							itemListUniqueIndex += pProviderThread->providerIndex;
						}
						else
							/* Shift index by one for each provider that publishes an extra item. */
							itemListUniqueIndex += itemListCountRemainder;

						if ((ret = providerSessionAddPublishingItems(pProviderThread, (ProviderSession*)pChannelInfo->pUserSpec, 
									niProvPerfConfig.commonItemCount, itemListUniqueIndex, itemListCount - niProvPerfConfig.commonItemCount, 
									(RsslUInt16)directoryConfig.serviceId)) != RSSL_RET_SUCCESS)
						{
							printf("providerSessionAddPublishingItems() failed\n");
							return ret;
						}
						else
						{
							printf("Created publishing list.\n");
							ret = RSSL_RET_SUCCESS;
						}

						/* send the first burst of refreshes */
						if (rotatingQueueGetCount(&pProvSession->refreshItemList) != 0)
							ret = sendRefreshBurst(pProviderThread, pProvSession);
						else
							ret = RSSL_RET_SUCCESS;

						if (ret < RSSL_RET_SUCCESS)
							return ret;
					}

					if (ret > RSSL_RET_SUCCESS)
					{
						/* Need to flush */
						providerThreadRequestChannelFlush(pProviderThread, pChannelInfo);
					}

				}
				else
				{
					printf("Login stream closed.\n");
					ret = RSSL_RET_FAILURE;
				}
			}
			else 
				ret = RSSL_RET_SUCCESS;
			break;
		}
		default:
			printf("Received message with unhandled domain: %d\n", msg.msgBase.domainType);
			break;
	}


	if (ret < RSSL_RET_SUCCESS) 
	{
		signal_shutdown = RSSL_TRUE;
		return ret;
	}
	else
	{
		/* Typically these requests result in a response, so call for a flush to make sure it gets out.*/
		providerThreadRequestChannelFlush(pProviderThread, pChannelInfo);
		return ret;
	}
}
Exemple #8
0
RsslRet UPAProvider::ProcessRequest(RsslChannel* chnl, RsslBuffer* buffer)
{
    RsslRet ret = 0;
    RsslMsg msg = RSSL_INIT_MSG;
    RsslDecodeIterator dIter;

    // set up an iterator to decode the message
    rsslClearDecodeIterator(&dIter);
    rsslSetDecodeIteratorRWFVersion(&dIter, chnl->majorVersion, chnl->minorVersion);
    // and attach it top the message buffer
    rsslSetDecodeIteratorBuffer(&dIter, buffer);

    ret = rsslDecodeMsg(&dIter, &msg);				
    if (ret != RSSL_RET_SUCCESS)
    {
        t42log_error("UPAProvider::ProcessRequest - rsslDecodeMsg(): Error %d on channel fd=%d  Size %d \n", ret, chnl->socketId, buffer->length);
        RemoveChannelConnection(chnl);
        return RSSL_RET_FAILURE;
    }

    switch ( msg.msgBase.domainType )
    {
    case RSSL_DMT_LOGIN:
        if (ProcessLoginRequest(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
        {

            RemoveChannelConnection(chnl);
            return RSSL_RET_FAILURE;
        }
        break;
    case RSSL_DMT_SOURCE:

        if (ProcessSourceDirectoryRequest(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
        {
            RemoveChannelConnection(chnl);
            return RSSL_RET_FAILURE;
        }
        break;
    case RSSL_DMT_DICTIONARY:
        if (ProcessDictionaryRequest(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
        {
            RemoveChannelConnection(chnl);
            return RSSL_RET_FAILURE;
        }
        break;
    case RSSL_DMT_MARKET_PRICE:
    case RSSL_DMT_MARKET_BY_ORDER:
    case RSSL_DMT_SYMBOL_LIST:
    case RSSL_DMT_MARKET_BY_PRICE:
    case RSSL_DMT_YIELD_CURVE:
        if (ProcessItemRequest(chnl, &msg, &dIter) != RSSL_RET_SUCCESS)
        {
            RemoveChannelConnection(chnl);
            return RSSL_RET_FAILURE;
        }
        break;
    default:
          break;
    }


    return RSSL_RET_SUCCESS;
}