RsslReactorCallbackRet simpleTunnelMsgHandlerConsumerMsgCallback(RsslTunnelStream *pTunnelStream, RsslTunnelStreamMsgEvent *pEvent) { 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; } 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 decodeMBOUpdate(RsslDecodeIterator* pIter, RsslMsg* msg, ProviderThread* pProviderThread) { RsslFieldList fList = RSSL_INIT_FIELD_LIST; RsslFieldEntry fEntry = RSSL_INIT_FIELD_ENTRY; RsslMap Map = RSSL_INIT_MAP; RsslMapEntry mEntry = RSSL_INIT_MAP_ENTRY; RsslRet ret = 0; RsslPrimitive key; RsslDataType dataType; RsslPrimitive primitive; RsslDictionaryEntry* dictionaryEntry = NULL; RsslUInt genMsgTimeTracker = 0; /* decode field list */ if((ret = rsslDecodeMap(pIter, &Map)) == RSSL_RET_SUCCESS) { if(rsslMapCheckHasSetDefs(&Map) == RSSL_TRUE) { rsslClearLocalFieldSetDefDb(&pProviderThread->fListSetDef); pProviderThread->fListSetDef.entries.data = pProviderThread->setDefMemory; pProviderThread->fListSetDef.entries.length = sizeof(pProviderThread->setDefMemory); if((ret = rsslDecodeLocalFieldSetDefDb(pIter, &pProviderThread->fListSetDef)) != RSSL_RET_SUCCESS) return ret; } if(rsslMapCheckHasSummaryData(&Map) == RSSL_TRUE) { if((ret = rsslDecodeFieldList(pIter, &fList, &pProviderThread->fListSetDef)) == RSSL_RET_SUCCESS) { while ((ret = rsslDecodeFieldEntry(pIter, &fEntry)) != RSSL_RET_END_OF_CONTAINER) { if (ret != RSSL_RET_SUCCESS) return ret; /* get dictionary entry */ dictionaryEntry = getDictionaryEntry(pProviderThread->pDictionary, fEntry.fieldId); if (!dictionaryEntry) { printf("Error: Decoded field ID %d not present in dictionary.\n", fEntry.fieldId); return RSSL_RET_FAILURE; } /* decode and print out fid value */ dataType = dictionaryEntry->rwfType; switch (dataType) { case RSSL_DT_INT: if((ret = rsslDecodeInt(pIter, &primitive.intType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_UINT: if((ret = rsslDecodeUInt(pIter, &primitive.uintType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_FLOAT: if ((ret = rsslDecodeFloat(pIter, &primitive.floatType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DOUBLE: if ((ret = rsslDecodeDouble(pIter, &primitive.doubleType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_REAL: if ((ret = rsslDecodeReal(pIter, &primitive.realType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DATE: if ((ret = rsslDecodeDate(pIter, &primitive.dateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_TIME: if ((ret = rsslDecodeTime(pIter, &primitive.timeType)) < RSSL_RET_SUCCESS ) return ret; break; case RSSL_DT_DATETIME: if ((ret = rsslDecodeDateTime(pIter, &primitive.dateTimeType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_QOS: if ((ret = rsslDecodeQos(pIter, &primitive.qosType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_STATE: if ((ret = rsslDecodeState(pIter, &primitive.stateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_ENUM: { RsslEnumType *pEnumTypeInfo; if ((ret = rsslDecodeEnum(pIter, &primitive.enumType)) < RSSL_RET_SUCCESS ) return ret; if (ret == RSSL_RET_BLANK_DATA) break; pEnumTypeInfo = getFieldEntryEnumType(dictionaryEntry, primitive.enumType); if (pEnumTypeInfo) primitive.bufferType = pEnumTypeInfo->display; break; } case RSSL_DT_BUFFER: case RSSL_DT_ASCII_STRING: case RSSL_DT_UTF8_STRING: case RSSL_DT_RMTES_STRING: if ((ret = rsslDecodeBuffer(pIter, &primitive.bufferType)) < RSSL_RET_SUCCESS ) return ret; break; default: printf("Error: Unhandled data type %s(%u) in field with ID %u.\n", rsslDataTypeToString(dataType), dataType, fEntry.fieldId); return RSSL_RET_FAILURE; } if (msg->msgBase.msgClass == RSSL_MC_GENERIC && ret != RSSL_RET_BLANK_DATA) { if(fEntry.fieldId == TIM_TRK_3_FID) genMsgTimeTracker = primitive.uintType; } } } else { return ret; } } while((ret = rsslDecodeMapEntry(pIter, &mEntry, &key)) != RSSL_RET_END_OF_CONTAINER) { if (mEntry.action != RSSL_MPEA_DELETE_ENTRY) { if((ret = rsslDecodeFieldList(pIter, &fList, &pProviderThread->fListSetDef)) == RSSL_RET_SUCCESS) { while ((ret = rsslDecodeFieldEntry(pIter, &fEntry)) != RSSL_RET_END_OF_CONTAINER) { if (ret != RSSL_RET_SUCCESS) return ret; /* get dictionary entry */ dictionaryEntry = getDictionaryEntry(pProviderThread->pDictionary, fEntry.fieldId); if (!dictionaryEntry) { printf("Error: Decoded field ID %d not present in dictionary.\n", fEntry.fieldId); return RSSL_RET_FAILURE; } /* decode and print out fid value */ dataType = dictionaryEntry->rwfType; switch (dataType) { case RSSL_DT_INT: if((ret = rsslDecodeInt(pIter, &primitive.intType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_UINT: if((ret = rsslDecodeUInt(pIter, &primitive.uintType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_FLOAT: if ((ret = rsslDecodeFloat(pIter, &primitive.floatType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DOUBLE: if ((ret = rsslDecodeDouble(pIter, &primitive.doubleType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_REAL: if ((ret = rsslDecodeReal(pIter, &primitive.realType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DATE: if ((ret = rsslDecodeDate(pIter, &primitive.dateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_TIME: if ((ret = rsslDecodeTime(pIter, &primitive.timeType)) < RSSL_RET_SUCCESS ) return ret; break; case RSSL_DT_DATETIME: if ((ret = rsslDecodeDateTime(pIter, &primitive.dateTimeType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_QOS: if ((ret = rsslDecodeQos(pIter, &primitive.qosType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_STATE: if ((ret = rsslDecodeState(pIter, &primitive.stateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_ENUM: { RsslEnumType *pEnumTypeInfo; if ((ret = rsslDecodeEnum(pIter, &primitive.enumType)) < RSSL_RET_SUCCESS ) return ret; if (ret == RSSL_RET_BLANK_DATA) break; pEnumTypeInfo = getFieldEntryEnumType(dictionaryEntry, primitive.enumType); if (pEnumTypeInfo) primitive.bufferType = pEnumTypeInfo->display; break; } case RSSL_DT_BUFFER: case RSSL_DT_ASCII_STRING: case RSSL_DT_UTF8_STRING: case RSSL_DT_RMTES_STRING: if ((ret = rsslDecodeBuffer(pIter, &primitive.bufferType)) < RSSL_RET_SUCCESS ) return ret; break; default: printf("Error: Unhandled data type %s(%u) in field with ID %u.\n", rsslDataTypeToString(dataType), dataType, fEntry.fieldId); return RSSL_RET_FAILURE; } } } else { return ret; } } } } else { return ret; } if(genMsgTimeTracker) updateLatencyStats(pProviderThread, genMsgTimeTracker); return RSSL_RET_SUCCESS; }
RsslRet decodeMPUpdate(RsslDecodeIterator *pIter, RsslMsg *msg, ConsumerThread* pConsumerThread) { RsslFieldList fList = RSSL_INIT_FIELD_LIST; RsslFieldEntry fEntry = RSSL_INIT_FIELD_ENTRY; RsslRet ret = 0; RsslDataType dataType; RsslPrimitive primitive; RsslDictionaryEntry* dictionaryEntry = NULL; RsslUInt timeTracker = 0; RsslUInt postTimeTracker = 0; RsslUInt genMsgTimeTracker = 0; /* decode field list */ if ((ret = rsslDecodeFieldList(pIter, &fList, 0)) == RSSL_RET_SUCCESS) { while ((ret = rsslDecodeFieldEntry(pIter, &fEntry)) != RSSL_RET_END_OF_CONTAINER) { if (ret != RSSL_RET_SUCCESS) return ret; /* get dictionary entry */ dictionaryEntry = getDictionaryEntry(pConsumerThread->pDictionary, fEntry.fieldId); if (!dictionaryEntry) { printf("Error: Decoded field ID %d not present in dictionary.\n", fEntry.fieldId); return RSSL_RET_FAILURE; } /* decode and print out fid value */ dataType = dictionaryEntry->rwfType; switch (dataType) { case RSSL_DT_INT: if((ret = rsslDecodeInt(pIter, &primitive.intType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_UINT: if((ret = rsslDecodeUInt(pIter, &primitive.uintType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_FLOAT: if ((ret = rsslDecodeFloat(pIter, &primitive.floatType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DOUBLE: if ((ret = rsslDecodeDouble(pIter, &primitive.doubleType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_REAL: if ((ret = rsslDecodeReal(pIter, &primitive.realType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DATE: if ((ret = rsslDecodeDate(pIter, &primitive.dateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_TIME: if ((ret = rsslDecodeTime(pIter, &primitive.timeType)) < RSSL_RET_SUCCESS ) return ret; break; case RSSL_DT_DATETIME: if ((ret = rsslDecodeDateTime(pIter, &primitive.dateTimeType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_QOS: if ((ret = rsslDecodeQos(pIter, &primitive.qosType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_STATE: if ((ret = rsslDecodeState(pIter, &primitive.stateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_ENUM: { RsslEnumType *pEnumTypeInfo; if ((ret = rsslDecodeEnum(pIter, &primitive.enumType)) < RSSL_RET_SUCCESS ) return ret; if (ret == RSSL_RET_BLANK_DATA) break; pEnumTypeInfo = getFieldEntryEnumType(dictionaryEntry, primitive.enumType); if (pEnumTypeInfo) primitive.bufferType = pEnumTypeInfo->display; break; } case RSSL_DT_BUFFER: case RSSL_DT_ASCII_STRING: case RSSL_DT_UTF8_STRING: case RSSL_DT_RMTES_STRING: if ((ret = rsslDecodeBuffer(pIter, &primitive.bufferType)) < RSSL_RET_SUCCESS ) return ret; break; default: printf("Error: Unhandled data type %s(%u) in field with ID %u.\n", rsslDataTypeToString(dataType), dataType, fEntry.fieldId); return RSSL_RET_FAILURE; } if (msg->msgBase.msgClass == RSSL_MC_UPDATE && ret != RSSL_RET_BLANK_DATA) { if(fEntry.fieldId == TIM_TRK_1_FID) timeTracker = primitive.uintType; if(fEntry.fieldId == TIM_TRK_2_FID) postTimeTracker = primitive.uintType; } else if (msg->msgBase.msgClass == RSSL_MC_GENERIC && ret != RSSL_RET_BLANK_DATA) { if(fEntry.fieldId == TIM_TRK_3_FID) genMsgTimeTracker = primitive.uintType; } } } else { return ret; } if (timeTracker) updateLatencyStats(pConsumerThread, timeTracker, RSSL_MC_UPDATE); if(postTimeTracker && checkPostUserInfo(msg)) updateLatencyStats(pConsumerThread, postTimeTracker, RSSL_MC_POST); if(genMsgTimeTracker) updateLatencyStats(pConsumerThread, genMsgTimeTracker, RSSL_MC_GENERIC); 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; }