/* * Encodes the symbol list close. Returns success if * encoding succeeds or failure if encoding fails. * pCommand - the ChannelCommand to send an item close to * pReactorChannel - The channel to send an item close to * msgBuf - The message buffer to encode the item close into * streamId - The stream id of the symbol list * * This function is only used within the Symbol List Handler * and each handler has its own implementation, although much is similar */ static RsslRet encodeSymbolListClose(ChannelCommand *pCommand, RsslReactorChannel* pReactorChannel, RsslBuffer* msgBuf, RsslInt32 streamId) { RsslRet ret = 0; RsslCloseMsg msg = RSSL_INIT_CLOSE_MSG; RsslEncodeIterator encodeIter; /* clear encode iterator */ rsslClearEncodeIterator(&encodeIter); /* set-up message */ msg.msgBase.msgClass = RSSL_MC_CLOSE; msg.msgBase.streamId = streamId; msg.msgBase.domainType = RSSL_DMT_SYMBOL_LIST; msg.msgBase.containerType = RSSL_DT_NO_DATA; /* encode message */ if((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) < RSSL_RET_SUCCESS) { printf("rsslSetEncodeIteratorBuffer() failed with return code: %d\n", ret); return ret; } rsslSetEncodeIteratorRWFVersion(&encodeIter, pReactorChannel->majorVersion, pReactorChannel->minorVersion); if ((ret = rsslEncodeMsg(&encodeIter, (RsslMsg*)&msg)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsg() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
void encodeStatusMsg( RsslUInt8 domainType, RsslInt32 streamId, RsslBuffer* pRsslBuffer ) { RsslEncodeIterator eIter; RsslStatusMsg statusMsg; rsslClearEncodeIterator( &eIter ); rsslClearStatusMsg( &statusMsg ); statusMsg.flags |= RSSL_STMF_HAS_STATE; statusMsg.state.code = RSSL_SC_NONE; statusMsg.state.dataState = RSSL_DATA_SUSPECT; statusMsg.state.streamState = RSSL_STREAM_CLOSED; statusMsg.state.text.data = (char*)"Closed"; statusMsg.state.text.length = 6; statusMsg.msgBase.domainType = domainType; statusMsg.msgBase.streamId = streamId; statusMsg.msgBase.containerType = RSSL_DT_NO_DATA; rsslSetEncodeIteratorBuffer( &eIter, pRsslBuffer ); rsslSetEncodeIteratorRWFVersion( &eIter, RSSL_RWF_MAJOR_VERSION, RSSL_RWF_MINOR_VERSION ); rsslEncodeMsg( &eIter, (RsslMsg*)&statusMsg ); pRsslBuffer->length = rsslGetEncodedBufferLength( &eIter ); }
RsslRet encodeItemUpdate(RsslChannel* chnl, ItemInfo* itemInfo, RsslBuffer* msgBuf, RsslPostUserInfo *pPostUserInfo, RsslUInt encodeStartTime) { RsslRet ret; RsslUpdateMsg updateMsg; RsslEncodeIterator encodeIter; rsslClearUpdateMsg(&updateMsg); updateMsg.msgBase.streamId = itemInfo->StreamId; rsslClearEncodeIterator(&encodeIter); rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); if ((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) != RSSL_RET_SUCCESS) return ret; updateMsg.msgBase.domainType = itemInfo->attributes.domainType; if (pPostUserInfo) { updateMsg.flags |= RSSL_UPMF_HAS_POST_USER_INFO; updateMsg.postUserInfo = *pPostUserInfo; } switch(itemInfo->attributes.domainType) { case RSSL_DMT_MARKET_PRICE: updateMsg.msgBase.containerType = RSSL_DT_FIELD_LIST; if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&updateMsg, 0)) < RSSL_RET_SUCCESS) return ret; if ((ret = encodeMarketPriceDataBody(&encodeIter, getNextMarketPriceUpdate((MarketPriceItem*)itemInfo->itemData), RSSL_MC_UPDATE, encodeStartTime)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DMT_MARKET_BY_ORDER: updateMsg.msgBase.containerType = RSSL_DT_MAP; if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&updateMsg, 0)) < RSSL_RET_SUCCESS) return ret; if ((ret = encodeMarketByOrderDataBody(&encodeIter, getNextMarketByOrderUpdate((MarketByOrderItem*)itemInfo->itemData), RSSL_MC_UPDATE, encodeStartTime)) < RSSL_RET_SUCCESS) return ret; break; default: assert(0); break; } if ((ret = rsslEncodeMsgComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) return ret; msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
/* Sends a basic Login Request on the given streamID, using the RDM package. */ RsslRet sendLoginRequest(ChannelHandler *pChannelHandler, ChannelInfo *pChannelInfo, RsslInt32 streamId, RsslError *error) { RsslRDMLoginRequest loginRequest; RsslRet ret; RsslBuffer *msgBuf; RsslErrorInfo errorInfo; RsslEncodeIterator eIter; RsslChannelInfo chanInfo; RsslChannel *pChannel = pChannelInfo->pChannel; if ((ret = rsslGetChannelInfo(pChannel, &chanInfo, error)) != RSSL_RET_SUCCESS) { printf("rsslGetChannelInfo() failed: %d(%s)\n", ret, error->text); return RSSL_RET_FAILURE; } /* Send Login Request */ if ((ret = rsslInitDefaultRDMLoginRequest(&loginRequest, streamId)) != RSSL_RET_SUCCESS) { printf("rsslInitDefaultRDMLoginRequest() failed: %d\n", ret); return RSSL_RET_FAILURE; } if (strlen(niProvPerfConfig.username)) { loginRequest.userName.data = niProvPerfConfig.username; loginRequest.userName.length = (RsslUInt32)strlen(niProvPerfConfig.username); } loginRequest.flags |= RDM_LG_RQF_HAS_ROLE | RDM_LG_RQF_HAS_APPLICATION_NAME; loginRequest.role = RDM_LOGIN_ROLE_PROV; loginRequest.applicationName = applicationName; if (!(msgBuf = rsslGetBuffer(pChannel, chanInfo.maxFragmentSize, RSSL_FALSE, error))) { printf("rsslGetBuffer() failed: (%d) %s\n", error->rsslErrorId, error->text); return ret; } rsslClearEncodeIterator(&eIter); rsslSetEncodeIteratorRWFVersion(&eIter, pChannel->majorVersion, pChannel->minorVersion); if ( (ret = rsslSetEncodeIteratorBuffer(&eIter, msgBuf)) != RSSL_RET_SUCCESS) { printf("rsslSetEncodeIteratorBuffer() failed: %d(%s)\n", ret, errorInfo.rsslError.text); return ret; } if ((ret = rsslEncodeRDMLoginMsg(&eIter, (RsslRDMLoginMsg*)&loginRequest, &msgBuf->length, &errorInfo)) != RSSL_RET_SUCCESS) { printf("rsslEncodeRDMLoginMsg() failed: %d(%s)\n", ret, errorInfo.rsslError.text); return ret; } return channelHandlerWriteChannel(pChannelHandler, pChannelInfo, msgBuf, 0); }
/* * Encodes the symbol list request. Returns success if * encoding succeeds or failure if encoding fails. * pCommand - the ChannelCommand to send an item request to * msgBuf - The message buffer to encode the item request into * pRequest - Item request structure * * This function is only used within the Symbol List Handler * and each handler has its own implementation, although much is similar */ static RsslRet encodeSymbolListRequest(ChannelCommand *pCommand, RsslBuffer* msgBuf, ItemRequest *pRequest) { RsslRet ret = 0; RsslRequestMsg msg = RSSL_INIT_REQUEST_MSG; RsslEncodeIterator encodeIter; /* clear encode iterator*/ rsslClearEncodeIterator(&encodeIter); /*set-up message*/ msg.msgBase.msgClass = RSSL_MC_REQUEST; msg.msgBase.streamId = pRequest->streamId; msg.msgBase.domainType = RSSL_DMT_SYMBOL_LIST; msg.msgBase.containerType = RSSL_DT_NO_DATA; if (snapshotRequest) { msg.flags = RSSL_RQMF_HAS_QOS | RSSL_RQMF_HAS_PRIORITY; } else { msg.flags = RSSL_RQMF_HAS_QOS | RSSL_RQMF_STREAMING | RSSL_RQMF_HAS_PRIORITY; } msg.priorityClass = 1; msg.priorityCount = 1; /*copy the QoS information*/ rsslCopyQos(&(msg.qos), &pCommand->qos); /*specify msgKey members*/ msg.msgBase.msgKey.flags = RSSL_MKF_HAS_NAME_TYPE | RSSL_MKF_HAS_NAME | RSSL_MKF_HAS_SERVICE_ID; msg.msgBase.msgKey.nameType = RDM_INSTRUMENT_NAME_TYPE_RIC; msg.msgBase.msgKey.serviceId = (RsslUInt16)pCommand->serviceId; /*if the user specified the SL name on the command line, add it to the request */ msg.msgBase.msgKey.name = pCommand->symbolListRequest.itemName; /* encode message*/ if((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) < RSSL_RET_SUCCESS) { printf("rsslEncodeIteratorBuffer() failed with return code: %d\n", ret); return ret; } rsslSetEncodeIteratorRWFVersion(&encodeIter, pCommand->reactorChannel->majorVersion, pCommand->reactorChannel->minorVersion); if ((ret = rsslEncodeMsg(&encodeIter, (RsslMsg*)&msg)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsgInit() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
RsslRet snapshotSessionProcessChannelActive(SnapshotSession *pSession) { RsslEncodeIterator encodeIter; RsslRDMLoginRequest loginRequest; RsslBuffer *pBuffer; RsslErrorInfo rsslErrorInfo; RsslError rsslError; RsslRet ret = RSSL_RET_FAILURE; /* Get a buffer from the channel for writing. */ if (!(pBuffer = rsslGetBuffer(pSession->pRsslChannel, 1024, RSSL_FALSE, &rsslError))) { printf("<%s> rsslGetBuffer() failed while sending login request: %d (%s -- %s).\n\n", pSession->name, rsslError.rsslErrorId, rsslRetCodeToString(rsslError.rsslErrorId), rsslError.text); return rsslError.rsslErrorId; } /* Populate the login request with some default information. */ if ((ret = rsslInitDefaultRDMLoginRequest(&loginRequest, LOGIN_STREAM_ID)) != RSSL_RET_SUCCESS) { printf("<%s> rsslInitDefaultRDMLoginRequest() failed: %d(%s).\n\n", pSession->name, ret, rsslRetCodeToString(ret)); rsslReleaseBuffer(pBuffer, &rsslError); return ret; } /* Encode the login request using the RDM package encoder utility. This will * translate the login request structure to an encoded message and set the proper length * on the buffer. */ rsslClearEncodeIterator(&encodeIter); rsslSetEncodeIteratorRWFVersion(&encodeIter, pSession->pRsslChannel->majorVersion, pSession->pRsslChannel->minorVersion); rsslSetEncodeIteratorBuffer(&encodeIter, pBuffer); if ((ret = rsslEncodeRDMLoginMsg(&encodeIter, (RsslRDMLoginMsg*)&loginRequest, &pBuffer->length, &rsslErrorInfo)) != RSSL_RET_SUCCESS) { printf("<%s> rsslEncodeRDMLoginMsg() failed: %d (%s -- %s).\n\n", pSession->name, ret, rsslRetCodeToString(ret), rsslErrorInfo.rsslError.text); rsslReleaseBuffer(pBuffer, &rsslError); return ret; } /* Write the message. */ if ((ret = snapshotSessionWrite(pSession, pBuffer)) != RSSL_RET_SUCCESS) return ret; pSession->state = SNAPSHOT_STATE_LOGIN_REQUESTED; return RSSL_RET_SUCCESS; }
RsslRet encodeItemGenMsg(RsslChannel* chnl, ItemInfo* itemInfo, RsslBuffer* msgBuf, RsslUInt encodeStartTime) { RsslRet ret; RsslGenericMsg genMsg; RsslEncodeIterator encodeIter; rsslClearEncodeIterator(&encodeIter); rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); if ((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) != RSSL_RET_SUCCESS) return ret; /* Prepare generic message. */ rsslClearGenericMsg(&genMsg); genMsg.msgBase.streamId = itemInfo->StreamId; genMsg.msgBase.domainType = itemInfo->attributes.domainType; /* Encode generic message. */ switch(itemInfo->attributes.domainType) { case RSSL_DMT_MARKET_PRICE: genMsg.msgBase.containerType = RSSL_DT_FIELD_LIST; if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&genMsg, 0)) < RSSL_RET_SUCCESS) return ret; if ((ret = encodeMarketPriceDataBody(&encodeIter, getNextMarketPriceGenMsg((MarketPriceItem*)itemInfo->itemData), RSSL_MC_GENERIC, encodeStartTime)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DMT_MARKET_BY_ORDER: genMsg.msgBase.containerType = RSSL_DT_MAP; if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&genMsg, 0)) < RSSL_RET_SUCCESS) return ret; if ((ret = encodeMarketByOrderDataBody(&encodeIter, getNextMarketByOrderGenMsg((MarketByOrderItem*)itemInfo->itemData), RSSL_MC_GENERIC, encodeStartTime)) < RSSL_RET_SUCCESS) return ret; break; default: assert(0); break; } if ((ret = rsslEncodeMsgComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) return ret; msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
RsslRet publishDirectoryRefresh(ChannelHandler *pChannelHandler, ChannelInfo *pChannelInfo, RsslInt32 streamId) { RsslError error; RsslBuffer* msgBuf = 0; RsslRet ret; RsslChannel *pChannel = pChannelInfo->pChannel; /* get a buffer for the source directory response */ msgBuf = rsslGetBuffer(pChannel, 512, RSSL_FALSE, &error); if (msgBuf != NULL) { RsslEncodeIterator eIter; RsslErrorInfo errorInfo; RsslRDMDirectoryRefresh directoryRefresh; rsslClearRDMDirectoryRefresh(&directoryRefresh); directoryRefresh.flags = RDM_DR_RFF_HAS_SERVICE_ID | RDM_DR_RFF_CLEAR_CACHE; directoryRefresh.filter = RDM_DIRECTORY_SERVICE_INFO_FILTER | RDM_DIRECTORY_SERVICE_STATE_FILTER | RDM_DIRECTORY_SERVICE_GROUP_FILTER; /* StreamId */ directoryRefresh.rdmMsgBase.streamId = streamId; directoryRefresh.serviceList = &service; directoryRefresh.serviceCount = 1; rsslClearEncodeIterator(&eIter); rsslSetEncodeIteratorRWFVersion(&eIter, pChannel->majorVersion, pChannel->minorVersion); rsslSetEncodeIteratorBuffer(&eIter, msgBuf); if ((ret = rsslEncodeRDMDirectoryMsg(&eIter, (RsslRDMDirectoryMsg*)&directoryRefresh, &msgBuf->length, &errorInfo)) != RSSL_RET_SUCCESS) { printf("rsslEncodeRDMDirectoryMsg() failed: %d(%s)", ret, errorInfo.rsslError.text); return ret; } return channelHandlerWriteChannel(pChannelHandler, pChannelInfo, msgBuf, 0); } else { printf("rsslGetBuffer(): Failed <%s>\n", error.text); return error.rsslErrorId; } }
RsslRet UPAProvider::EncodeAck(RsslChannel* chnl, RsslBuffer* ackBuf, RsslPostMsg *postMsg, RsslUInt8 nakCode, char *text) { RsslRet ret = 0; RsslAckMsg ackMsg = RSSL_INIT_ACK_MSG; RsslEncodeIterator encodeIter; /* clear encode iterator */ rsslClearEncodeIterator(&encodeIter); /* set-up message */ ackMsg.msgBase.msgClass = RSSL_MC_ACK; ackMsg.msgBase.streamId = postMsg->msgBase.streamId; ackMsg.msgBase.domainType = postMsg->msgBase.domainType; ackMsg.msgBase.containerType = RSSL_DT_NO_DATA; ackMsg.flags = RSSL_AKMF_NONE; ackMsg.nakCode = nakCode; ackMsg.ackId = postMsg->postId; ackMsg.seqNum = postMsg->seqNum; if (nakCode != RSSL_NAKC_NONE) ackMsg.flags |= RSSL_AKMF_HAS_NAK_CODE; if (postMsg->flags & RSSL_PSMF_HAS_SEQ_NUM) ackMsg.flags |= RSSL_AKMF_HAS_SEQ_NUM; if (text != NULL) { ackMsg.flags |= RSSL_AKMF_HAS_TEXT; ackMsg.text.data = text; ackMsg.text.length = (RsslUInt32)strlen(text); } /* encode message */ rsslSetEncodeIteratorBuffer(&encodeIter, ackBuf); rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); if ((ret = rsslEncodeMsg(&encodeIter, (RsslMsg*)&ackMsg)) < RSSL_RET_SUCCESS) { t42log_error("UPAProvider::EncodeAck - rsslEncodeMsg() of ackMsg failed with return code: %d\n", ret); return ret; } ackBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
/* assuming pEncFieldList RsslBuffer contains the pre-encoded payload with data and length populated */ RsslRet getPreEncodedRsslFieldListBuffer(RsslBuffer *pEncUInt) { RsslRet retVal; //used to store and check the return value from the function calls RsslUInt8 majorVersion = RSSL_RWF_MAJOR_VERSION; //This should be initialized to the MAJOR version of RWF being encoded RsslUInt8 minorVersion = RSSL_RWF_MINOR_VERSION; // This should be initialized to the MINOR version of RWF being encoded /* create and clear iterator to prepare for encoding */ RsslEncodeIterator encodeIter; rsslClearEncodeIterator(&encodeIter); /* associate buffer and iterator, code assumes that (&encDecBuffer)->data points to sufficient memory and (&encDecBuffer)->length indicates number of bytes available in pBuffer->data */ if ((retVal = rsslSetEncodeIteratorBuffer(&encodeIter, pEncUInt)) < RSSL_RET_SUCCESS) { printf("Error %s (%d) encountered with rsslSetEncodeIteratorBuffer(). Error Text: %s\n", rsslRetCodeToString(retVal), retVal, rsslRetCodeInfo(retVal)); return retVal; } /* set proper protocol version information on iterator, this can typically be obtained from the RsslChannel associated with the connection once it becomes active */ if ((retVal = rsslSetEncodeIteratorRWFVersion(&encodeIter, majorVersion, minorVersion)) < RSSL_RET_SUCCESS) { printf("Error %s (%d) encountered with rsslSetEncodeIteratorRWFVersion(). Error Text: %s\n", rsslRetCodeToString(retVal), retVal, rsslRetCodeInfo(retVal)); return retVal; } if ((retVal = exampleEncodeFieldList(&encodeIter)) < RSSL_RET_SUCCESS) { printf("Error %s (%d) encountered with exampleEncodeFieldList(). Error Text: %s\n", rsslRetCodeToString(retVal), retVal, rsslRetCodeInfo(retVal)); return retVal; } //this is important! /* When encoding is complete, set the pEncUInt->length to the number of bytes Encoded */ pEncUInt->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
static void simpleTunnelMsgHandlerSendMessage(SimpleTunnelMsgHandler *pSimpleTunnelMsgHandler) { RsslTunnelStream *pTunnelStream = pSimpleTunnelMsgHandler->tunnelStreamHandler.pTunnelStream; RsslReactorChannel *pReactorChannel = pTunnelStream->pReactorChannel; RsslTunnelStreamSubmitOptions submitOpts; RsslTunnelStreamGetBufferOptions bufferOpts; RsslEncodeIterator eIter; RsslBuffer *pBuffer; RsslRet ret, ret2; RsslErrorInfo errorInfo; rsslClearTunnelStreamGetBufferOptions(&bufferOpts); bufferOpts.size = 1024; if ((pBuffer = rsslTunnelStreamGetBuffer(pTunnelStream, &bufferOpts, &errorInfo)) == NULL) { printf("rsslTunnelStreamGetBuffer failed: %s(%s)\n", rsslRetCodeToString(errorInfo.rsslError.rsslErrorId), &errorInfo.rsslError.text); return; } rsslClearEncodeIterator(&eIter); rsslSetEncodeIteratorRWFVersion(&eIter, pTunnelStream->classOfService.common.protocolMajorVersion, pTunnelStream->classOfService.common.protocolMinorVersion); rsslSetEncodeIteratorBuffer(&eIter, pBuffer); /* Write text as the data body. */ pBuffer->length = snprintf(pBuffer->data, pBuffer->length, "TunnelStream Message: %d", pSimpleTunnelMsgHandler->msgCount + 1); /* Message encoding complete; submit it. */ rsslClearTunnelStreamSubmitOptions(&submitOpts); submitOpts.containerType = RSSL_DT_OPAQUE; if ((ret = rsslTunnelStreamSubmit(pTunnelStream, pBuffer, &submitOpts, &errorInfo)) != RSSL_RET_SUCCESS) { printf("rsslTunnelStreamSubmit(): Failed <%s>\n", errorInfo.rsslError.text); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &errorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, errorInfo.rsslError.text); return; } ++pSimpleTunnelMsgHandler->msgCount; }
/* * Encodes the not supported status. Returns success if * encoding succeeds or failure if encoding fails. * chnl - The channel to send not supported status message to * requestMsg - The partially decoded request message * msgBuf - The message buffer to encode the not supported status into */ RsslRet encodeNotSupportedStatus(RsslReactorChannel* chnl, RsslMsg* requestMsg, RsslBuffer* msgBuf) { RsslRet ret = 0; RsslStatusMsg msg = RSSL_INIT_STATUS_MSG; char stateText[MAX_MSG_SIZE]; RsslEncodeIterator encodeIter; /* clear encode iterator */ rsslClearEncodeIterator(&encodeIter); /* set-up message */ msg.msgBase.msgClass = RSSL_MC_STATUS; msg.msgBase.streamId = requestMsg->msgBase.streamId; msg.msgBase.domainType = requestMsg->msgBase.domainType; msg.msgBase.containerType = RSSL_DT_NO_DATA; msg.flags = RSSL_STMF_HAS_STATE; msg.state.streamState = RSSL_STREAM_CLOSED; msg.state.dataState = RSSL_DATA_SUSPECT; msg.state.code = RSSL_SC_USAGE_ERROR; sprintf(stateText, "Request rejected for stream id %d - domain type %d is not supported", requestMsg->msgBase.streamId, requestMsg->msgBase.domainType); msg.state.text.data = stateText; msg.state.text.length = (RsslUInt32)strlen(stateText) + 1; /* encode message */ if((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) < RSSL_RET_SUCCESS) { printf("rsslSetEncodeIteratorBuffer() failed with return code: %d\n", ret); return ret; } rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); if ((ret = rsslEncodeMsg(&encodeIter, (RsslMsg*)&msg)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsg() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
RsslRet encodeItemCloseStatus(RsslChannel* chnl, ItemInfo* itemInfo, RsslBuffer* msgBuf, RsslInt32 streamId) { RsslRet ret = 0; RsslStatusMsg msg = RSSL_INIT_STATUS_MSG; char stateText[128]; RsslEncodeIterator encodeIter; /* clear encode iterator */ rsslClearEncodeIterator(&encodeIter); /* set-up message */ msg.msgBase.msgClass = RSSL_MC_STATUS; msg.msgBase.streamId = streamId; msg.msgBase.domainType = itemInfo->attributes.domainType; msg.msgBase.containerType = RSSL_DT_NO_DATA; msg.flags = RSSL_STMF_HAS_STATE; msg.state.streamState = RSSL_STREAM_CLOSED; msg.state.dataState = RSSL_DATA_SUSPECT; msg.state.code = RSSL_SC_NONE; snprintf(stateText, 128, "Stream closed" ); msg.state.text.data = stateText; msg.state.text.length = (RsslUInt32)strlen(stateText); /* encode message */ rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf); rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); if ((ret = rsslEncodeMsg(&encodeIter, (RsslMsg*)&msg)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsg() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
//APIQA RsslRet sendGenericMsgOnLogin(RsslChannel* chnl) { RsslRet ret = 0; RsslGenericMsg msg = RSSL_INIT_GENERIC_MSG; RsslMap map = RSSL_INIT_MAP; RsslMapEntry mEntry = RSSL_INIT_MAP_ENTRY; RsslElementList rsslElementList = RSSL_INIT_ELEMENT_LIST; RsslBuffer serviceNameBuffer; RsslEncodeIterator encodeIter; RsslElementEntry element = RSSL_INIT_ELEMENT_ENTRY; RsslBuffer* msgBuf; RsslError error; RsslUInt warmStandByMode = 1; serviceNameBuffer.length = 11; serviceNameBuffer.data = "DIRECT_FEED"; /* clear encode iterator */ rsslClearEncodeIterator(&encodeIter); /* set-up message */ msg.msgBase.msgClass = RSSL_MC_GENERIC; msg.msgBase.domainType = RSSL_DMT_LOGIN; msg.msgBase.containerType = RSSL_DT_MAP; msg.msgBase.msgKey.name.length = 24; msg.msgBase.msgKey.name.data = "ConsumerConnectionStatus"; msg.msgBase.msgKey.flags = RSSL_MKF_HAS_NAME; msg.flags = RSSL_GNMF_HAS_MSG_KEY | RSSL_GNMF_MESSAGE_COMPLETE; /* get a buffer for the login request */ msgBuf = rsslGetBuffer(chnl, MAX_MSG_SIZE, RSSL_FALSE, &error); /* StreamId */ msg.msgBase.streamId = LOGIN_STREAM_ID; /* encode message */ if ((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) < RSSL_RET_SUCCESS) { printf("rsslSetEncodeIteratorBuffer() failed with return code: %d\n", ret); return ret; } rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&msg, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsgInit() failed with return code: %d\n", ret); return ret; } /* encode map */ map.keyPrimitiveType = RSSL_DT_ASCII_STRING; map.containerType = RSSL_DT_ELEMENT_LIST; if ((ret = rsslEncodeMapInit(&encodeIter, &map, 0, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMapInit() failed with return code: %d\n", ret); return ret; } /* encode map entry */ mEntry.action = RSSL_MPEA_ADD_ENTRY; if ((ret = rsslEncodeMapEntryInit(&encodeIter, &mEntry, &serviceNameBuffer, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMapEntry() failed with return code: %d\n", ret); return ret; } /* encode the element list */ rsslElementList.flags = RSSL_ELF_HAS_STANDARD_DATA; if ((ret = rsslEncodeElementListInit(&encodeIter, &rsslElementList, 0, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementListInit() failed with return code: %d\n", ret); return ret; } /* WarmStandbyMode */ element.dataType = RSSL_DT_UINT; element.name = RSSL_ENAME_WARMSTANDBY_MODE; if ((ret = rsslEncodeElementEntry(&encodeIter, &element, &warmStandByMode)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementEntry() failed with return code: %d\n", ret); return ret; } /* complete encode element list */ if ((ret = rsslEncodeElementListComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementListComplete() failed with return code: %d\n", ret); return ret; } /* complete encode map entry */ if ((ret = rsslEncodeMapEntryComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMapEntryComplete() failed with return code: %d\n", ret); return ret; } /* complete encode map */ if ((ret = rsslEncodeMapComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMapComplete() failed with return code: %d\n", ret); return ret; } /* complete encode message */ if ((ret = rsslEncodeMsgComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsgComplete() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); if (ret != RSSL_RET_SUCCESS) { rsslReleaseBuffer(msgBuf, &error); printf("\nsendGenericMsgOnLogin() failed with return code: %d\n", ret); return ret; } /* send login request */ if (sendMessage(chnl, msgBuf) != RSSL_RET_SUCCESS) return RSSL_RET_FAILURE; return RSSL_RET_SUCCESS; }
/* * Sends the login request reject status message for a channel. * pReactorChannel - The channel to send request reject status message to * streamId - The stream id of the request * reason - The reason for the reject */ static RsslRet sendLoginRequestReject(RsslReactor *pReactor, RsslReactorChannel* pReactorChannel, RsslInt32 streamId, RsslLoginRejectReason reason, RsslErrorInfo *pError) { RsslErrorInfo rsslErrorInfo; RsslBuffer* msgBuf = 0; /* get a buffer for the login request reject status */ msgBuf = rsslReactorGetBuffer(pReactorChannel, MAX_MSG_SIZE, RSSL_FALSE, &rsslErrorInfo); if (msgBuf != NULL) { RsslRet ret = 0; char stateText[MAX_LOGIN_INFO_STRLEN]; RsslEncodeIterator encodeIter; RsslRDMLoginStatus loginStatus; RsslErrorInfo rsslErrorInfo; rsslClearRDMLoginStatus(&loginStatus); loginStatus.flags |= RDM_LG_STF_HAS_STATE; loginStatus.rdmMsgBase.streamId = streamId; loginStatus.state.streamState = RSSL_STREAM_CLOSED_RECOVER; loginStatus.state.dataState = RSSL_DATA_SUSPECT; /* set-up message */ switch(reason) { case MAX_LOGIN_REQUESTS_REACHED: loginStatus.state.code = RSSL_SC_TOO_MANY_ITEMS; snprintf(stateText, sizeof(stateText), "Login request rejected for stream id %d - max request count reached", streamId); loginStatus.state.text.data = stateText; loginStatus.state.text.length = (RsslUInt32)strlen(stateText) + 1; break; case LOGIN_RDM_DECODER_FAILED: /* The typed message decoder failed. Pass along the error text. */ loginStatus.state.code = RSSL_SC_USAGE_ERROR; snprintf(stateText, sizeof(stateText), "Login request rejected for stream id %d - decoding failure: %s", streamId, pError->rsslError.text); loginStatus.state.text.data = stateText; loginStatus.state.text.length = (RsslUInt32)strlen(stateText) + 1; break; default: break; } /* encode message */ rsslClearEncodeIterator(&encodeIter); if((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) < RSSL_RET_SUCCESS) { rsslReactorReleaseBuffer(pReactorChannel, msgBuf, &rsslErrorInfo); printf("\nrsslSetEncodeIteratorBuffer() failed with return code: %d\n", ret); return RSSL_RET_FAILURE; } rsslSetEncodeIteratorRWFVersion(&encodeIter, pReactorChannel->majorVersion, pReactorChannel->minorVersion); if (ret = rsslEncodeRDMLoginMsg(&encodeIter, (RsslRDMLoginMsg*)&loginStatus, &msgBuf->length, &rsslErrorInfo) != RSSL_RET_SUCCESS) { rsslReactorReleaseBuffer(pReactorChannel, msgBuf, &rsslErrorInfo); printf("\nrsslEncodeRDMLoginMsg() failed\n"); return RSSL_RET_FAILURE; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); /* send request reject status */ if (sendMessage(pReactor, pReactorChannel, msgBuf) != RSSL_RET_SUCCESS) return RSSL_RET_FAILURE; } else { printf("rsslReactorGetBuffer(): Failed <%s>\n", rsslErrorInfo.rsslError.text); return RSSL_RET_FAILURE; } return RSSL_RET_SUCCESS; }
/* * Sends a login refresh to a channel. This consists of getting * a message buffer, initializing the RsslRDMLoginRefresh structure, * encoding it, and sending the encoded message. * pReactorChannel - The channel to send a login response to * pLoginRequest - The login request that solicited this refresh */ static RsslRet sendLoginRefresh(RsslReactor *pReactor, RsslReactorChannel* pReactorChannel, RsslRDMLoginRequest* pLoginRequest) { RsslErrorInfo rsslErrorInfo; RsslBuffer* msgBuf = 0; RsslUInt32 ipAddress = 0; RsslRet ret; /* get a buffer for the login response */ msgBuf = rsslReactorGetBuffer(pReactorChannel, MAX_MSG_SIZE, RSSL_FALSE, &rsslErrorInfo); if (msgBuf != NULL) { RsslRDMLoginRefresh loginRefresh; RsslEncodeIterator eIter; rsslClearRDMLoginRefresh(&loginRefresh); /* Set state information */ loginRefresh.state.streamState = RSSL_STREAM_OPEN; loginRefresh.state.dataState = RSSL_DATA_OK; loginRefresh.state.code = RSSL_SC_NONE; /* Set stream ID */ loginRefresh.rdmMsgBase.streamId = pLoginRequest->rdmMsgBase.streamId; /* Mark refresh as solicited since it is a response to a request. */ loginRefresh.flags = RDM_LG_RFF_SOLICITED; /* Echo the userName, applicationId, applicationName, and position */ loginRefresh.flags |= RDM_LG_RFF_HAS_USERNAME; loginRefresh.userName = pLoginRequest->userName; if (pLoginRequest->flags & RDM_LG_RQF_HAS_USERNAME_TYPE) { loginRefresh.flags |= RDM_LG_RFF_HAS_USERNAME_TYPE; loginRefresh.userNameType = pLoginRequest->userNameType; } loginRefresh.flags |= RDM_LG_RFF_HAS_APPLICATION_ID; loginRefresh.applicationId = pLoginRequest->applicationId; loginRefresh.flags |= RDM_LG_RFF_HAS_APPLICATION_NAME; loginRefresh.applicationName = pLoginRequest->applicationName; loginRefresh.flags |= RDM_LG_RFF_HAS_POSITION; loginRefresh.position = pLoginRequest->position; /* This provider does not support Single-Open behavior. */ loginRefresh.flags |= RDM_LG_RFF_HAS_SINGLE_OPEN; loginRefresh.singleOpen = 0; /* This provider supports posting. */ loginRefresh.flags |= RDM_LG_RFF_HAS_SUPPORT_POST; loginRefresh.supportOMMPost = 1; /* This provider supports batch requests*/ loginRefresh.flags |= RDM_LG_RFF_HAS_SUPPORT_BATCH; loginRefresh.supportBatchRequests = RDM_LOGIN_BATCH_SUPPORT_REQUESTS | RDM_LOGIN_BATCH_SUPPORT_CLOSES; /* this provider supports batch requests and batch close */ /* set the clear cache flag */ loginRefresh.flags |= RDM_LG_RFF_CLEAR_CACHE; /* Leave all other parameters as default values. */ /* Encode the refresh. */ rsslClearEncodeIterator(&eIter); rsslSetEncodeIteratorRWFVersion(&eIter, pReactorChannel->majorVersion, pReactorChannel->minorVersion); if((ret = rsslSetEncodeIteratorBuffer(&eIter, msgBuf)) < RSSL_RET_SUCCESS) { rsslReactorReleaseBuffer(pReactorChannel, msgBuf, &rsslErrorInfo); printf("rsslSetEncodeIteratorBuffer() failed with return code: %d\n", ret); return RSSL_RET_FAILURE; } if (rsslEncodeRDMLoginMsg(&eIter, (RsslRDMLoginMsg*)&loginRefresh, &msgBuf->length, &rsslErrorInfo) != RSSL_RET_SUCCESS) { rsslReactorReleaseBuffer(pReactorChannel, msgBuf, &rsslErrorInfo); printf("\nrsslEncodeRDMLoginRefresh() failed:%s(%s)\n", rsslErrorInfo.rsslError.text, rsslErrorInfo.errorLocation); return RSSL_RET_FAILURE; } /* Send the refresh. */ if (sendMessage(pReactor, pReactorChannel, msgBuf) != RSSL_RET_SUCCESS) return RSSL_RET_FAILURE; } else { printf("rsslReactorGetBuffer(): Failed <%s>\n", rsslErrorInfo.rsslError.text); return RSSL_RET_FAILURE; } return RSSL_RET_SUCCESS; }
RsslRet processDirectoryRequest(ChannelHandler *pChannelHandler, ChannelInfo *pChannelInfo, RsslMsg* msg, RsslDecodeIterator* dIter) { RsslRet ret; RsslState *pState = 0; RsslRDMDirectoryMsg directoryMsg; char directoryMsgChar[4000]; RsslBuffer memoryBuffer = { 4000, directoryMsgChar }; RsslErrorInfo errorInfo; RsslChannel *pChannel = pChannelInfo->pChannel; if ((ret = rsslDecodeRDMDirectoryMsg(dIter, msg, &directoryMsg, &memoryBuffer, &errorInfo)) != RSSL_RET_SUCCESS) { printf("rsslDecodeRDMDirectoryMsg() failed: %d(%s)\n", ret, errorInfo.rsslError.text); return ret; } switch(directoryMsg.rdmMsgBase.rdmMsgType) { case RDM_DR_MT_REQUEST: { RsslError error; RsslBuffer* msgBuf = 0; RsslChannel *pChannel = pChannelInfo->pChannel; RsslEncodeIterator eIter; RsslRDMDirectoryRefresh directoryRefresh; printf("Received Directory Request.\n\n"); if ((msgBuf = rsslGetBuffer(pChannel, 512, RSSL_FALSE, &error)) == NULL) { printf("processDirectoryRequest(): rsslGetBuffer() failed: %d(%s)\n", error.rsslErrorId, error.text); return error.rsslErrorId; } rsslClearRDMDirectoryRefresh(&directoryRefresh); directoryRefresh.flags = RDM_DR_RFF_SOLICITED | RDM_DR_RFF_CLEAR_CACHE; directoryRefresh.filter = directoryMsg.request.filter; /* StreamId */ directoryRefresh.rdmMsgBase.streamId = directoryMsg.request.rdmMsgBase.streamId; /* ServiceId */ if (directoryMsg.request.flags & RDM_DR_RQF_HAS_SERVICE_ID) { /* Match the ServiceID if requested */ directoryRefresh.flags |= RDM_DR_RFF_HAS_SERVICE_ID; directoryRefresh.serviceId = directoryMsg.request.serviceId; if (directoryMsg.request.serviceId == service.serviceId) { directoryRefresh.serviceList = &service; directoryRefresh.serviceCount = 1; } } else { directoryRefresh.serviceList = &service; directoryRefresh.serviceCount = 1; } rsslClearEncodeIterator(&eIter); rsslSetEncodeIteratorRWFVersion(&eIter, pChannel->majorVersion, pChannel->minorVersion); rsslSetEncodeIteratorBuffer(&eIter, msgBuf); if ((ret = rsslEncodeRDMDirectoryMsg(&eIter, (RsslRDMDirectoryMsg*)&directoryRefresh, &msgBuf->length, &errorInfo)) != RSSL_RET_SUCCESS) { printf("rsslEncodeRDMDirectoryMsg() failed: %d(%s)", ret, errorInfo.rsslError.text); return ret; } return channelHandlerWriteChannel(pChannelHandler, pChannelInfo, msgBuf, 0); } case RDM_DR_MT_CLOSE: printf("\nReceived Source Directory Close for StreamId %d\n", directoryMsg.rdmMsgBase.streamId); return RSSL_RET_SUCCESS; default: printf("\nReceived Unhandled Source Directory Msg Class: %d\n", msg->msgBase.msgClass); return RSSL_RET_FAILURE; } }
/* * Encodes the item request. Returns success if * encoding succeeds or failure if encoding fails. * chnl - The channel to send an item request to * msgBuf - The message buffer to encode the item request into * streamId - The stream id of the item request * isPrivateStream - Flag for private stream request * * This function is only used within the Market Price Handler * and each handler has its own implementation, although much is similar */ static RsslRet encodeItemRequest(RsslChannel* chnl, RsslBuffer* msgBuf, RsslInt32 streamId, RsslBool isPrivateStream) { RsslRet ret = 0; RsslRequestMsg msg = RSSL_INIT_REQUEST_MSG; RsslEncodeIterator encodeIter; RsslElementList eList = RSSL_INIT_ELEMENT_LIST; RsslLoginResponseInfo* loginInfo = getLoginResponseInfo(); RsslSourceDirectoryResponseInfo* srcDirRespInfo = 0; RsslUInt32 listIndex; if (getSourceDirectoryResponseInfo(getServiceId(), &srcDirRespInfo) != RSSL_RET_SUCCESS) return RSSL_RET_FAILURE; /* clear encode iterator */ rsslClearEncodeIterator(&encodeIter); /* set-up message */ msg.msgBase.msgClass = RSSL_MC_REQUEST; msg.msgBase.streamId = streamId; msg.msgBase.domainType = RSSL_DMT_MARKET_PRICE; if((viewRequest == RSSL_TRUE) && (loginInfo->SupportViewRequests == RSSL_TRUE)) msg.msgBase.containerType = RSSL_DT_ELEMENT_LIST; else msg.msgBase.containerType = RSSL_DT_NO_DATA; if (snapshotRequest) { msg.flags = RSSL_RQMF_HAS_QOS | RSSL_RQMF_HAS_PRIORITY; } else { msg.flags = RSSL_RQMF_HAS_QOS | RSSL_RQMF_STREAMING | RSSL_RQMF_HAS_PRIORITY; } if (isPrivateStream) { msg.flags |= RSSL_RQMF_PRIVATE_STREAM; } if((loginInfo->SupportViewRequests == RSSL_TRUE) && (viewRequest == RSSL_TRUE)) msg.flags |= RSSL_RQMF_HAS_VIEW; msg.priorityClass = 1; msg.priorityCount = 1; /* copy the QoS information */ rsslCopyQos(&(msg.qos), &(srcDirRespInfo->ServiceGeneralInfo.QoS[0])); /* specify msgKey members */ msg.msgBase.msgKey.flags = RSSL_MKF_HAS_NAME_TYPE | RSSL_MKF_HAS_NAME | RSSL_MKF_HAS_SERVICE_ID; msg.msgBase.msgKey.nameType = RDM_INSTRUMENT_NAME_TYPE_RIC; if (!isPrivateStream) /* non-private stream */ { listIndex = streamId - MARKETPRICE_STREAM_ID_START; msg.msgBase.msgKey.name.data = marketPriceItemInfoList[listIndex].itemname; msg.msgBase.msgKey.name.length = marketPriceItemInfoList[listIndex].nameLength; } else /* private stream */ { listIndex = streamId - MARKETPRICE_PRIVATE_STREAM_ID_START; msg.msgBase.msgKey.name.data = marketPricePSItemInfoList[listIndex].itemname; msg.msgBase.msgKey.name.length = marketPricePSItemInfoList[listIndex].nameLength; } msg.msgBase.msgKey.serviceId = (RsslUInt16)getServiceId(); /* encode message */ if((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) < RSSL_RET_SUCCESS) { printf("rsslSetEncodeIteratorBuffer() failed with return code: %d\n", ret); return ret; } rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&msg, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsgInit() failed with return code: %d\n", ret); return ret; } if(viewRequest == RSSL_TRUE) { if (loginInfo->SupportViewRequests == RSSL_TRUE) { eList.flags = RSSL_ELF_HAS_STANDARD_DATA; if ((ret = rsslEncodeElementListInit(&encodeIter, &eList, 0, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementListInit() failed with return code: %d\n", ret); return ret; } encodeViewElementRequest(&encodeIter); if ((ret = rsslEncodeElementListComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementListComplete() failed with return code: %d\n", ret); return ret; } } else { printf("\nConnected Provider does not support Dynamic View requests. Disabling View functionality.\n"); viewRequest = RSSL_FALSE; } } if ((ret = rsslEncodeMsgComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsgComplete() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); if (!isPrivateStream) marketPriceItemInfoList[listIndex].streamId = streamId; else marketPricePSItemInfoList[listIndex].streamId = streamId; return RSSL_RET_SUCCESS; }
RsslBuffer* tunnelManagerGetChannelBuffer(TunnelManagerImpl *pManagerImpl, RsslEncodeIterator *pIter, RsslUInt32 length, RsslBool mustSendMsg, RsslErrorInfo *pErrorInfo) { RsslBuffer *pBuffer; RsslReactorChannel *pReactorChannel = pManagerImpl->base._pReactorChannel; RsslRet ret; assert(pReactorChannel); if ((pBuffer = rsslReactorGetBuffer(pReactorChannel, length, RSSL_FALSE, pErrorInfo)) == NULL) { RsslReactorChannelInfo channelInfo; if (!mustSendMsg) return NULL; if (pErrorInfo->rsslError.rsslErrorId != RSSL_RET_BUFFER_NO_BUFFERS) return NULL; if ((ret = rsslReactorGetChannelInfo(pReactorChannel, &channelInfo, pErrorInfo) != RSSL_RET_SUCCESS)) return NULL; /* Grow the buffer pool by one and attempt to get the buffer again. */ /* Try the shared pool first. */ channelInfo.rsslChannelInfo.maxOutputBuffers += 1; if ((ret = rsslReactorChannelIoctl(pReactorChannel, RSSL_MAX_NUM_BUFFERS, &channelInfo.rsslChannelInfo.maxOutputBuffers, pErrorInfo)) != RSSL_RET_SUCCESS) { /* If that doesn't work, try the guaranteed pool. */ channelInfo.rsslChannelInfo.guaranteedOutputBuffers += 1; if ((ret = rsslReactorChannelIoctl(pReactorChannel, RSSL_NUM_GUARANTEED_BUFFERS, &channelInfo.rsslChannelInfo.guaranteedOutputBuffers, pErrorInfo)) != RSSL_RET_SUCCESS) return NULL; } if ((pBuffer = rsslReactorGetBuffer(pReactorChannel, length, RSSL_FALSE, pErrorInfo)) == NULL) return NULL; } if (pIter != NULL) { rsslClearEncodeIterator(pIter); rsslSetEncodeIteratorRWFVersion(pIter, pReactorChannel->majorVersion, pReactorChannel->minorVersion); if ((ret = rsslSetEncodeIteratorBuffer(pIter, pBuffer)) != RSSL_RET_SUCCESS) { RsslErrorInfo errorInfo; rsslReactorReleaseBuffer(pReactorChannel, pBuffer, &errorInfo); rsslSetErrorInfo(pErrorInfo, RSSL_EIC_FAILURE, RSSL_RET_FAILURE, __FILE__, __LINE__, "Failed to set encode iterator on buffer."); return NULL; } } return pBuffer; }
/* * Encode and send a queue message through the ReactorChannel. * This message will contain an field list as its payload. */ static void sendQueueMsg(QueueMsgHandler *pQueueMsgHandler) { int i; RsslErrorInfo rsslErrorInfo; RsslRet ret, ret2; RsslFieldList fieldList; RsslFieldEntry fieldEntry; for(i = 0; i < pQueueMsgHandler->destNameCount; i++) { RsslBuffer *pBuffer; RsslTunnelStreamSubmitOptions submitOpts; RsslTunnelStreamGetBufferOptions bufferOpts; RsslRDMQueueData queueData; RsslEncodeIterator eIter; RsslBuffer fieldBuffer; RsslDateTime dateTime; RsslReal real; RsslEnum enumVal; RsslUInt uintVal; RsslTunnelStream *pTunnelStream = pQueueMsgHandler->tunnelStreamHandler.pTunnelStream; rsslClearTunnelStreamGetBufferOptions(&bufferOpts); bufferOpts.size = 1024; if ((pBuffer = rsslTunnelStreamGetBuffer(pQueueMsgHandler->tunnelStreamHandler.pTunnelStream, &bufferOpts, &rsslErrorInfo)) == NULL) { printf("rsslTunnelStreamGetBuffer(): Failed <%s>\n", rsslErrorInfo.rsslError.text); return; } // initialize the QueueData encoding rsslClearRDMQueueData(&queueData); queueData.rdmMsgBase.streamId = QUEUE_MSG_STREAM_ID; queueData.identifier = ++pQueueMsgHandler->identifier; queueData.rdmMsgBase.domainType = QUEUE_MSG_DOMAIN; queueData.sourceName = pQueueMsgHandler->sourceName; queueData.destName = pQueueMsgHandler->destNames[i]; queueData.timeout = RDM_QMSG_TC_INFINITE; queueData.containerType = RSSL_DT_FIELD_LIST; rsslClearEncodeIterator(&eIter); rsslSetEncodeIteratorRWFVersion(&eIter, pTunnelStream->classOfService.common.protocolMajorVersion, pTunnelStream->classOfService.common.protocolMinorVersion); rsslSetEncodeIteratorBuffer(&eIter, pBuffer); if ((ret = rsslEncodeRDMQueueMsgInit(&eIter, (RsslRDMQueueMsg*)&queueData, &rsslErrorInfo)) != RSSL_RET_ENCODE_CONTAINER) { printf("rsslEncodeRDMQueueMsgInit(): Failed <%s>\n", rsslErrorInfo.rsslError.text); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } //// Start Content Encoding //// rsslClearFieldList(&fieldList); fieldList.flags = RSSL_FLF_HAS_STANDARD_DATA; if ((ret = rsslEncodeFieldListInit(&eIter, &fieldList, NULL, 0)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldListInit(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* MsgType */ rsslClearFieldEntry(&fieldEntry); rsslClearBuffer(&fieldBuffer); fieldEntry.fieldId = 35; fieldEntry.dataType = RSSL_DT_BUFFER; fieldBuffer.length = 1; fieldBuffer.data = (char*)"D"; // D for new single order if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &fieldBuffer)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* ClOrderId */ rsslClearFieldEntry(&fieldEntry); rsslClearBuffer(&fieldBuffer); fieldEntry.fieldId = 11; fieldEntry.dataType = RSSL_DT_BUFFER; fieldBuffer.length = 12; fieldBuffer.data = (char*)"100000020998"; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &fieldBuffer)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* Account */ rsslClearFieldEntry(&fieldEntry); rsslClearBuffer(&fieldBuffer); fieldEntry.fieldId = 1; fieldEntry.dataType = RSSL_DT_BUFFER; fieldBuffer.length = 10; fieldBuffer.data = (char*)"D6789-3456"; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &fieldBuffer)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* Handle instruction */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 21; fieldEntry.dataType = RSSL_DT_ENUM; enumVal = 1; // 1 = automated, 2 = semi automated, 3 = manual if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &enumVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* Symbol */ rsslClearFieldEntry(&fieldEntry); rsslClearBuffer(&fieldBuffer); fieldEntry.fieldId = 55; fieldEntry.dataType = RSSL_DT_BUFFER; fieldBuffer.length = 3; fieldBuffer.data = (char*)"TRI"; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &fieldBuffer)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* Side */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 54; fieldEntry.dataType = RSSL_DT_ENUM; enumVal = 1; // 1 for Buy if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &enumVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* TransactTime */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 60; fieldEntry.dataType = RSSL_DT_DATETIME; if ((ret = rsslDateTimeGmtTime(&dateTime)) != RSSL_RET_SUCCESS) { printf("rsslDateTimeGmtTime(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &dateTime)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* OrderQty */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 38; fieldEntry.dataType = RSSL_DT_UINT; uintVal = 1000; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &uintVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* OrderType */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 40; fieldEntry.dataType = RSSL_DT_ENUM; enumVal = 1; // 2 for Limit Order if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &enumVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } /* Price */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 44; fieldEntry.dataType = RSSL_DT_REAL; rsslClearReal(&real); real.value = 3835; //38.35 real.hint = RSSL_RH_EXPONENT_2; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &real)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } if ((ret = rsslEncodeFieldListComplete(&eIter, RSSL_TRUE)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldListComplete(): Failed <%d>\n", ret); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } //// End Content Encoding //// // complete the QueueData encoding if ((ret = rsslEncodeRDMQueueMsgComplete(&eIter, RSSL_TRUE, &pBuffer->length, &rsslErrorInfo)) != RSSL_RET_SUCCESS) { printf("rsslEncodeRDMQueueMsgComplete(): Failed <%s>\n", rsslErrorInfo.rsslError.text); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } // submit the encoded data buffer of QueueData to the tunnel stream rsslClearTunnelStreamSubmitOptions(&submitOpts); submitOpts.containerType = RSSL_DT_MSG; if ((ret = rsslTunnelStreamSubmit(pQueueMsgHandler->tunnelStreamHandler.pTunnelStream, pBuffer, &submitOpts, &rsslErrorInfo)) != RSSL_RET_SUCCESS) { printf("rsslTunnelStreamSubmit(): Failed <%s>\n", rsslErrorInfo.rsslError.text); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &rsslErrorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, rsslErrorInfo.rsslError.text); return; } printf("Submitted Single Order message with ID %lld to %.*s.\n\n", pQueueMsgHandler->identifier, pQueueMsgHandler->destNames[i].length, pQueueMsgHandler->destNames[i].data); } }
/* * Encode and send a queue message ACK through the ReactorChannel. * This message will contain an field list as its payload. */ static void ackQueueMsg(QueueMsgHandler *pQueueMsgHandler, RsslBuffer *pDestName, RsslInt32 streamId) { RsslRet ret; RsslErrorInfo rsslErrorInfo; RsslEnum enumVal; RsslUInt uIntVal; RsslReal realVal; RsslTunnelStreamSubmitMsgOptions submitMsgOpts; RsslRDMQueueData queueData; RsslEncodeIterator eIter; RsslFieldList fieldList; RsslFieldEntry fieldEntry; RsslBuffer fieldBuffer; RsslBuffer ackBuffer; char ackBufferMemory[1024]; RsslTunnelStream *pTunnelStream = pQueueMsgHandler->tunnelStreamHandler.pTunnelStream; ackBuffer.data = ackBufferMemory; ackBuffer.length = sizeof(ackBufferMemory); // encode content into ackBuffer rsslClearEncodeIterator(&eIter); rsslSetEncodeIteratorRWFVersion(&eIter, pTunnelStream->classOfService.common.protocolMajorVersion, pTunnelStream->classOfService.common.protocolMajorVersion); rsslSetEncodeIteratorBuffer(&eIter, &ackBuffer); //// Start Content Encoding //// rsslClearFieldList(&fieldList); fieldList.flags = RSSL_FLF_HAS_STANDARD_DATA; if ((ret = rsslEncodeFieldListInit(&eIter, &fieldList, NULL, 0)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldListInit(): Failed <%d>\n", ret); return; } /* MsgType */ rsslClearFieldEntry(&fieldEntry); rsslClearBuffer(&fieldBuffer); fieldEntry.fieldId = 35; fieldEntry.dataType = RSSL_DT_BUFFER; fieldBuffer.length = 1; fieldBuffer.data = (char*)"8"; // 8 for execution report if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &fieldBuffer)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* OrderId */ rsslClearFieldEntry(&fieldEntry); rsslClearBuffer(&fieldBuffer); fieldEntry.fieldId = 37; fieldEntry.dataType = RSSL_DT_BUFFER; fieldBuffer.length = 18; fieldBuffer.data = (char*)"BATS-3456789-98765"; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &fieldBuffer)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* ClOrderId */ rsslClearFieldEntry(&fieldEntry); rsslClearBuffer(&fieldBuffer); fieldEntry.fieldId = 11; fieldEntry.dataType = RSSL_DT_BUFFER; fieldBuffer.length = 12; fieldBuffer.data = (char*)"100000020998"; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &fieldBuffer)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* ExecID */ rsslClearFieldEntry(&fieldEntry); rsslClearBuffer(&fieldBuffer); fieldEntry.fieldId = 17; fieldEntry.dataType = RSSL_DT_BUFFER; fieldBuffer.length = 10; fieldBuffer.data = (char*)"7654689076"; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &fieldBuffer)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* ExecType */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 150; fieldEntry.dataType = RSSL_DT_ENUM; enumVal = 0; // 0 for New, 1 for partial fill, 2 for fill, 3 for Done if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &enumVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* Order Status */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 39; fieldEntry.dataType = RSSL_DT_ENUM; enumVal = 0; // 0 for new, 1 for partial fill, 2 for fill, 3 for done if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &enumVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* Side */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 54; fieldEntry.dataType = RSSL_DT_ENUM; enumVal = 1; // 1 for buy if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &enumVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* LeavesQty */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 151; fieldEntry.dataType = RSSL_DT_UINT; uIntVal = 1000; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &uIntVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* CumQty */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 14; fieldEntry.dataType = RSSL_DT_UINT; uIntVal = 0; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &uIntVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* AvgPx */ rsslClearFieldEntry(&fieldEntry); fieldEntry.fieldId = 6; fieldEntry.dataType = RSSL_DT_REAL; rsslClearReal(&realVal); realVal.value = 0; realVal.hint = RSSL_RH_EXPONENT0; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &realVal)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } /* Symbol */ rsslClearFieldEntry(&fieldEntry); rsslClearBuffer(&fieldBuffer); fieldEntry.fieldId = 55; fieldEntry.dataType = RSSL_DT_BUFFER; fieldBuffer.length = 3; fieldBuffer.data = (char*)"TRI"; if ((ret = rsslEncodeFieldEntry(&eIter, &fieldEntry, &fieldBuffer)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry(): Failed <%d>\n", ret); return; } if ((ret = rsslEncodeFieldListComplete(&eIter, RSSL_TRUE)) != RSSL_RET_SUCCESS) { printf("rsslEncodeFieldListComplete(): Failed <%d>\n", ret); return; } //// End Content Encoding //// // set ackBuffer encoded length ackBuffer.length = rsslGetEncodedBufferLength(&eIter); // initialize the QueueData with the ackBuffer set as the encodedDataBody rsslClearRDMQueueData(&queueData); queueData.rdmMsgBase.streamId = streamId; queueData.identifier = ++pQueueMsgHandler->identifier; queueData.rdmMsgBase.domainType = QUEUE_MSG_DOMAIN; queueData.sourceName = pQueueMsgHandler->sourceName; queueData.destName = *pDestName; queueData.timeout = RDM_QMSG_TC_INFINITE; queueData.containerType = RSSL_DT_FIELD_LIST; queueData.encDataBody = ackBuffer; // submit QueueData message with the encodedDataBody to the tunnel stream rsslClearTunnelStreamSubmitMsgOptions(&submitMsgOpts); submitMsgOpts.pRDMMsg = (RsslRDMMsg *)&queueData; if ((ret = rsslTunnelStreamSubmitMsg(pQueueMsgHandler->tunnelStreamHandler.pTunnelStream, &submitMsgOpts, &rsslErrorInfo)) != RSSL_RET_SUCCESS) { printf("rsslTunnelStreamSubmitMsg(): Failed <%s>\n", rsslErrorInfo.rsslError.text); return; } printf("Submitted Exec Report message with ID %lld to %.*s.\n\n", pQueueMsgHandler->identifier, pDestName->length, pDestName->data); }
/* * Encodes the batch item request. Returns success if * encoding succeeds or failure if encoding fails. * chnl - The channel to send an item request to * msgBuf - The message buffer to encode the item request into * streamId - The stream id of the item request * isPrivateStream - Flag for private stream request * * This function is only used within the Market Price Handler * and each handler has its own implementation, although much is similar */ static RsslRet encodeBatchItemRequest(RsslChannel* chnl, RsslBuffer* msgBuf, RsslInt32 streamId, RsslBool isPrivateStream) { RsslRet ret = 0; RsslRequestMsg msg = RSSL_INIT_REQUEST_MSG; RsslElementList eList = RSSL_INIT_ELEMENT_LIST; RsslElementEntry eEntry = RSSL_INIT_ELEMENT_ENTRY; RsslArray elementArray = RSSL_INIT_ARRAY; RsslEncodeIterator encodeIter; RsslSourceDirectoryResponseInfo* srcDirRespInfo = 0; RsslBuffer itemName; int i; RsslLoginResponseInfo* loginInfo = getLoginResponseInfo(); if (getSourceDirectoryResponseInfo(getServiceId(), &srcDirRespInfo) != RSSL_RET_SUCCESS) return RSSL_RET_FAILURE; /* clear encode iterator */ rsslClearEncodeIterator(&encodeIter); /* set-up message */ msg.msgBase.msgClass = RSSL_MC_REQUEST; msg.msgBase.streamId = streamId; msg.msgBase.domainType = RSSL_DMT_MARKET_PRICE; msg.msgBase.containerType = RSSL_DT_ELEMENT_LIST; if (snapshotRequest) { msg.flags = RSSL_RQMF_HAS_QOS | RSSL_RQMF_HAS_PRIORITY | RSSL_RQMF_HAS_BATCH; } else { msg.flags = RSSL_RQMF_HAS_QOS | RSSL_RQMF_STREAMING | RSSL_RQMF_HAS_PRIORITY | RSSL_RQMF_HAS_BATCH; } if((loginInfo->SupportViewRequests == RSSL_TRUE) && (viewRequest == RSSL_TRUE)) { msg.flags |= RSSL_RQMF_HAS_VIEW; } if (isPrivateStream) { msg.flags |= RSSL_RQMF_PRIVATE_STREAM; } msg.priorityClass = 1; msg.priorityCount = 1; /* copy the QoS information */ rsslCopyQos(&(msg.qos), &(srcDirRespInfo->ServiceGeneralInfo.QoS[0])); /* specify msgKey members */ msg.msgBase.msgKey.flags = RSSL_MKF_HAS_NAME_TYPE | RSSL_MKF_HAS_SERVICE_ID; msg.msgBase.msgKey.nameType = RDM_INSTRUMENT_NAME_TYPE_RIC; msg.msgBase.msgKey.serviceId = (RsslUInt16)getServiceId(); /* encode message */ if((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) < RSSL_RET_SUCCESS) { printf("rsslSetEncodeIteratorBuffer() failed with return code: %d\n", ret); return ret; } rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); /* start the request message encoding */ if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&msg, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsg() failed with return code: %d\n", ret); return ret; } /* For Batch requests, the message has a payload of an element list that contains an array of the requested items */ eList.flags = RSSL_ELF_HAS_STANDARD_DATA; if((ret = rsslEncodeElementListInit(&encodeIter, &eList, 0, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementListInit() failed with return code: %d\n", ret); return ret; } eEntry.name = RSSL_ENAME_BATCH_ITEM_LIST; eEntry.dataType = RSSL_DT_ARRAY; if((ret = rsslEncodeElementEntryInit(&encodeIter, &eEntry, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementEntryInit() failed with return code: %d\n", ret); return ret; } /* Encode the array of requested item names */ elementArray.primitiveType = RSSL_DT_ASCII_STRING; elementArray.itemLength = 0; if((ret = rsslEncodeArrayInit(&encodeIter, &elementArray)) < RSSL_RET_SUCCESS) { printf("rsslEncodeArrayInit() failed with return code: %d\n", ret); return ret; } if (!isPrivateStream) /* non-private stream */ { for(i = 0; i < itemCount; i++) { itemName.data = marketPriceItemInfoList[i].itemname; itemName.length = marketPriceItemInfoList[i].nameLength; marketPriceItemInfoList[i].streamId = ++streamId; if((ret = rsslEncodeArrayEntry(&encodeIter, &itemName, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeArrayEntry() failed with return code: %d\n", ret); return ret; } } } else /* private stream */ { for(i = 0; i < privateStreamItemCount; i++) { itemName.data = marketPricePSItemInfoList[i].itemname; itemName.length = marketPricePSItemInfoList[i].nameLength; marketPricePSItemInfoList[i].streamId = ++streamId; if((ret = rsslEncodeArrayEntry(&encodeIter, &itemName, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeArrayEntry() failed with return code: %d\n", ret); return ret; } } } if((ret = rsslEncodeArrayComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeArrayComplete() failed with return code: %d\n", ret); return ret; } if((ret = rsslEncodeElementEntryComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementEntryComplete() failed with return code: %d\n", ret); return ret; } /* * Encode a view request into the list. */ if((loginInfo->SupportViewRequests == RSSL_TRUE) && (viewRequest == RSSL_TRUE) ) encodeViewElementRequest(&encodeIter); if((ret = rsslEncodeElementListComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementListComplete() failed with return code: %d\n", ret); return ret; } if((ret = rsslEncodeMsgComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMessageComplete() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
/* * Encodes the batch item close message. Returns success if * encoding succeeds or failure if encoding fails. * chnl - The channel to send a batch item close message to * msgBuf - The message buffer to encode the batch item close msg into * batchCloseStreamId - The stream id of the batch item close message * * This function is only used within the Market Price Handler * and each handler has its own implementation, although much is similar */ static RsslRet encodeBatchItemClose(RsslChannel* chnl, RsslBuffer* msgBuf, RsslInt32 batchCloseStreamId) { RsslRet ret = 0; RsslCloseMsg msg; RsslElementList eList; RsslElementEntry eEntry; RsslArray elementArray; RsslEncodeIterator encodeIter; RsslInt itemStreamId; int i; /* clear encode iterator */ rsslClearEncodeIterator(&encodeIter); /* set-up message */ rsslClearCloseMsg(&msg); msg.msgBase.msgClass = RSSL_MC_CLOSE; msg.msgBase.streamId = batchCloseStreamId; msg.flags = RSSL_CLMF_HAS_BATCH; msg.msgBase.domainType = RSSL_DMT_MARKET_PRICE; msg.msgBase.containerType = RSSL_DT_ELEMENT_LIST; /* encode message */ if((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) < RSSL_RET_SUCCESS) { printf("rsslSetEncodeIteratorBuffer() failed with return code: %d\n", ret); return ret; } rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); /* start the batch close message encoding */ if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&msg, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsg() failed with return code: %d\n", ret); return ret; } /* For Batch close, the message has a payload of an element list that contains an array of streamIDs in which the client registers interest for close */ rsslClearElementList(&eList); eList.flags = RSSL_ELF_HAS_STANDARD_DATA; if((ret = rsslEncodeElementListInit(&encodeIter, &eList, 0, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementListInit() failed with return code: %d\n", ret); return ret; } rsslClearElementEntry(&eEntry); eEntry.name = RSSL_ENAME_BATCH_STREAMID_LIST; eEntry.dataType = RSSL_DT_ARRAY; if((ret = rsslEncodeElementEntryInit(&encodeIter, &eEntry, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeelementEntryEntryInit() failed with return code: %d\n", ret); return ret; } /* Encode the array of streamIDs in which the client registers interest for close */ rsslClearArray(&elementArray); elementArray.primitiveType = RSSL_DT_INT; elementArray.itemLength = 0; /* Array will have variable length entries */ if((ret = rsslEncodeArrayInit(&encodeIter, &elementArray)) < RSSL_RET_SUCCESS) { printf("rsslEncodeArrayInit() failed with return code: %d\n", ret); return ret; } /* encode payload with streamId list */ for(i = 0; i < itemCount; i++) { itemStreamId = i + MARKETPRICE_STREAM_ID_START; /* we only want to close a stream if it was not already closed (e.g. rejected by provider, closed via refresh or status, or redirected) */ if (!rsslIsFinalState(&marketPriceItemInfoList[i].itemState)) { if((ret = rsslEncodeArrayEntry(&encodeIter, 0, (void*)(&itemStreamId))) < RSSL_RET_SUCCESS) { printf("rsslEncodeArrayEntry() failed with return code: %d\n", ret); return ret; } } } for(i = 0; i < privateStreamItemCount; i++) { itemStreamId = i + MARKETPRICE_PRIVATE_STREAM_ID_START; /* we only want to close a stream if it was not already closed (e.g. rejected by provider, closed via refresh or status, or redirected) */ if (!rsslIsFinalState(&marketPricePSItemInfoList[i].itemState)) { if((ret = rsslEncodeArrayEntry(&encodeIter, 0, (void*)(&itemStreamId))) < RSSL_RET_SUCCESS) { printf("rsslEncodeArrayEntry() failed with return code: %d\n", ret); return ret; } } } if((ret = rsslEncodeArrayComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeArrayComplete() failed with return code: %d\n", ret); return ret; } if((ret = rsslEncodeElementEntryComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeelementEntryEntryComplete() failed with return code: %d\n", ret); return ret; } if((ret = rsslEncodeElementListComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeElementListComplete() failed with return code: %d\n", ret); return ret; } if((ret = rsslEncodeMsgComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMessageComplete() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
RsslReactorCallbackRet simpleTunnelMsgHandlerProviderMsgCallback(RsslTunnelStream *pTunnelStream, RsslTunnelStreamMsgEvent *pEvent) { RsslMsg *pRsslMsg = pEvent->pRsslMsg; RsslReactorChannel *pReactorChannel = pTunnelStream->pReactorChannel; SimpleTunnelMsgHandler *pSimpleTunnelMsgHandler = (SimpleTunnelMsgHandler*)pTunnelStream->userSpecPtr; /* Inspect the message and handle it accordingly. This is basically * the same as the consumer's message callback but will respond to the * client's authentication login message if one is received. */ switch(pEvent->containerType) { case RSSL_DT_OPAQUE: { /* Read the text contained. */ printf("Tunnel Stream %d received OPAQUE data: %.*s\n\n", pTunnelStream->streamId, pEvent->pRsslBuffer->length, pEvent->pRsslBuffer->data); break; } case RSSL_DT_MSG: { switch(pRsslMsg->msgBase.domainType) { case RSSL_DMT_LOGIN: { RsslDecodeIterator dIter; RsslRDMLoginMsg loginMsg; char tmpMemory[1024]; RsslBuffer memoryBuffer; RsslRet ret; RsslErrorInfo errorInfo; /* Use the ValueAdd RDM Decoder to decode the login message. */ rsslClearDecodeIterator(&dIter); rsslSetDecodeIteratorRWFVersion(&dIter, pTunnelStream->classOfService.common.protocolMajorVersion, pTunnelStream->classOfService.common.protocolMinorVersion); rsslSetDecodeIteratorBuffer(&dIter, &pRsslMsg->msgBase.encDataBody); rsslClearBuffer(&memoryBuffer); memoryBuffer.length = sizeof(tmpMemory); memoryBuffer.data = tmpMemory; if ((ret = rsslDecodeRDMLoginMsg(&dIter, pRsslMsg, &loginMsg, &memoryBuffer, &errorInfo)) != RSSL_RET_SUCCESS) { printf("rsslDecodeRDMLoginMsg() failed: %s(%s)\n", rsslRetCodeToString(ret), errorInfo.rsslError.text); break; } switch(loginMsg.rdmMsgBase.rdmMsgType) { case RDM_LG_MT_REQUEST: { /* This is a login request, likely the client's authentication * request. Send a response to establish the tunnel stream. */ RsslRDMLoginRefresh loginRefresh; RsslTunnelStreamSubmitOptions submitOpts; RsslTunnelStreamGetBufferOptions bufferOpts; RsslBuffer *pBuffer; RsslEncodeIterator eIter; RsslRet ret, ret2; RsslRDMLoginRequest *pLoginRequest = &loginMsg.request; printf("Received login request on tunnel stream(ID %d) with stream ID %d.\n", pTunnelStream->streamId, pLoginRequest->rdmMsgBase.streamId); if (pLoginRequest->flags & RDM_LG_RQF_NO_REFRESH) break; rsslClearTunnelStreamGetBufferOptions(&bufferOpts); bufferOpts.size = 1024; if ((pBuffer = rsslTunnelStreamGetBuffer(pTunnelStream, &bufferOpts, &errorInfo)) == NULL) { printf("rsslTunnelStreamGetBuffer failed: %s(%s)\n", rsslRetCodeToString(errorInfo.rsslError.rsslErrorId), &errorInfo.rsslError.text); break; } rsslClearRDMLoginRefresh(&loginRefresh); /* Set state information */ loginRefresh.state.streamState = RSSL_STREAM_OPEN; loginRefresh.state.dataState = RSSL_DATA_OK; loginRefresh.state.code = RSSL_SC_NONE; loginRefresh.state.text.data = (char*)"Tunnel login accepted."; loginRefresh.state.text.length = (RsslUInt32)strlen(loginRefresh.state.text.data); /* Set stream ID */ loginRefresh.rdmMsgBase.streamId = pLoginRequest->rdmMsgBase.streamId; /* Mark refresh as solicited since it is a response to a request. */ loginRefresh.flags = RDM_LG_RFF_SOLICITED; /* Echo the userName, applicationId, applicationName, and position */ loginRefresh.flags |= RDM_LG_RFF_HAS_USERNAME; loginRefresh.userName = pLoginRequest->userName; if (pLoginRequest->flags & RDM_LG_RQF_HAS_USERNAME_TYPE) { loginRefresh.flags |= RDM_LG_RFF_HAS_USERNAME_TYPE; loginRefresh.userNameType = pLoginRequest->userNameType; } loginRefresh.flags |= RDM_LG_RFF_HAS_APPLICATION_ID; loginRefresh.applicationId = pLoginRequest->applicationId; loginRefresh.flags |= RDM_LG_RFF_HAS_APPLICATION_NAME; loginRefresh.applicationName = pLoginRequest->applicationName; loginRefresh.flags |= RDM_LG_RFF_HAS_POSITION; loginRefresh.position = pLoginRequest->position; /* This provider does not support Single-Open behavior. */ loginRefresh.flags |= RDM_LG_RFF_HAS_SINGLE_OPEN; loginRefresh.singleOpen = 0; /* set the clear cache flag */ loginRefresh.flags |= RDM_LG_RFF_CLEAR_CACHE; /* Leave all other parameters as default values. */ /* Encode the refresh. */ rsslClearEncodeIterator(&eIter); rsslSetEncodeIteratorRWFVersion(&eIter, pTunnelStream->classOfService.common.protocolMajorVersion, pTunnelStream->classOfService.common.protocolMinorVersion); if((ret = rsslSetEncodeIteratorBuffer(&eIter, pBuffer)) < RSSL_RET_SUCCESS) { printf("rsslSetEncodeIteratorBuffer(): Failed <%s>\n", errorInfo.rsslError.text); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &errorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, errorInfo.rsslError.text); break; } if (rsslEncodeRDMLoginMsg(&eIter, (RsslRDMLoginMsg*)&loginRefresh, &pBuffer->length, &errorInfo) != RSSL_RET_SUCCESS) { printf("rsslEncodeRDMLoginMsg(): Failed <%s>\n", errorInfo.rsslError.text); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &errorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, errorInfo.rsslError.text); break; } /* Message encoding complete; submit it. */ rsslClearTunnelStreamSubmitOptions(&submitOpts); submitOpts.containerType = RSSL_DT_MSG; if ((ret = rsslTunnelStreamSubmit(pTunnelStream, pBuffer, &submitOpts, &errorInfo)) != RSSL_RET_SUCCESS) { printf("rsslTunnelStreamSubmit(): Failed <%s>\n", errorInfo.rsslError.text); if ((ret2 = rsslTunnelStreamReleaseBuffer(pBuffer, &errorInfo)) != RSSL_RET_SUCCESS) printf("rsslTunnelStreamReleaseBuffer(): Failed <%d:%s>\n", ret2, errorInfo.rsslError.text); break; } printf("Sent response to tunnel login request.\n\n"); pSimpleTunnelMsgHandler->waitingForAuthenticationRequest = RSSL_FALSE; break; } case RDM_LG_MT_CLOSE: { /* Login close message. */ RsslRDMLoginClose *pLoginClose = &loginMsg.close; printf("Received login close on tunnel stream(ID %d) with stream ID %d.\n", pTunnelStream->streamId, pLoginClose->rdmMsgBase.streamId); break; } } break; } default: { /* Don't recognize this message. */ printf("Received unhandled message in TunnelStream with stream ID %d, class %u(%s) and domainType %u(%s)\n\n", pRsslMsg->msgBase.streamId, pRsslMsg->msgBase.msgClass, rsslMsgClassToString(pRsslMsg->msgBase.msgClass), pRsslMsg->msgBase.domainType, rsslDomainTypeToString(pRsslMsg->msgBase.domainType)); break; } } break; } default: { printf("Received unhandled buffer containerType %d(%s) in tunnel stream %d\n\n", pEvent->containerType, rsslDataTypeToString(pEvent->containerType), pTunnelStream->streamId); break; } } return RSSL_RC_CRET_SUCCESS; }
RsslRet encodeItemRefresh(RsslChannel* chnl, ItemInfo* itemInfo, RsslBuffer* msgBuf, RsslPostUserInfo *pPostUserInfo, RsslUInt encodeStartTime) { RsslRet ret; RsslRefreshMsg refreshMsg; RsslEncodeIterator encodeIter; rsslClearEncodeIterator(&encodeIter); rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); if ((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) != RSSL_RET_SUCCESS) return ret; rsslClearRefreshMsg(&refreshMsg); refreshMsg.flags = RSSL_RFMF_HAS_MSG_KEY | RSSL_RFMF_REFRESH_COMPLETE | RSSL_RFMF_HAS_QOS | RSSL_RFMF_CLEAR_CACHE; if (itemInfo->itemFlags & ITEM_IS_SOLICITED) refreshMsg.flags |= RSSL_RFMF_SOLICITED; if (itemInfo->itemFlags & ITEM_IS_PRIVATE) refreshMsg.flags |= RSSL_RFMF_PRIVATE_STREAM; refreshMsg.msgBase.msgKey = *itemInfo->attributes.pMsgKey; refreshMsg.msgBase.streamId = itemInfo->StreamId; /* Images for snapshot requests should use the non-streaming state. */ refreshMsg.state.streamState = (itemInfo->itemFlags & ITEM_IS_STREAMING_REQ) ? RSSL_STREAM_OPEN : RSSL_STREAM_NON_STREAMING; refreshMsg.state.dataState = RSSL_DATA_OK; refreshMsg.state.code = RSSL_SC_NONE; refreshMsg.qos.dynamic = RSSL_FALSE; refreshMsg.qos.rate = RSSL_QOS_RATE_TICK_BY_TICK; refreshMsg.qos.timeliness = RSSL_QOS_TIME_REALTIME; refreshMsg.msgBase.domainType = itemInfo->attributes.domainType; if (pPostUserInfo) { refreshMsg.flags |= RSSL_RFMF_HAS_POST_USER_INFO; refreshMsg.postUserInfo = *pPostUserInfo; } switch(itemInfo->attributes.domainType) { case RSSL_DMT_MARKET_PRICE: refreshMsg.msgBase.containerType = RSSL_DT_FIELD_LIST; if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&refreshMsg, 0)) < RSSL_RET_SUCCESS) return ret; if ((ret = encodeMarketPriceDataBody(&encodeIter, &xmlMarketPriceMsgs.refreshMsg, RSSL_MC_REFRESH, encodeStartTime)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DMT_MARKET_BY_ORDER: refreshMsg.msgBase.containerType = RSSL_DT_MAP; if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&refreshMsg, 0)) < RSSL_RET_SUCCESS) return ret; if ((ret = encodeMarketByOrderDataBody(&encodeIter, &xmlMarketByOrderMsgs.refreshMsg, RSSL_MC_REFRESH, encodeStartTime)) < RSSL_RET_SUCCESS) return ret; break; default: assert(0); break; } if ((ret = rsslEncodeMsgComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) return ret; msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
RsslRet snapshotSessionRequestItems(SnapshotSession *pSession) { RsslUInt32 i; RsslEncodeIterator encodeIter; RsslRequestMsg requestMsg; RsslBuffer *pBuffer; RsslError rsslError; RsslRet ret; for (i = 0; i < itemList.itemCount; ++i) { Item *pItem = &itemList.items[i]; if (!(pBuffer = rsslGetBuffer(pSession->pRsslChannel, 128, RSSL_FALSE, &rsslError))) { printf("<%s> rsslGetBuffer() failed while sending item request: %d (%s -- %s).\n\n", pSession->name, rsslError.rsslErrorId, rsslRetCodeToString(rsslError.rsslErrorId), rsslError.text); return ret; } rsslClearRequestMsg(&requestMsg); requestMsg.flags = RSSL_RQMF_HAS_QOS; requestMsg.msgBase.streamId = pItem->snapshotServerStreamId; requestMsg.msgBase.domainType = pItem->domainType; requestMsg.msgBase.containerType = RSSL_DT_NO_DATA; requestMsg.qos.rate = RSSL_QOS_RATE_TICK_BY_TICK; requestMsg.qos.timeliness = RSSL_QOS_TIME_REALTIME; /* This system uses the real-time feed's stream ID as the name. */ requestMsg.msgBase.msgKey.flags = RSSL_MKF_HAS_SERVICE_ID | RSSL_MKF_HAS_IDENTIFIER; requestMsg.msgBase.msgKey.identifier = pItem->feedStreamId; requestMsg.msgBase.msgKey.serviceId = exampleConfig.serviceId; rsslClearEncodeIterator(&encodeIter); rsslSetEncodeIteratorRWFVersion(&encodeIter, pSession->pRsslChannel->majorVersion, pSession->pRsslChannel->minorVersion); rsslSetEncodeIteratorBuffer(&encodeIter, pBuffer); if ((ret = rsslEncodeMsg(&encodeIter, (RsslMsg*)&requestMsg)) != RSSL_RET_SUCCESS) { printf("<%s> rsslEncodeMsg() failed while sending item request: %d (%s).\n\n", pSession->name, ret, rsslRetCodeToString(ret)); rsslReleaseBuffer(pBuffer, &rsslError); return ret; } pBuffer->length = rsslGetEncodedBufferLength(&encodeIter); /* Write the message. */ if ((ret = snapshotSessionWrite(pSession, pBuffer)) != RSSL_RET_SUCCESS) return ret; printf("<%s> Sent request for item %s, %s on stream %d.\n\n", pSession->name, pItem->symbolName, rsslDomainTypeToString(pItem->domainType), pItem->snapshotServerStreamId); } return RSSL_RET_SUCCESS; }
RsslRet encodeItemRequestReject(RsslChannel* chnl, RsslInt32 streamId, ItemRejectReason reason, RsslBuffer* msgBuf, RsslUInt8 domainType) { RsslRet ret = 0; RsslStatusMsg msg = RSSL_INIT_STATUS_MSG; char stateText[128]; RsslEncodeIterator encodeIter; /* clear encode iterator */ rsslClearEncodeIterator(&encodeIter); /* set-up message */ msg.msgBase.msgClass = RSSL_MC_STATUS; msg.msgBase.streamId = streamId; msg.msgBase.domainType = domainType; msg.msgBase.containerType = RSSL_DT_NO_DATA; msg.flags = RSSL_STMF_HAS_STATE; msg.state.streamState = RSSL_STREAM_CLOSED_RECOVER; msg.state.dataState = RSSL_DATA_SUSPECT; switch (reason) { case ITEM_COUNT_REACHED: msg.state.code = RSSL_SC_TOO_MANY_ITEMS; snprintf(stateText, 128, "Item request rejected for stream id %d - item count reached for this channel", streamId); msg.state.text.data = stateText; msg.state.text.length = (RsslUInt32)strlen(stateText) + 1; break; case INVALID_SERVICE_ID: msg.state.code = RSSL_SC_USAGE_ERROR; msg.state.streamState = RSSL_STREAM_CLOSED; snprintf(stateText, 128, "Item request rejected for stream id %d - service id invalid", streamId); msg.state.text.data = stateText; msg.state.text.length = (RsslUInt32)strlen(stateText) + 1; break; case QOS_NOT_SUPPORTED: msg.state.code = RSSL_SC_USAGE_ERROR; msg.state.streamState = RSSL_STREAM_CLOSED; snprintf(stateText, 128, "Item request rejected for stream id %d - QoS not supported", streamId); msg.state.text.data = stateText; msg.state.text.length = (RsslUInt32)strlen(stateText) + 1; break; case ITEM_ALREADY_OPENED: msg.state.code = RSSL_SC_ALREADY_OPEN; snprintf(stateText, 128, "Item request rejected for stream id %d - item already open with exact same key on another stream", streamId); msg.state.text.data = stateText; msg.state.text.length = (RsslUInt32)strlen(stateText) + 1; break; case STREAM_ALREADY_IN_USE: msg.state.code = RSSL_SC_USAGE_ERROR; snprintf(stateText, 128, "Item request rejected for stream id %d - stream already in use with a different key", streamId); msg.state.text.data = stateText; msg.state.text.length = (RsslUInt32)strlen(stateText) + 1; break; case DOMAIN_NOT_SUPPORTED: msg.state.code = RSSL_SC_USAGE_ERROR; msg.state.streamState = RSSL_STREAM_CLOSED; snprintf(stateText, 128, "Item request rejected for stream id %d - this provider does not support domain %u", streamId, domainType); msg.state.text.data = stateText; msg.state.text.length = (RsslUInt32)strlen(stateText) + 1; break; default: break; } /* encode message */ rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf); rsslSetEncodeIteratorRWFVersion(&encodeIter, chnl->majorVersion, chnl->minorVersion); if ((ret = rsslEncodeMsg(&encodeIter, (RsslMsg*)&msg)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsg() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
static RsslRet encodeSymbolListRequest(SnapshotSession* pSession, RsslBuffer* msgBuf, RsslInt32 streamId) { RsslRet ret = 0; RsslRequestMsg msg; RsslEncodeIterator encodeIter; RsslQos *pQos; /* clear encode iterator*/ rsslClearEncodeIterator(&encodeIter); /*set-up message*/ rsslClearRequestMsg(&msg); msg.msgBase.msgClass = RSSL_MC_REQUEST; msg.msgBase.streamId = streamId; msg.msgBase.domainType = RSSL_DMT_SYMBOL_LIST; msg.msgBase.containerType = RSSL_DT_NO_DATA; msg.flags = RSSL_RQMF_HAS_PRIORITY; msg.priorityClass = 1; msg.priorityCount = 1; /* Use a QoS from the service, if one is given. */ if ((pSession->pService->flags & RDM_SVCF_HAS_INFO) && (pSession->pService->info.flags & RDM_SVC_IFF_HAS_QOS) && (pSession->pService->info.qosCount > 0)) { pQos = &pSession->pService->info.qosList[0]; } else { pQos = NULL; } if (pQos) { msg.flags |= RSSL_RQMF_HAS_QOS; msg.qos = *pQos; } /* specify msgKey members */ msg.msgBase.msgKey.flags = RSSL_MKF_HAS_NAME_TYPE | RSSL_MKF_HAS_NAME | RSSL_MKF_HAS_SERVICE_ID; msg.msgBase.msgKey.nameType = RDM_INSTRUMENT_NAME_TYPE_RIC; msg.msgBase.msgKey.serviceId = (RsslUInt16)(pSession->pService->serviceId); /* if the there was no symbol list name included in the source directory, set the name data to NULL */ if ((pSession->pService->flags & RDM_SVCF_HAS_INFO) && (pSession->pService->info.flags & RDM_SVC_IFF_HAS_ITEM_LIST ) && (pSession->pService->info.itemList.length > 0)) { msg.msgBase.msgKey.name.length = pSession->pService->info.itemList.length; msg.msgBase.msgKey.name.data = pSession->pService->info.itemList.data; } else { msg.msgBase.msgKey.name.data = NULL; } /* encode message */ if((ret = rsslSetEncodeIteratorBuffer(&encodeIter, msgBuf)) < RSSL_RET_SUCCESS) { printf("<%s> rsslEncodeIteratorBuffer() failed with return code: %d\n", pSession->name, ret); return ret; } rsslSetEncodeIteratorRWFVersion(&encodeIter, pSession->pRsslChannel->majorVersion, pSession->pRsslChannel->minorVersion); if ((ret = rsslEncodeMsgInit(&encodeIter, (RsslMsg*)&msg, 0)) < RSSL_RET_SUCCESS) { printf("<%s> rsslEncodeMsgInit() failed with return code: %d\n", pSession->name, ret); return ret; } if((ret = rsslEncodeMsgComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("<%s> rsslEncodeMessageComplete() failed with return code: %d\n", pSession->name, ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }
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); }
/* * Encodes the symbol list response. Returns success if * encoding succeeds or failure if encoding fails. * pReactorChannel - The channel to send a market price response to * itemInfo - The item information * isSolicited - The response is solicited if set * msgBuf - The message buffer to encode the market price response into * streamId - The stream id of the market price response * isStreaming - Flag for streaming or snapshot * serviceId - The service id of the market price response * dictionary - The dictionary used for encoding * itemName - the name of the item to be encoded (this value is NULL if a refresh msg is being encoded) * responseType- The type of response to be encoded: refresh, add update, or delete update */ RsslRet encodeSymbolListResponse(RsslReactorChannel* pReactorChannel, RsslItemInfo* itemInfo, RsslBuffer* msgBuf, RsslBool isSolicited, RsslInt32 streamId, RsslBool isStreaming, RsslUInt16 serviceId, RsslDataDictionary* dictionary, char* itemName, RsslUInt8 responseType) { RsslRet ret = 0; RsslRefreshMsg refreshMsg = RSSL_INIT_REFRESH_MSG; RsslUpdateMsg updateMsg = RSSL_INIT_UPDATE_MSG; RsslMsgBase* msgBase; RsslMsg* msg; RsslMap map = RSSL_INIT_MAP; RsslMapEntry mapEntry = RSSL_INIT_MAP_ENTRY; RsslFieldList fList = RSSL_INIT_FIELD_LIST; RsslFieldEntry fEntry = RSSL_INIT_FIELD_ENTRY; char stateText[MAX_ITEM_INFO_STRLEN]; char errTxt[256]; RsslBuffer errorText = {255, (char*)errTxt}; RsslEncodeIterator encodeIter; RsslBuffer tmpBuf; RsslUInt32 i = 0; rsslClearEncodeIterator(&encodeIter); /*set-up message*/ /*set message depending on whether refresh or update*/ if (responseType == SYMBOL_LIST_REFRESH) /*this is a refresh message*/ { msgBase = &refreshMsg.msgBase; msgBase->msgClass = RSSL_MC_REFRESH; refreshMsg.state.streamState = RSSL_STREAM_OPEN; if (isStreaming) { refreshMsg.state.dataState = RSSL_DATA_OK; } else { refreshMsg.state.streamState = RSSL_STREAM_NON_STREAMING; } refreshMsg.state.code = RSSL_SC_NONE; if (isSolicited) { refreshMsg.flags = RSSL_RFMF_HAS_MSG_KEY | RSSL_RFMF_SOLICITED | RSSL_RFMF_REFRESH_COMPLETE | RSSL_RFMF_HAS_QOS | RSSL_RFMF_CLEAR_CACHE; } else { refreshMsg.flags = RSSL_RFMF_HAS_MSG_KEY | RSSL_RFMF_REFRESH_COMPLETE | RSSL_RFMF_HAS_QOS | RSSL_RFMF_CLEAR_CACHE; } sprintf(stateText, "Item Refresh Completed"); refreshMsg.state.text.data = stateText; refreshMsg.state.text.length = (RsslUInt32)strlen(stateText); msgBase->msgKey.flags = RSSL_MKF_HAS_SERVICE_ID | RSSL_MKF_HAS_NAME; /* ServiceId*/ msgBase->msgKey.serviceId = serviceId; /* Itemname */ msgBase->msgKey.name.data = itemInfo->Itemname; msgBase->msgKey.name.length = (RsslUInt32)strlen(itemInfo->Itemname); /* Qos */ refreshMsg.qos.dynamic = RSSL_FALSE; refreshMsg.qos.rate = RSSL_QOS_RATE_TICK_BY_TICK; refreshMsg.qos.timeliness = RSSL_QOS_TIME_REALTIME; msg = (RsslMsg *)&refreshMsg; } else /*this is an update message */ { msgBase = &updateMsg.msgBase; msgBase->msgClass = RSSL_MC_UPDATE; msg = (RsslMsg *)&updateMsg; } msgBase->domainType = RSSL_DMT_SYMBOL_LIST; msgBase->containerType = RSSL_DT_MAP; /* StreamId*/ msgBase->streamId = streamId; /* encode message */ if((ret = rsslSetEncodeIteratorBuffer(&encodeIter,msgBuf)) < RSSL_RET_SUCCESS) { printf("rsslSetEncodeIteratorBuffer() failed with return code: %d\n", ret); return ret; } rsslSetEncodeIteratorRWFVersion(&encodeIter, pReactorChannel->majorVersion, pReactorChannel->minorVersion); if ((ret = rsslEncodeMsgInit(&encodeIter, msg, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsgInit() failed with return code: %d\n", ret); return ret; } /*encode map*/ map.flags = 0; map.containerType = RSSL_DT_NO_DATA; map.keyPrimitiveType = RSSL_DT_BUFFER; if ((ret = rsslEncodeMapInit(&encodeIter, &map, 0, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMapInit() failed with return code: %d\n", ret); return ret; } /* encode map entry */ rsslClearMapEntry(&mapEntry); mapEntry.flags = RSSL_MPEF_NONE; switch(responseType) { /* this is a refresh message, so begin encoding the entire symbol list */ case SYMBOL_LIST_REFRESH: tmpBuf.data = symbolListItemList[i].itemName; mapEntry.action = RSSL_MPEA_ADD_ENTRY; break; /* this is an update message adding a name, so only encode the item being added to the list */ case SYMBOL_LIST_UPDATE_ADD: tmpBuf.data = itemName; mapEntry.action = RSSL_MPEA_ADD_ENTRY; break; /* this is an update message deleting a name */ case SYMBOL_LIST_UPDATE_DELETE: tmpBuf.data = itemName; mapEntry.action = RSSL_MPEA_DELETE_ENTRY; break; } tmpBuf.length = (RsslUInt32)strlen(tmpBuf.data); if((ret = rsslEncodeMapEntryInit(&encodeIter, &mapEntry, &tmpBuf, 0)) < RSSL_RET_SUCCESS) { printf("rsslEncodeFieldEntry() failed with return code: %d\n", ret); return ret; } if ((ret = rsslEncodeMapEntryComplete(&encodeIter, RSSL_TRUE))) { printf("rsslEncodeMapEntryComplete() failed with return code: %d\n", ret); return ret; } /* if this is a refresh message, finish encoding the entire symbol list in the response */ if (responseType == SYMBOL_LIST_REFRESH) { for(i = 1; i < MAX_SYMBOL_LIST_SIZE; i++) { if(symbolListItemList[i].isInUse == RSSL_TRUE) { tmpBuf.data = symbolListItemList[i].itemName; tmpBuf.length = (RsslUInt32)strlen(tmpBuf.data); if ((ret = rsslEncodeMapEntry(&encodeIter, &mapEntry, &tmpBuf)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMapEntry() failed with return code: %d\n", ret); return ret; } } } } /* complete map */ if ((ret = rsslEncodeMapComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMapComplete() failed with return code: %d\n", ret); return ret; } /* complete encode message */ if ((ret = rsslEncodeMsgComplete(&encodeIter, RSSL_TRUE)) < RSSL_RET_SUCCESS) { printf("rsslEncodeMsgComplete() failed with return code: %d\n", ret); return ret; } msgBuf->length = rsslGetEncodedBufferLength(&encodeIter); return RSSL_RET_SUCCESS; }