/* * 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; }
// 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; } }
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; }