void queueMsgHandlerInit(QueueMsgHandler *pQueueMsgHandler, char *consumerName, RsslUInt8 domainType, RsslBool useAuthentication) { int i; tunnelStreamHandlerInit(&pQueueMsgHandler->tunnelStreamHandler, consumerName, domainType, useAuthentication, RSSL_TRUE /* Queue messaging */, queueMsgHandlerProcessTunnelOpened, queueMsgHandlerProcessTunnelClosed, queueMsgHandlerDefaultMsgCallback, queueMsgHandlerQueueMsgCallback); rsslClearBuffer(&pQueueMsgHandler->sourceName); for (i = 0; i < MAX_DEST_NAMES; ++i) rsslClearBuffer(&pQueueMsgHandler->destNames[i]); pQueueMsgHandler->destNameCount = 0; pQueueMsgHandler->isQueueStreamOpen = RSSL_FALSE; pQueueMsgHandler->identifier = 0; }
/* * 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); }
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; }