示例#1
0
RsslRet UPAConsumer::ProcessOffStreamResponse(RsslMsg* msg, RsslDecodeIterator* dIter)
{
   // handle ACK / NAK for off-stream posts

   if (msg->msgBase.msgClass == RSSL_MC_ACK)
   {
      t42log_debug("Received AckMsg for stream #%d", msg->msgBase.streamId);

      // get key 
      RsslMsgKey *key = 0;
      key = (RsslMsgKey *)rsslGetMsgKey(msg);

      UPABridgePoster_ptr_t poster;
      PublisherPostMessageReply *reply = 0;

      RsslUInt32 id = msg->ackMsg.ackId;
      if (postManager_.RemovePost(id, poster, reply))
      {
         poster->ProcessAck(msg, dIter, reply);
      }
      else
      {
         t42log_warn("received response for off-stream post with unknown id %d", id); 
      }
   }
   return RSSL_RET_SUCCESS;
}
示例#2
0
RsslRet UPAProvider::ProcessSourceDirectoryRequest( RsslChannel* chnl, RsslMsg* msg, RsslDecodeIterator* dIter )
{

    // need to (a) check the filter flags - The rssl UPA provider sample does this. Not sure why its completely necessary - in any case we will send all the elements
    // (b) get the streamID - this get encodeded into the response
    // (c) add a map entry for each of the services - the upa sample only supports a single service but we potentially support many


    UPASourceDirectory srcDir;

    switch(msg->msgBase.msgClass)
    {
    case RSSL_MC_REQUEST:
        {
            RsslMsgKey* key = 0;
            key = (RsslMsgKey *)rsslGetMsgKey(msg);
            if (!((key->flags & RSSL_MKF_HAS_FILTER) && (key->filter & RDM_DIRECTORY_SERVICE_INFO_FILTER) 
                &&	(key->filter & RDM_DIRECTORY_SERVICE_STATE_FILTER) && (key->filter & RDM_DIRECTORY_SERVICE_GROUP_FILTER)))
            {
                if (srcDir.SendSrcDirectoryRequestReject(chnl, msg->msgBase.streamId, UPASourceDirectory::IncorrectFilterFlags) != RSSL_RET_SUCCESS)
                {
                        return RSSL_RET_FAILURE;
                }
                break;
            }

            RsslInt32 streamId = msg->requestMsg.msgBase.streamId;
            srcDir.SendSourceDirectoryResponse(chnl, streamId, key, owner_->GetSource());
        }
        break;

    case RSSL_MC_CLOSE:
        t42log_debug("Received Source Directory Close for StreamId %d\n", msg->msgBase.streamId);

        // dont actually need to do anything as we dont persist the info at the moment. If mama allowed us to report and publisjh source state then we would close the persistsed source data here

        break;

    default:
        t42log_warn("Received Unhandled Source Directory Msg Class: %d\n", msg->msgBase.msgClass);
        return RSSL_RET_FAILURE;

        break;

    }



    return RSSL_RET_SUCCESS;
}
static RsslRet processSymbolListResponse(SnapshotSession* pSession, RsslMsg* msg, RsslDecodeIterator* dIter)
{
	RsslRet ret = 0;

	RsslMsgKey* key = 0;
	RsslMap rsslMap;
	RsslMapEntry mapEntry;
	RsslVector rsslVector;
	RsslVectorEntry vectorEntry;
	char tempData[1024];
	char mapKeyData[32];
	RsslBuffer tempBuffer;
	RsslBuffer fidBufferValue;
	RsslLocalFieldSetDefDb fieldSetDefDb;
	RsslLocalElementSetDefDb elemSetDefDb;
	RsslElementList elemList;
	RsslElementEntry elemEntry;
	RsslFieldEntry fieldEntry;
	RsslFieldList fieldList;
	RsslBuffer stringBuf;
	char data[24];

	tempBuffer.data = tempData;
	tempBuffer.length = 1024;

	switch(msg->msgBase.msgClass)
	{
	case RSSL_MC_REFRESH:

		printf("\n<%s> Received symbol list refresh.\n\n", pSession->name);
	case RSSL_MC_UPDATE:

		/* decode symbol list response */
		/* get key*/
		key = (RsslMsgKey *)rsslGetMsgKey(msg);

		if(msg->msgBase.msgClass == RSSL_MC_REFRESH)
		{
			rsslStateToString(&tempBuffer, &msg->refreshMsg.state);
			printf("%.*s\n", tempBuffer.length, tempBuffer.data);
		}

		rsslClearMap(&rsslMap);

		if ((ret = rsslDecodeMap(dIter, &rsslMap)) != RSSL_RET_SUCCESS)
		{
			printf("<%s> rsslDecodeMap() failed with return code: %d\n", pSession->name, ret);
			return RSSL_RET_FAILURE;
		}

		if (rsslMap.flags & RSSL_MPF_HAS_SET_DEFS)
		{
			/* must ensure it is the correct type - if map contents are element list, this is a field set definition db */
			if (rsslMap.containerType == RSSL_DT_FIELD_LIST)
			{
				rsslClearLocalFieldSetDefDb(&fieldSetDefDb);
				if ((ret = rsslDecodeLocalFieldSetDefDb(dIter, &fieldSetDefDb)) < RSSL_RET_SUCCESS)
				{
					/* decoding failures tend to be unrecoverable */
					printf("<%s> Error %s (%d) encountered with rsslDecodeLocalElementSetDefDb().  Error Text: %s\n",
						pSession->name,
						rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret));
					return ret;
				}
			}
		}

		/* decode the map */
		while ((ret = rsslDecodeMapEntry(dIter, &mapEntry, mapKeyData)) != RSSL_RET_END_OF_CONTAINER)
		{
			if(ret != RSSL_RET_SUCCESS)
			{
				printf("<%s> rsslDecodeMapEntry() failed with return code: %d\n", pSession->name, ret);
				return RSSL_RET_FAILURE;
			}

			stringBuf.data = data;
			stringBuf.length = 24;
			rsslPrimitiveToString(&mapKeyData,rsslMap.keyPrimitiveType,&stringBuf);

			printf("\nID: %s, ", stringBuf.data);
			pSession->symbolListEntry[SymbolListCounter] = (SymbolListEntry*)malloc(sizeof(SymbolListEntry));
			pSession->symbolListEntry[SymbolListCounter]->id = atoi(stringBuf.data);

			if ((ret = rsslDecodeFieldList(dIter, &fieldList, &fieldSetDefDb)) != RSSL_RET_SUCCESS)
			{
				printf("<%s> rsslDecodeMap() failed with return code: %d\n", pSession->name, ret);
				return RSSL_RET_FAILURE;
			}


			/* The following fields are needed to uniquely identify a symbol on the realtime and gap fill streams:
			FID		Name						Type
			3422	Provider Symbol				RMTES_STRING
			8746	Provider Symbol 2			RMTES_STRING
			32639	Multicast channel(RT)		Vector of Element Lists
			32640	Multicast Channel(Gapfill)	Vector of Element Lists
			*/


			while ((ret = rsslDecodeFieldEntry(dIter, &fieldEntry)) != RSSL_RET_END_OF_CONTAINER)
			{
				if (ret != RSSL_RET_SUCCESS)
				{
					printf("<%s> rsslDecodeFieldEntry() failed with return code: %d\n", pSession->name, ret);
					return RSSL_RET_FAILURE;
				}

				if(fieldEntry.fieldId == 8746)
				{
					if ((ret = rsslDecodeBuffer(dIter, &fidBufferValue)) == RSSL_RET_SUCCESS)
					{
						//snprintf(&pSession->symbolListEntry[SymbolListCounter]->name[0], 128, "%.*s", fidBufferValue.length, fidBufferValue.data);
						printf("SYMBOL2: %s", fidBufferValue.data);
					}
					else if (ret != RSSL_RET_BLANK_DATA)
					{
						printf("<%s> Error: %s (%d) encountered with rsslDecodeBuffer(). Error Text: %s\n",
							pSession->name,
							rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret));
						return ret;
					}
				}
				else if (fieldEntry.fieldId == 3422)
				{
					if ((ret = rsslDecodeBuffer(dIter, &fidBufferValue)) == RSSL_RET_SUCCESS)
					{
						snprintf(&pSession->symbolListEntry[SymbolListCounter]->name[0], 128, "%.*s", fidBufferValue.length, fidBufferValue.data);
						printf("SYMBOL: %s", pSession->symbolListEntry[SymbolListCounter]->name);
					}
					else if (ret != RSSL_RET_BLANK_DATA)
					{
						printf("<%s> Error: %s (%d) encountered with rsslDecodeBuffer(). Error Text: %s\n",
							pSession->name,
							rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret));
						return ret;
					}
				}
				else if (fieldEntry.fieldId == 32639)
				{

					int countStreamingChan = 0;

					rsslClearVector(&rsslVector);
					if ((ret = rsslDecodeVector(dIter, &rsslVector)) != RSSL_RET_SUCCESS)
					{
						printf("<%s> rsslDecodeVector() failed with return code: %d\n", pSession->name, ret);
						return RSSL_RET_FAILURE;
					}

					if (rsslVector.flags & RSSL_VTF_HAS_SET_DEFS)
					{
						/* must ensure it is the correct type - if map contents are element list, this is a field set definition db */
						if (rsslVector.containerType == RSSL_DT_ELEMENT_LIST)
						{
							rsslClearLocalElementSetDefDb(&elemSetDefDb);
							if ((ret = rsslDecodeLocalElementSetDefDb(dIter, &elemSetDefDb)) < RSSL_RET_SUCCESS)
							{
								/* decoding failures tend to be unrecoverable */
								printf("<%s> Error %s (%d) encountered with rsslDecodeLocalElementSetDefDb().  Error Text: %s\n",
									pSession->name,
									rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret));
								return ret;
							}
						}
					}

					/* decode the vector */
					while ((ret = rsslDecodeVectorEntry(dIter, &vectorEntry)) != RSSL_RET_END_OF_CONTAINER)
					{
						if(ret != RSSL_RET_SUCCESS)
						{
							printf("<%s> rsslDecodeVectorEntry() failed with return code: %d\n", pSession->name, ret);
							return RSSL_RET_FAILURE;
						}

						rsslClearElementList(&elemList);
						if ((ret = rsslDecodeElementList(dIter, &elemList, &elemSetDefDb)) != RSSL_RET_SUCCESS)
						{
							printf("<%s> rsslDecodeElementList() failed with return code: %d\n", pSession->name, ret);
							return RSSL_RET_FAILURE;
						}

						while ((ret = rsslDecodeElementEntry(dIter, &elemEntry)) != RSSL_RET_END_OF_CONTAINER)
						{
							if (ret != RSSL_RET_SUCCESS)
							{
								printf("<%s> rsslDecodeElementEntry() failed with return code: %d\n", pSession->name, ret);
								return RSSL_RET_FAILURE;
							}

							if (rsslBufferIsEqual(&elemEntry.name, &RSSL_ENAME_CHANNEL_ID))
							{
								if ((ret = rsslDecodeUInt(dIter, &pSession->symbolListEntry[SymbolListCounter]->streamingChannels[countStreamingChan].channelId)) == RSSL_RET_SUCCESS)
								{	
									printf(" StreamingChanId: %d", pSession->symbolListEntry[SymbolListCounter]->streamingChannels[countStreamingChan].channelId);
								}
								else
								{
									printf("<%s> Error: %s (%d) encountered with rsslDecodeUInt(). Error Text: %s\n",
										pSession->name,
										rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret));
									return ret;
								}
							}
							else if (rsslBufferIsEqual(&elemEntry.name, &RSSL_ENAME_DOMAIN))
							{
								if ((ret = rsslDecodeUInt(dIter, &pSession->symbolListEntry[SymbolListCounter]->streamingChannels[countStreamingChan].domain)) == RSSL_RET_SUCCESS)
								{	
									printf(" StreamingChanDom: %d", pSession->symbolListEntry[SymbolListCounter]->streamingChannels[countStreamingChan].domain);
								}
								else
								{
									printf("<%s> Error: %s (%d) encountered with rsslDecodeUInt(). Error Text: %s\n",
										pSession->name,
										rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret));
									return ret;
								}
							}

						}
						countStreamingChan++;

					}
				}
				else if (fieldEntry.fieldId == 32640)
				{
					int countGapChan = 0;

					rsslClearVector(&rsslVector);
					if ((ret = rsslDecodeVector(dIter, &rsslVector)) != RSSL_RET_SUCCESS)
					{
						printf("<%s> rsslDecodeVector() failed with return code: %d\n", pSession->name, ret);
						return RSSL_RET_FAILURE;
					}

					if (rsslVector.flags & RSSL_VTF_HAS_SET_DEFS)
					{
						/* must ensure it is the correct type - if map contents are element list, this is a field set definition db */
						if (rsslVector.containerType == RSSL_DT_ELEMENT_LIST)
						{
							rsslClearLocalElementSetDefDb(&elemSetDefDb);
							if ((ret = rsslDecodeLocalElementSetDefDb(dIter, &elemSetDefDb)) < RSSL_RET_SUCCESS)
							{
								/* decoding failures tend to be unrecoverable */
								printf("<%s> Error %s (%d) encountered with rsslDecodeLocalElementSetDefDb().  Error Text: %s\n",
									pSession->name,
									rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret));
								return ret;
							}

						}
					}

					/* decode the vector */
					while ((ret = rsslDecodeVectorEntry(dIter, &vectorEntry)) != RSSL_RET_END_OF_CONTAINER)
					{
						if(ret != RSSL_RET_SUCCESS)
						{
							printf("<%s> rsslDecodeVectorEntry() failed with return code: %d\n", pSession->name, ret);
							return RSSL_RET_FAILURE;
						}

						rsslClearElementList(&elemList);
						if ((ret = rsslDecodeElementList(dIter, &elemList, &elemSetDefDb)) != RSSL_RET_SUCCESS)
						{
							printf("<%s> rsslDecodeElementList() failed with return code: %d\n", pSession->name, ret);
							return RSSL_RET_FAILURE;
						}

						while ((ret = rsslDecodeElementEntry(dIter, &elemEntry)) != RSSL_RET_END_OF_CONTAINER)
						{
							if (ret != RSSL_RET_SUCCESS)
							{
								printf("<%s> rsslDecodeElementEntry() failed with return code: %d\n", pSession->name, ret);
								return RSSL_RET_FAILURE;
							}
							if (rsslBufferIsEqual(&elemEntry.name, &RSSL_ENAME_CHANNEL_ID))
							{
								if ((ret = rsslDecodeUInt(dIter, &pSession->symbolListEntry[SymbolListCounter]->gapChannels[countGapChan].channelId)) == RSSL_RET_SUCCESS)
								{	
									printf(" GapChanId: %d", pSession->symbolListEntry[SymbolListCounter]->gapChannels[countGapChan].channelId);
								}
								else
								{
									printf("<%s> Error: %s (%d) encountered with rsslDecodeUInt(). Error Text: %s\n",
										pSession->name,
										rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret));
									return ret;
								}
							}
							else if (rsslBufferIsEqual(&elemEntry.name, &RSSL_ENAME_DOMAIN))
							{
								if ((ret = rsslDecodeUInt(dIter, &pSession->symbolListEntry[SymbolListCounter]->gapChannels[countGapChan].domain)) == RSSL_RET_SUCCESS)
								{	
									printf(" GapChanlDom: %d", pSession->symbolListEntry[SymbolListCounter]->gapChannels[countGapChan].domain);
								}
								else
								{
									printf("<%s> Error: %s (%d) encountered with rsslDecodeUInt(). Error Text: %s\n",
										pSession->name,
										rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret));
									return ret;
								}
							}
						}
					}
					countGapChan++;
				}
			}
			SymbolListCounter++;
		}



		break;

	case RSSL_MC_STATUS:
		printf("\n<%s> Received Item StatusMsg for stream %i \n", pSession->name, msg->statusMsg.msgBase.streamId);
		if (msg->statusMsg.flags & RSSL_STMF_HAS_STATE)
		{
			rsslStateToString(&tempBuffer, &msg->statusMsg.state);
			printf("        %.*s\n\n", tempBuffer.length, tempBuffer.data);
		}

		break;

	case RSSL_MC_ACK:
		/* although this application only posts on MP (Market Price), 
		* ACK handler is provided for other domains to allow user to extend 
		* and post on MBO (Market By Order), MBP (Market By Price), SymbolList, and Yield Curve domains */
		printf("\n<%s> Received AckMsg for stream %i \n", pSession->name, msg->msgBase.streamId);

		/* get key */
		key = (RsslMsgKey *)rsslGetMsgKey(msg);

		/* print out item name from key if it has it */
		if (key)
		{
			printf("%.*s\nDOMAIN: %s\n", key->name.length, key->name.data, rsslDomainTypeToString(msg->msgBase.domainType));
		}
		printf("\tackId=%u\n", msg->ackMsg.ackId);
		if (msg->ackMsg.flags & RSSL_AKMF_HAS_SEQ_NUM)
			printf("\tseqNum=%u\n", msg->ackMsg.seqNum);
		if (msg->ackMsg.flags & RSSL_AKMF_HAS_NAK_CODE)
			printf("\tnakCode=%u\n", msg->ackMsg.nakCode);
		if (msg->ackMsg.flags & RSSL_AKMF_HAS_TEXT)
			printf("\ttext=%.*s\n", msg->ackMsg.text.length, msg->ackMsg.text.data);

		break;

	default:
		printf("\n<%s> Recieved Unhandled Item Msg Class: %d\n", pSession->name, msg->msgBase.msgClass);
		break;
	}

	return RSSL_RET_SUCCESS;
}
示例#4
0
static RsslRet processItemRequest(ProviderThread *pProvThread, ProviderSession *pProvSession, RsslMsg* msg, RsslDecodeIterator* dIter)
{
	ItemInfo* itemInfo = NULL;
	RsslMsgKey* key = 0;
	RsslRet ret = RSSL_RET_SUCCESS;
	RsslItemAttributes attribs;
	RsslChannel *pChannel = pProvSession->pChannelInfo->pChannel;

	attribs.domainType = msg->msgBase.domainType;
	attribs.pMsgKey = &msg->msgBase.msgKey;


	switch(msg->msgBase.msgClass)
	{
	case RSSL_MC_REQUEST:
		countStatIncr(&pProvThread->itemRequestCount);

		/* get key */
		key = (RsslMsgKey *)rsslGetMsgKey(msg);

		/* check if item count reached */
		if ((pProvSession->openItemsCount >= directoryConfig.openLimit))
		{
			sendItemRequestReject(pProvThread, pProvSession, msg->msgBase.streamId, attribs.domainType, ITEM_COUNT_REACHED);
			break;
		}
		/* check if service id correct */
		if (key->serviceId != directoryConfig.serviceId)
		{
			sendItemRequestReject(pProvThread, pProvSession, msg->msgBase.streamId, attribs.domainType, INVALID_SERVICE_ID);
			break;
		}
		/* check if QoS supported */
		if (((RsslRequestMsg *)msg)->flags & RSSL_RQMF_HAS_WORST_QOS &&
			((RsslRequestMsg *)msg)->flags & RSSL_RQMF_HAS_QOS)
		{
			if (!rsslQosIsInRange(&((RsslRequestMsg *)msg)->qos, &((RsslRequestMsg *)msg)->worstQos, &directoryConfig.qos))
			{
				sendItemRequestReject(pProvThread, pProvSession, msg->msgBase.streamId, attribs.domainType, QOS_NOT_SUPPORTED);
				break;
			}
		}
		else if (((RsslRequestMsg *)msg)->flags & RSSL_RQMF_HAS_QOS)
		{
			if (!rsslQosIsEqual(&((RsslRequestMsg *)msg)->qos, &directoryConfig.qos))
			{
				sendItemRequestReject(pProvThread, pProvSession, msg->msgBase.streamId, attribs.domainType, QOS_NOT_SUPPORTED);
				break;
			}
		}

		/* check if item already opened with exact same key and domain.
		 * If we find one, check the StreamId.
		 * If the streamId matches, it is a reissue.
		 * If the streamId does not match, reject the redundant request. */
		itemInfo = findAlreadyOpenItem(pProvSession, msg, &attribs);
		if (itemInfo && itemInfo->StreamId != msg->msgBase.streamId)
		{
			sendItemRequestReject(pProvThread, pProvSession, msg->msgBase.streamId, attribs.domainType, ITEM_ALREADY_OPENED);
			break;
		}

		/* check if stream already in use with a different key */
		if (isStreamInUse(pProvSession, msg->msgBase.streamId, key))
		{
			sendItemRequestReject(pProvThread, pProvSession, msg->msgBase.streamId, attribs.domainType, STREAM_ALREADY_IN_USE);
			break;
		}

		if (!itemInfo)
		{
			RsslItemAttributes attributes;

			/* New request */
			/* get item info structure */
			attributes.pMsgKey = key;
			attributes.domainType = msg->msgBase.domainType;
			itemInfo = createItemInfo(pProvThread, pProvSession, &attributes, msg->msgBase.streamId);

			if (!itemInfo)
			{
				printf("Failed to get storage for item.\n");
				return RSSL_RET_FAILURE;
			}

			/* get StreamId */
			itemInfo->StreamId = msg->requestMsg.msgBase.streamId;

			hashTableInsertLink(&pProvSession->itemAttributesTable, &itemInfo->itemAttributesTableLink, &itemInfo->attributes);
			hashTableInsertLink(&pProvSession->itemStreamIdTable, &itemInfo->itemStreamIdTableLink, &itemInfo->StreamId);

			itemInfo->itemFlags |= ITEM_IS_SOLICITED;
		}
		else
		{
			/* else it was a reissue */
			if (!(msg->requestMsg.flags & RSSL_RQMF_NO_REFRESH))
			{
				/* Move item back to refresh queue. */
				if (itemInfo->myQueue)
				{
					rotatingQueueRemove(itemInfo->myQueue, &itemInfo->watchlistLink);
					itemInfo->myQueue = &pProvSession->refreshItemList;
					rotatingQueueInsert(&pProvSession->refreshItemList, &itemInfo->watchlistLink);
				}
			}


		}

		/* get IsStreamingRequest */
		if (msg->requestMsg.flags & RSSL_RQMF_STREAMING)
		{
			itemInfo->itemFlags |= ITEM_IS_STREAMING_REQ;
		}

		/* check if the request is for a private stream */
		if (msg->requestMsg.flags & RSSL_RQMF_PRIVATE_STREAM)
		{
			itemInfo->itemFlags |= ITEM_IS_PRIVATE;
		}

		break;

	case RSSL_MC_POST:
	{
		countStatIncr(&pProvThread->postMsgCount);
		return reflectPostMsg(pProvThread, dIter, pProvSession, &msg->postMsg);
	}

	case RSSL_MC_GENERIC:
	{
		countStatIncr(&pProvThread->stats.genMsgRecvCount);
		if (!pProvThread->stats.firstGenMsgRecvTime)
			pProvThread->stats.firstGenMsgRecvTime = getTimeNano();
		return processGenMsg(pProvThread, dIter, pProvSession, &msg->genericMsg);
	}

	case RSSL_MC_CLOSE:
		/* close item stream */
		countStatIncr(&pProvThread->closeMsgCount);
		closeItemStream(pProvThread, pProvSession, msg->msgBase.streamId);
		break;

	default:
		printf("\nReceived Unhandled Item Msg Class: %d\n", msg->msgBase.msgClass);
    	break;
	}

	return ret;
}
/*
 * Processes a market price response.
 */
RsslRet processMarketPriceResponse(RsslMsg* msg, RsslDecodeIterator* dIter)
{
	RsslMsgKey* key = 0;
	RsslFieldList fList = RSSL_INIT_FIELD_LIST;
	RsslFieldEntry fEntry = RSSL_INIT_FIELD_ENTRY;
	RsslRet ret = 0;
	char tempData[1024];
	RsslBuffer tempBuffer;
	RsslBool isBatchRequest = RSSL_FALSE;
	
	tempBuffer.data = tempData;
	tempBuffer.length = 1024;

	switch(msg->msgBase.msgClass)
	{
		case RSSL_MC_REFRESH:
			printf("Received RefreshMsg for stream %i\n", msg->refreshMsg.msgBase.streamId);

			if (msg->refreshMsg.flags & RSSL_RFMF_HAS_SEQ_NUM)
				printf("SEQ. NO.: %u\n", msg->refreshMsg.seqNum);

			/* process just like update */
		case RSSL_MC_UPDATE:
			/* decode market price response */
			
			/* get key */
			key = (RsslMsgKey *)rsslGetMsgKey(msg);

			/* print out item name from key if it has it */
			if (key)
			{
				printf("%.*s\n", key->name.length, key->name.data);
			}
			if (msg->msgBase.msgClass == RSSL_MC_UPDATE)
			{
				printf("Received UpdateMsg for stream %i\n", msg->updateMsg.msgBase.streamId);
				/* When displaying update information, we should also display the updateType information. */
				printf("UPDATE TYPE: %u\n", msg->updateMsg.updateType);	

				if (msg->updateMsg.flags & RSSL_UPMF_HAS_SEQ_NUM)
					printf("SEQ. NO.: %u\n", msg->updateMsg.seqNum);
			}
			printf("DOMAIN: %s\n", rsslDomainTypeToString(msg->msgBase.domainType));

			if (msg->msgBase.msgClass == RSSL_MC_REFRESH)
			{
				rsslStateToString(&tempBuffer, &msg->refreshMsg.state);
				printf("%.*s\n", tempBuffer.length, tempBuffer.data);
			}

			/* decode field list */
			if ((ret = rsslDecodeFieldList(dIter, &fList, 0)) == RSSL_RET_SUCCESS)
			{
				/* decode each field entry in list */
				while ((ret = rsslDecodeFieldEntry(dIter, &fEntry)) != RSSL_RET_END_OF_CONTAINER)
				{
					if (ret == RSSL_RET_SUCCESS)
					{
						if ((ret = decodeFieldEntry(&fEntry, dIter)) != RSSL_RET_SUCCESS)
						{
							return ret;
						}
					}
					else
					{
						printf("rsslDecodeFieldEntry() failed with return code: %d\n", ret);
						return RSSL_RET_FAILURE;
					}
				}
			}
			else
			{
				printf("rsslDecodeFieldList() failed with return code: %d\n", ret);
				return RSSL_RET_FAILURE;
			}
			break;
		case RSSL_MC_STATUS:
			if (msg->statusMsg.flags & RSSL_STMF_HAS_STATE)
    		{
				printf("Received StatusMsg for stream %i\n", msg->statusMsg.msgBase.streamId);
    			rsslStateToString(&tempBuffer, &msg->statusMsg.state);
				printf("	%.*s\n\n", tempBuffer.length, tempBuffer.data);
			}
			break;
		default:
			printf("\nReceived Unhandled Item Msg Class: %d\n", msg->msgBase.msgClass);
   			break;
	}

	return RSSL_RET_SUCCESS;
}
/*
 * Publically visable symbol list response handler 
 *
 * Processes a symbol list response.  This consists of extracting the
 * key, printing out the item name contained in the key, decoding the
 * map and map entries.
 * pReactor - RsslReactor associated with the application
 * pReactorChannel - The channel to get the symbol list response from
 * msg - The partially decoded message
 * dIter - The decode iterator
 */
RsslRet processSymbolListResponse(RsslReactor *pReactor, RsslReactorChannel *pReactorChannel, RsslMsgEvent* pMsgEvent, RsslMsg* msg, RsslDecodeIterator* dIter)
{
	RsslRet ret = 0;

	RsslMsgKey* key = 0;
	RsslMap rsslMap = RSSL_INIT_MAP;
	RsslMapEntry mapEntry = RSSL_INIT_MAP_ENTRY;
	RsslBuffer mapKey = RSSL_INIT_BUFFER;
	char tempData[1024];
	RsslBuffer tempBuffer;
	ChannelCommand *pCommand = (ChannelCommand*)pReactorChannel->userSpecPtr;
	ItemRequest *pRequest = &pCommand->symbolListRequest;

	tempBuffer.data = tempData;
	tempBuffer.length = 1024;

	switch(msg->msgBase.msgClass)
	{
		case RSSL_MC_REFRESH:
			/* update our item state list if its a refresh, then process just like update */

			pRequest->itemState.dataState = msg->refreshMsg.state.dataState;
			pRequest->itemState.streamState = msg->refreshMsg.state.streamState;

			/* refresh continued - process just like update */

		case RSSL_MC_UPDATE:
			/* decode symbol list response */
			/* get key*/
			key = (RsslMsgKey *)rsslGetMsgKey(msg);

			/* Print descriptor of the channel this message was received from. */
			printf("\n(Channel %d): ", pReactorChannel->socketId);

			/* print the name of the symbolist and the domain */
			printf("\n%.*s\nDOMAIN: %s\n", pRequest->itemName.length, pRequest->itemName.data, rsslDomainTypeToString(msg->msgBase.domainType));
	
			if (msg->msgBase.msgClass == RSSL_MC_UPDATE)
			{
				/* When displaying update information, we should also display the updateType information. */
				printf("UPDATE TYPE: %u\n", msg->updateMsg.updateType);	
			}

			if(msg->msgBase.msgClass == RSSL_MC_REFRESH)
			{
				rsslStateToString(&tempBuffer, &msg->refreshMsg.state);
				printf("%.*s\n", tempBuffer.length, tempBuffer.data);
			}

			if ((ret = rsslDecodeMap(dIter, &rsslMap)) == RSSL_RET_SUCCESS)
			{
				/* decode the map */
				while ((ret = rsslDecodeMapEntry(dIter, &mapEntry, &mapKey)) != RSSL_RET_END_OF_CONTAINER)
				{
					if(ret == RSSL_RET_SUCCESS)
					{
						/* print the name and action for this symbol list entry */
						printf("%.*s\t%s\n", mapEntry.encKey.length, mapEntry.encKey.data, mapEntryActionToString(mapEntry.action));
					}
					else
					{
						printf("rsslDecodeMapEntry() failed with return code: %d\n", ret);
						return RSSL_RET_FAILURE;
					}
				}
			}
			else
			{
				printf("rsslDecodeMap() failed with return code: %d\n", ret);
				return RSSL_RET_FAILURE;
			}

			break;

		case RSSL_MC_STATUS:
			printf("\nReceived Item StatusMsg for stream %i \n", msg->statusMsg.msgBase.streamId);
			if (msg->statusMsg.flags & RSSL_STMF_HAS_STATE)
			{
				rsslStateToString(&tempBuffer, &msg->statusMsg.state);
				printf("	%.*s\n\n", tempBuffer.length, tempBuffer.data);

				/* update our state table for posting */
				pRequest->itemState.dataState = msg->statusMsg.state.dataState;
				pRequest->itemState.streamState = msg->statusMsg.state.streamState;
			}

			break;

		case RSSL_MC_ACK:
			/* although this application only posts on MP (Market Price), 
			   ACK handler is provided for other domains to allow user to extend 
			   and post on MBO (Market By Order), MBP (Market By Price), SymbolList, and Yield Curve domains */
			printf("\nReceived AckMsg for stream %i \n", msg->msgBase.streamId);

			/* get key */
			key = (RsslMsgKey *)rsslGetMsgKey(msg);

			/* print out item name from key if it has it */
			if (key)
			{
				printf("%.*s\nDOMAIN: %s\n", key->name.length, key->name.data, rsslDomainTypeToString(msg->msgBase.domainType));
			}
			printf("\tackId=%u\n", msg->ackMsg.ackId);
			if (msg->ackMsg.flags & RSSL_AKMF_HAS_SEQ_NUM)
				printf("\tseqNum=%u\n", msg->ackMsg.seqNum);
			if (msg->ackMsg.flags & RSSL_AKMF_HAS_NAK_CODE)
				printf("\tnakCode=%u\n", msg->ackMsg.nakCode);
			if (msg->ackMsg.flags & RSSL_AKMF_HAS_TEXT)
				printf("\ttext=%.*s\n", msg->ackMsg.text.length, msg->ackMsg.text.data);

			break;

		default:
			printf("\nRecieved Unhandled Item Msg Class: %d\n", msg->msgBase.msgClass);
			break;
	}

	return RSSL_RET_SUCCESS;
}
/*
 * Publically visable market price response handler 
 *
 * Processes a market price response.  This consists of extracting the
 * key, printing out the item name contained in the key, decoding the
 * field list and field entry, and calling decodeFieldEntry() to decode
 * the field entry data.
 * msg - The partially decoded message
 * dIter - The decode iterator
 */
RsslRet processMarketPriceResponse(RsslChannel *chnl, RsslMsg* msg, RsslDecodeIterator* dIter)
{
	RsslMsgKey* key;
	RsslFieldList fList = RSSL_INIT_FIELD_LIST;
	RsslFieldEntry fEntry = RSSL_INIT_FIELD_ENTRY;
	RsslRet ret = 0;
	char tempData[1024];
	RsslBuffer tempBuffer;
	RsslBool isBatchRequest = RSSL_FALSE;
	RsslBool isPrivateStream = RSSL_FALSE;
	MarketPriceItemInfo *itemInfo = NULL;
	char postUserAddrString[16];

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

	key = (RsslMsgKey *)rsslGetMsgKey(msg);

	// determine which item in the info list we received a response for
	if (msg->msgBase.streamId == MARKETPRICE_BATCH_STREAM_ID_START ||
		msg->msgBase.streamId == MARKETPRICE_BATCH_PRIVATE_STREAM_ID_START)
	{
		isBatchRequest = RSSL_TRUE;	// we dont have info list entries for a status response to a batch request
	}
	else if (msg->msgBase.streamId >= MARKETPRICE_PRIVATE_STREAM_ID_START)
	{
		isPrivateStream = RSSL_TRUE;
		itemInfo = &marketPricePSItemInfoList[msg->msgBase.streamId - MARKETPRICE_PRIVATE_STREAM_ID_START];
	}
	else if (msg->msgBase.streamId >= MARKETPRICE_STREAM_ID_START)
	{
		itemInfo = &marketPriceItemInfoList[msg->msgBase.streamId - MARKETPRICE_STREAM_ID_START];
	}

	switch(msg->msgBase.msgClass)
	{
		case RSSL_MC_REFRESH:
			if (!(msg->refreshMsg.flags & RSSL_RFMF_PRIVATE_STREAM)) /* non-private stream */
			{
				/* check if this response should be on private stream but is not */
				/* if this is the case, close the stream */
				if (isPrivateStream)
				{
					printf("\nReceived non-private response for stream %i that should be private - closing stream\n", msg->msgBase.streamId);
					/* close stream */
					if (closeMPItemStream(chnl, itemInfo->streamId) != RSSL_RET_SUCCESS)
						return RSSL_RET_FAILURE;
					/* remove private stream entry from list */
					removeMarketPriceItemEntry(chnl, itemInfo->streamId, RSSL_TRUE);
					return RSSL_RET_SUCCESS;
				}
			}

			/* update our item state list if its a refresh, then process just like update */
			itemInfo->itemState.dataState = msg->refreshMsg.state.dataState;
			itemInfo->itemState.streamState = msg->refreshMsg.state.streamState;

			/* refresh continued - process just like update */

		case RSSL_MC_UPDATE:

			/* print out item name from key if it has it */
			if (key && (key->flags & RSSL_MKF_HAS_NAME))
				printf("\n%.*s", key->name.length, key->name.data);
			else
				printf("\n%s", itemInfo->itemname);

			if (isPrivateStream) printf(" (PRIVATE STREAM)");
			printf("\n");

			printf("DOMAIN: %s\n", rsslDomainTypeToString(msg->msgBase.domainType));

			if (msg->msgBase.msgClass == RSSL_MC_UPDATE)
			{
				/* When displaying update information, we should also display the updateType information. */
				printf("UPDATE TYPE: %u\n", msg->updateMsg.updateType);	

				/* The Visible Publisher Identity (VPI) can be found within the RsslPostUserInfo. 
				 * This will provide both the publisher ID and publisher address. Consumer can obtain the information from the msg - The partially decoded message.
				 */
				if (msg->updateMsg.flags & RSSL_UPMF_HAS_POST_USER_INFO)
				{
					rsslIPAddrUIntToString(msg->updateMsg.postUserInfo.postUserAddr, postUserAddrString);
					printf("Received UpdateMsg for stream %i ", itemInfo->streamId);
					printf("from publisher with user ID: \"%u\" at user address: \"%s\"\n", msg->updateMsg.postUserInfo.postUserId, postUserAddrString);
				}
			}
			else if (msg->msgBase.msgClass == RSSL_MC_REFRESH)
			{
				rsslStateToString(&tempBuffer, &msg->refreshMsg.state);
				printf("%.*s\n", tempBuffer.length, tempBuffer.data);

				/* The Visible Publisher Identity (VPI) can be found within the RsslPostUserInfo. 
				 * This will provide both the publisher ID and publisher address. Consumer can obtain the information from the msg - The partially decoded message.
				 */
				if (msg->refreshMsg.flags & RSSL_RFMF_HAS_POST_USER_INFO)
				{
					rsslIPAddrUIntToString(msg->refreshMsg.postUserInfo.postUserAddr, postUserAddrString);
					printf("\nReceived RefreshMsg for stream %i ", itemInfo->streamId);
					printf("from publisher with user ID: \"%u\" at user address: \"%s\"\n", msg->refreshMsg.postUserInfo.postUserId, postUserAddrString);
				}
			}


			/* decode market price response */
			/* decode field list */
			if ((ret = rsslDecodeFieldList(dIter, &fList, 0)) != RSSL_RET_SUCCESS)
			{
				printf("rsslDecodeFieldList() failed with return code: %d\n", ret);
				return RSSL_RET_FAILURE;
			}
			/* decode each field entry in list */
			while ((ret = rsslDecodeFieldEntry(dIter, &fEntry)) != RSSL_RET_END_OF_CONTAINER)
			{
				if (ret != RSSL_RET_SUCCESS)
				{
					printf("rsslDecodeFieldEntry() failed with return code: %d\n", ret);
					return RSSL_RET_FAILURE;
				}
				/* decode field entry info */
				if (decodeFieldEntry(&fEntry, dIter) != RSSL_RET_SUCCESS)
				{
					printf("\ndecodeFieldEntry() failed\n");
					return RSSL_RET_FAILURE;
				}
			}
			break;

		case RSSL_MC_STATUS:
			if (isBatchRequest)
				printf("\nReceived Batch StatusMsg for stream %i \n", msg->statusMsg.msgBase.streamId);
			else
				printf("\nReceived Item StatusMsg for stream %i \n", itemInfo->streamId);

			if (!(msg->statusMsg.flags & RSSL_STMF_PRIVATE_STREAM)) /* non-private stream */
			{
				/* check if this response should be on private stream but is not */
				/* if this is the case, close the stream */
				if (isPrivateStream)
				{
					printf("\nReceived non-private response for stream %i that should be private - closing stream\n", itemInfo->streamId);
					if (closeMPItemStream(chnl, itemInfo->streamId) != RSSL_RET_SUCCESS)
						return RSSL_RET_FAILURE;
					/* remove private stream entry from list */
					removeMarketPriceItemEntry(chnl, itemInfo->streamId, RSSL_TRUE);
					return RSSL_RET_SUCCESS;
				}
			}

			if (msg->statusMsg.flags & RSSL_STMF_HAS_STATE)
    		{
    			rsslStateToString(&tempBuffer, &msg->statusMsg.state);
				printf("	%.*s\n\n", tempBuffer.length, tempBuffer.data);

				if (itemInfo)
				{
					/* update our state table with the new state */
					itemInfo->itemState.dataState = msg->statusMsg.state.dataState;
					itemInfo->itemState.streamState = msg->statusMsg.state.streamState;
				}
				/* The Visible Publisher Identity (VPI) can be found within the RsslPostUserInfo. 
				 * This will provide both the publisher ID and publisher address. Consumer can obtain the information from the msg - The partially decoded message.
				 */
				if (msg->statusMsg.flags & RSSL_STMF_HAS_POST_USER_INFO)
				{
					rsslIPAddrUIntToString(msg->statusMsg.postUserInfo.postUserAddr, postUserAddrString);
					printf("Received StatusMsg for stream %i ", itemInfo->streamId);
					printf("from publisher with user ID: \"%u\" at user address: \"%s\"\n", msg->statusMsg.postUserInfo.postUserId, postUserAddrString);
				}

				/* redirect to private stream if indicated */
				if (msg->statusMsg.state.streamState == RSSL_STREAM_REDIRECTED &&
					(msg->statusMsg.flags & RSSL_STMF_PRIVATE_STREAM))
				{
    				if (redirectToMarketPricePrivateStream(chnl, itemInfo->streamId) != RSSL_RET_SUCCESS)
						return RSSL_RET_FAILURE;
				}
			}
			break;

		case RSSL_MC_ACK:
			printf("\nReceived AckMsg for stream %i \n", msg->msgBase.streamId);

			/* print out item name from key if it has it */
			/* if we sent an off stream post, we may not have created an itemInfo for it */
			if (key && (key->flags & RSSL_MKF_HAS_NAME))
				printf("\n%.*s", key->name.length, key->name.data);
			else if(itemInfo)	
				printf("\n%s", itemInfo->itemname);

			if (isPrivateStream) printf(" (PRIVATE STREAM)");
			printf("\n");

			printf("DOMAIN: %s\n", rsslDomainTypeToString(msg->msgBase.domainType));

			printf("\tackId=%u\n", msg->ackMsg.ackId);
			if (msg->ackMsg.flags & RSSL_AKMF_HAS_SEQ_NUM)
				printf("\tseqNum=%u\n", msg->ackMsg.seqNum);
			if (msg->ackMsg.flags & RSSL_AKMF_HAS_NAK_CODE)
				printf("\tnakCode=%u\n", msg->ackMsg.nakCode);
			if (msg->ackMsg.flags & RSSL_AKMF_HAS_TEXT)
				printf("\ttext=%.*s\n", msg->ackMsg.text.length, msg->ackMsg.text.data);

			break;

		default:
			printf("\nReceived Unhandled Item Msg Class: %d\n", msg->msgBase.msgClass);
   			break;
	}

	return RSSL_RET_SUCCESS;
}
示例#8
0
RsslRet UPAProvider::ProcessItemRequest(RsslChannel* chnl, RsslMsg* msg, RsslDecodeIterator* dIter)
{

    RsslMsgKey* key = 0;

    RsslUInt8 domainType = msg->msgBase.domainType;

    RsslInt32 streamId = msg->msgBase.streamId;

    switch(msg->msgBase.msgClass)
    {
    case RSSL_MC_REQUEST:
        // get key 
        {
            key = (RsslMsgKey *)rsslGetMsgKey(msg);

            bool isPrivateStream = (msg->requestMsg.flags & RSSL_RQMF_PRIVATE_STREAM) > 0 ? RSSL_TRUE : RSSL_FALSE;
            RMDSPublisherSource *source = owner_->GetSource();

            // insert the sourcename into the new item request as we cant get it from the servioce id
            if ( source == 0)
            {
                if (UPAPublisherItem::SendItemRequestReject(chnl, streamId, domainType, RSSL_SC_USAGE_ERROR, "Invalid service id",  isPrivateStream) != RSSL_RET_SUCCESS)
                    return RSSL_RET_FAILURE;
                break;
            }


            bool isNew;

            UPAPublisherItem_ptr_t newPubItem = source->AddItem(chnl, streamId, source->Name(), string(key->name.data, key->name.length), key->serviceId, owner_, isNew);

            // now need to add this item to our channel dictionary so we can find it again when we get a close
            ChannelDictionaryItem_t * dictItem = 0;
            ChannelDictionary_t::iterator it = channelDictionary_.find(chnl);
            if (it == channelDictionary_.end())
            {
                t42log_error("received item request for %s : %s on unknown channel (%d)\n", source->Name().c_str(), string(key->name.data, key->name.length).c_str(), chnl);
                break;
            }

            // so now we can insert the stream it in the dictionary item
            dictItem = it->second;
            dictItem->streamIdMap_[streamId] = newPubItem;

            // request a new item. Send a message to the client
            //
            // if its not a new item we want to request a recap, that will be send on the new channel / stream
            owner_->RequestItem(source->Name(), string(key->name.data, key->name.length), !isNew);
        } 
        break;



    case RSSL_MC_CLOSE:

        {
            t42log_debug("Received Item Close for StreamId %d\n", streamId);

            // find the item in the channel dictionary
            ChannelDictionary_t::iterator it = channelDictionary_.find(chnl);

            if (it == channelDictionary_.end())
            {
                t42log_error("received close item request for stream %d on unknown channel (%d)\n", streamId, chnl);
                break;
            }

            ChannelDictionaryItem_t * dictItem = it->second;

            // now look up the stream id
            ChannelStreamIdMap_t::iterator streamIt = dictItem->streamIdMap_.find(streamId);

            if (streamIt == dictItem->streamIdMap_.end())
            {
                t42log_warn("received item close for unknown stream id %d on channel %d \n", streamId, chnl);
                break;
            }

            UPAPublisherItem_ptr_t item = streamIt->second;
            dictItem->streamIdMap_.erase(streamIt);
            if (!item->RemoveChannel(chnl, streamId))
            {
                // this will send a message to the mama client to tell iut we dont want this any more
                owner_->CloseItem(item->Source(), item->Symbol());

            }

        }



        break;

    case RSSL_MC_POST:
        if (ProcessPost(chnl, msg, dIter) != RSSL_RET_SUCCESS)
            return RSSL_RET_FAILURE;
        break;

    default:
        printf("Received Unhandled Item Msg Class: %d\n", msg->msgBase.msgClass);
        break;
    }

    return RSSL_RET_SUCCESS;

}
示例#9
0
RsslRet UPAProvider::ProcessLoginRequest( RsslChannel* chnl, RsslMsg* msg, RsslDecodeIterator* dIter )
{

    RsslState *pState = 0;
    RsslMsgKey* key = 0;

    // shouldnt need to persist this
    login_.UPAChannel(chnl);
    UPALogin::RsslLoginRequestInfo loginRequestInfo;

    switch(msg->msgBase.msgClass)
    {
    case RSSL_MC_REQUEST:
         //get key 
        key = (RsslMsgKey *)rsslGetMsgKey(msg);

         //check if key has user name 
         //user name is only login user type accepted by this application (user name is the default type) 
        if (!(key->flags & RSSL_MKF_HAS_NAME) || ((key->flags & RSSL_MKF_HAS_NAME_TYPE) && (key->nameType != RDM_LOGIN_USER_NAME)))
        {
            login_.SendLoginRequestReject(chnl, msg->msgBase.streamId, UPALogin::NoUserName);
            break;
        }


        // decode the login request 
        if (login_.DecodeLoginRequest(&loginRequestInfo, msg, dIter, key) != RSSL_RET_SUCCESS)
        {
            t42log_warn("UPAProvider::ProcessLoginRequest - decodeLoginRequest() failed\n");
            return RSSL_RET_FAILURE;
        }


        // at this point we can do whatever cheking we want and reject the login

        t42log_info("Received Login Request for Username: %.*s\n", strlen(loginRequestInfo.Username), loginRequestInfo.Username);


        // in the reuters UPA sample they build the login response info from the requestInfo inside the send function
        // We want to allow a space to set values from config  so build the structure here
        UPALogin::RsslLoginResponseInfo loginRespInfo;
        memset((void*)&loginRespInfo, 0, sizeof(UPALogin::RsslLoginResponseInfo));

        loginRespInfo.StreamId = loginRequestInfo.StreamId;
         //Username 
        snprintf(loginRespInfo.Username, 128, "%s", loginRequestInfo.Username);
         //ApplicationId 
        snprintf(loginRespInfo.ApplicationId, 128, "%s", "255");
         //ApplicationName 
        snprintf(loginRespInfo.ApplicationName, 128, "%s", "Bridge");
         //Position 
        snprintf(loginRespInfo.Position, 128, "%s", loginRequestInfo.Position);

        loginRespInfo.SingleOpen = 0;				/* this provider does not support SingleOpen behavior */
        loginRespInfo.SupportBatchRequests = 0;		/* this provider supports batch requests */
        loginRespInfo.SupportOMMPost = acceptsPosts_ ? 1 : 0;

        // send login response 
        if (login_.SendLoginResponse(chnl, &loginRespInfo) != RSSL_RET_SUCCESS)
            return RSSL_RET_FAILURE;



        owner_->SentLoginResponse();


        break;

    case RSSL_MC_CLOSE:
        t42log_info("Received Login Close for StreamId %d\n", msg->msgBase.streamId);

        // dont actually need to do anything as we are not persisting login information

        break;

    default:
        t42log_warn("Received unhandled Login Msg Class: %d\n", msg->msgBase.msgClass);
        return RSSL_RET_FAILURE;

    }



    return RSSL_RET_SUCCESS;
}