static void setupXMLTracing(RsslChannel* pChannel, char* fileName)
{
	RsslError error;
	int debugFlags = 0x2C0;
	RsslTraceOptions traceOptions;

	rsslClearTraceOptions(&traceOptions);
	traceOptions.traceMsgFileName = fileName;
	traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_WRITE | RSSL_TRACE_READ;
	traceOptions.traceMsgMaxFileSize = 100000000;
	rsslIoctl(pChannel, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, &error);
}
/*
 * Connects to the RSSL server and returns the channel to the caller.
 * hostname - The hostname of the server to connect to
 * portno - The port number of the server to connect to
 * error - The error information in case of failure
 */
static RsslChannel* connectToRsslServer(RsslConnectionTypes connType, RsslError* error)
{
	RsslChannel* chnl;
	RsslConnectOptions copts = RSSL_INIT_CONNECT_OPTS;		

	printf("\nAttempting to connect to server %s:%s...\n", srvrHostname, srvrPortNo);
	copts.connectionInfo.unified.address = srvrHostname;
	copts.connectionInfo.unified.serviceName = srvrPortNo;
	copts.connectionInfo.unified.interfaceName = interfaceName;
	copts.proxyOpts.proxyHostName = proxyHostname;
	copts.proxyOpts.proxyPort = proxyPort;

	copts.guaranteedOutputBuffers = 500;
	copts.connectionType = connType;
	copts.majorVersion = RSSL_RWF_MAJOR_VERSION;
	copts.minorVersion = RSSL_RWF_MINOR_VERSION;
	copts.protocolType = RSSL_RWF_PROTOCOL_TYPE;

	rsslClearReadOutArgs(&readOutArgs);

	if ( (chnl = rsslConnect(&copts,error)) != 0)
	{
		FD_SET(chnl->socketId,&readfds);
		FD_SET(chnl->socketId,&exceptfds);
		if (xmlTrace) 
		{
			int debugFlags = 0x2C0;
			RsslTraceOptions traceOptions;

			rsslClearTraceOptions(&traceOptions);
			traceOptions.traceMsgFileName = traceOutputFile;
			traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_TO_MULTIPLE_FILES | RSSL_TRACE_TO_STDOUT | RSSL_TRACE_READ | RSSL_TRACE_WRITE;
			traceOptions.traceMsgMaxFileSize = 100000000;
			rsslIoctl(chnl, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, error);
		}

		printf("\nChannel IPC descriptor = "SOCKET_PRINT_TYPE"\n", chnl->socketId);
		if (!copts.blocking)
		{	
			if (!FD_ISSET(chnl->socketId,&wrtfds))
				FD_SET(chnl->socketId,&wrtfds);
		}
	}

	return chnl;
}
//END APIQA
int main(int argc, char **argv)
{
	struct timeval time_interval;
	RsslError error;
	fd_set useRead;
	fd_set useExcept;
	fd_set useWrt;
	int selRet;
	char errTxt[256];
	RsslBuffer errorText = {255, (char*)errTxt};
	RsslRet	retval = 0;
	RsslInProgInfo inProg = RSSL_INIT_IN_PROG_INFO;
	int i;
	RsslInitializeExOpts initOpts = RSSL_INIT_INITIALIZE_EX_OPTS;
	time_t currentTime;
#ifdef _WIN32
	int rcvBfrSize = 65535;
	int sendBfrSize = 65535;
#endif
	snprintf(srvrHostname, 128, "%s", defaultSrvrHostname);
	snprintf(srvrPortNo, 128, "%s", defaultSrvrPortNo);
	snprintf(serviceName, 128, "%s", defaultServiceName);
	snprintf(interfaceName, 128, "%s", defaultInterface);
	setUsername((char *)"");
	setAuthenticationToken((char *)"");
	setAuthenticationExtended((char *)"");
	setApplicationId((char *)"");
	snprintf(proxyHostname, 128, "%s", defaultProxyHost);
	snprintf(proxyPort, 128, "%s", defaultProxyPort);

    /* Check usage and retrieve operating parameters */
	if (argc == 1) /* use default operating parameters */
	{
		snprintf(itemName, 128, "%s", defaultItemName);
		/* add item name in market price handler */
		addMarketPriceItemName(itemName, RSSL_FALSE);
		mpItemReq = RSSL_TRUE;

		printf("\nUsing default operating parameters...\n\n");
		printf("srvrHostname: %s\n", srvrHostname);
		printf("srvrPortNo: %s\n", srvrPortNo);
		printf("serviceName: %s\n", serviceName);
		printf("itemName: %s\n", itemName);
		printf("connType: %d\n", connType);
	}
	else if (argc > 1) /* all operating parameters entered by user */
	{
		i = 1;

		while(i < argc)
		{
			if(strcmp("-libsslName", argv[i]) == 0)
			{
				i += 2;
				snprintf(libsslName, 128, "%s", argv[i-1]);
				initOpts.jitOpts.libsslName = libsslName;
			}
			//APIQA
			else if (strcmp("-reissueDir", argv[i]) == 0)
			{
				printf("Found -reissueDir ");

				_initialDirFilter = atoi(argv[++i]);

				printf("%d ", _initialDirFilter);

				_reissueDirFilter = atoi(argv[++i]);

				printf("%d\n", _reissueDirFilter);

				setDirectoryFilter(_initialDirFilter, _reissueDirFilter);

				break;
			}
			else if (strcmp("-reissueDict", argv[i]) == 0)
			{
				printf("Found -reissueDict ");

				_initialDictFilter = atoi(argv[++i]);

				printf("%d ", _initialDictFilter);

				_reissueDictFilter = atoi(argv[++i]);

				printf("%d\n", _reissueDictFilter);

				setDictionaryFilter(_initialDictFilter, _reissueDictFilter);

				break;
			}
			else if (strcmp("-xmlTrace", argv[i]) == 0)
			{
				xmlTrace = RSSL_TRUE;
				++i;
			}
			else if (strcmp("-loadDictFromFile", argv[i]) == 0)
			{
				_loadDictFromFile = RSSL_TRUE;
				++i;
			}
			else if (strcmp("-reissueQos", argv[i]) == 0)
			{
				_reissueQos = RSSL_TRUE;

				_qosRate = atoi(argv[++i]);

				_qosTimeliness = atoi(argv[++i]);

				printf("\nReissueQoS for rate = %d and timeline = %d\n", _qosRate, _qosTimeliness);

				setReissueQos(_qosRate, _qosTimeliness);

				break;
			}
			else if (strcmp("-reissueQosAndWorstQos", argv[i]) == 0)
			{
				_reissueQosAndWorstQos = RSSL_TRUE;

				_qosRate = atoi(argv[++i]);

				_qosTimeliness = atoi(argv[++i]);

				_worstQosRate = atoi(argv[++i]);

				_worstQosTimeliness = atoi(argv[++i]);

				printf("\nReissueQoS for rate = %d and timeline = %d\n", _qosRate, _qosTimeliness);
				printf("ReissueWorstQos QoS for worstRate = %d and worstTimeliness = %d\n", _worstQosRate, _worstQosTimeliness);

				setReissueQosAndWorstQos(_qosRate, _qosTimeliness, _worstQosRate, _worstQosTimeliness);

				break;
			}
			else if (strcmp("-sendGenericMsgOnLogin", argv[i]) == 0)
			{
				_sendGenMsgOnLogin = RSSL_TRUE;
				break;
			}
			else if (strcmp("-sendGenericMsgOnDirectory", argv[i]) == 0)
			{
				_sendGenMsgOnDirectory = RSSL_TRUE;
				break;
			}
			else if (strcmp("-requestDict", argv[i]) == 0)
			{
				_initialDictFilter = atoi(argv[++i]);
				break;
			}
			else if (strcmp("-requestDir", argv[i]) == 0)
			{
				_initialDirFilter = atoi(argv[++i]);
				break;
			}
			else if (strcmp("-reissueServiceId", argv[i]) == 0)
			{
				_changeServiceId = atoi(argv[++i]);

				printf("\nReissueServiceId to service ID = %d\n", _changeServiceId);

				setReissueChangeServiceName(_changeServiceId);
				break;
			}
			else if (strcmp("-privateStreamForItemReq", argv[i]) == 0)
			{
				setPriviateStream();
				++i;
			}
			else if (strcmp("-requestSameKeyWithDiffStreamId", argv[i]) == 0)
			{
				setReqSameKeyWithDiffStreamId();
				snprintf(itemName, 128, "%s", defaultItemName);
				addMarketPriceItemName(itemName, RSSL_FALSE);
				break;
			}
			else if (strcmp("-specificServiceId", argv[i]) == 0)
			{
				setSpecificServiceId(atoi(argv[++i]));
				++i;
			}
			else if (strcmp("-sendDirReqWithoutLogin", argv[i]) == 0)
			{
				_sendDirReqWithoutLogin = RSSL_TRUE;
				++i;
			}
			else if (strcmp("-sendDictReqWithoutLogin", argv[i]) == 0)
			{
				_sendDictReqWithoutLogin = RSSL_TRUE;
				++i;
			}
			else if (strcmp("-sendItemReqWithoutLogin", argv[i]) == 0)
			{
				_sendItemReqWithoutLogin = RSSL_TRUE;
				++i;
			}
			//END APIQA
			else if(strcmp("-libcryptoName", argv[i]) == 0)
			{
				i += 2;
				snprintf(libcryptoName, 128, "%s", argv[i-1]);
				initOpts.jitOpts.libcryptoName = libcryptoName;
			}
			else if(strcmp("-uname", argv[i]) == 0)
			{
				i += 2;
				setUsername(argv[i-1]);
			}
			else if(strcmp("-at", argv[i]) == 0)
			{
				i += 2;
				setAuthenticationToken(argv[i-1]);
			}
			else if(strcmp("-ax", argv[i]) == 0)
			{
				i += 2;
				setAuthenticationExtended(argv[i-1]);
			}
			else if(strcmp("-aid", argv[i]) == 0)
			{
				i += 2;
				setApplicationId(argv[i-1]);
			}
			else if(strcmp("-h", argv[i]) == 0)
			{
				i += 2;
				snprintf(srvrHostname, 128, "%s", argv[i-1]);
			}
			else if(strcmp("-p", argv[i]) == 0)
			{
				i += 2;
				snprintf(srvrPortNo, 128, "%s", argv[i-1]);
			}
			else if(strcmp("-ph", argv[i]) == 0)
			{
				i += 2;
				snprintf(proxyHostname, 128, "%s", argv[i-1]);
			}
			else if(strcmp("-pp", argv[i]) == 0)
			{
				i += 2;
				snprintf(proxyPort, 128, "%s", argv[i-1]);
			}
			else if(strcmp("-s", argv[i]) == 0)
			{
				i += 2;
				snprintf(serviceName, 128, "%s", argv[i-1]);
			}
			else if (strcmp("-c", argv[i]) == 0)
			{
				i += 1;				
				if (0 == strcmp(argv[i], "socket") || 0 == strcmp(argv[i], "0"))
					connType = RSSL_CONN_TYPE_SOCKET;
				else if (0 == strcmp(argv[i], "http") || 0 == strcmp(argv[i], "2"))
					connType = RSSL_CONN_TYPE_HTTP;
				else if (0 == strcmp(argv[i], "encrypted") || 0 == strcmp(argv[i], "1"))
					connType = RSSL_CONN_TYPE_ENCRYPTED;
				else if (0 == strcmp(argv[i], "reliableMCast") || 0 == strcmp(argv[i], "4"))
					connType = RSSL_CONN_TYPE_RELIABLE_MCAST;
				else 
				{
					connType = (RsslConnectionTypes)atoi(argv[i]);	
				}
				i += 1;
			}
			else if (strcmp("-yc", argv[i]) == 0)
			{
				i += 2;
				/* add item name in yield curve handler */
				addYieldCurveItemName(argv[i-1], RSSL_FALSE);
				ycItemReq = RSSL_TRUE;
			}
			else if(strcmp("-mp", argv[i]) == 0)
			{
				i += 2;
				/* add item name in market price handler */
				addMarketPriceItemName(argv[i-1], RSSL_FALSE);	
				mpItemReq = RSSL_TRUE;
				
			}
			else if(strcmp("-mbo", argv[i]) == 0)
			{
				i += 2;
				/* add item name in market by order handler */
				addMarketByOrderItemName(argv[i-1], RSSL_FALSE);
				mboItemReq = RSSL_TRUE;
			}
			else if(strcmp("-mbp", argv[i]) == 0)
			{
				i += 2;
				/* add item name in market by price handler */
				addMarketByPriceItemName(argv[i-1], RSSL_FALSE);	
				mbpItemReq = RSSL_TRUE;
			}
			else if(strcmp("-sl", argv[i]) == 0)
			{
				i++;
				slReq = RSSL_TRUE;
				/* check the rest of the command line arguments */
				if(i != argc)
				{
					/* check to see if next strings is the symbol list name */
					if(!(strncmp("-", argv[i], 1)))
					{
						/* user didn't specifiy name */
						setSymbolListInfo(RSSL_FALSE, slReq);
					}
					else
					{
						i++;
						setSymbolListName(argv[i-1]);
						setSymbolListInfo(RSSL_TRUE, slReq);
					}
				}
				else
				{
					/* no more command line arguments, so user didn't specifiy SL name */
					setSymbolListInfo(RSSL_FALSE, slReq);
				}
			}
			else if(strcmp("-view", argv[i]) == 0)
			{
				i++;
				setViewRequest();
			}
			else if (strcmp("-post", argv[i]) == 0)
			{
				i++;
				onPostEnabled = RSSL_TRUE;
				enableOnstreamPost();
			}
			else if (strcmp("-x", argv[i]) == 0)
			{
				i++;
				xmlTrace = RSSL_TRUE;
				snprintf(traceOutputFile, 128, "RsslConsumer\0");
			}
			else if (strcmp("-td", argv[i]) == 0)
			{
				i++;
				showTransportDetails = RSSL_TRUE;
			}
			else if (strcmp("-offpost", argv[i]) == 0)
			{
				i++;
				offPostEnabled = RSSL_TRUE;
			}
			else if(strcmp("-snapshot", argv[i]) == 0)
			{
				i++;
				setMPSnapshotRequest();
				setMBOSnapshotRequest();
				setMBPSnapshotRequest();
				setSLSnapshotRequest();
				setYCSnapshotRequest();
			}
			else if(strcmp("-mpps", argv[i]) == 0)
			{
				i += 2;
				/* add item name in market price handler */
				addMarketPriceItemName(argv[i-1], RSSL_TRUE);	
				mpItemReq = RSSL_TRUE;
				
			}
			else if(strcmp("-mbops", argv[i]) == 0)
			{
				i += 2;
				/* add item name in market by order handler */
				addMarketByOrderItemName(argv[i-1], RSSL_TRUE);
				mboItemReq = RSSL_TRUE;
			}
			else if(strcmp("-mbpps", argv[i]) == 0)
			{
				i += 2;
				/* add item name in market by price handler */
				addMarketByPriceItemName(argv[i-1], RSSL_TRUE);	
				mbpItemReq = RSSL_TRUE;
			}
			else if (strcmp("-ycps", argv[i]) == 0)
			{
				i += 2;
				/* add item name in yield curve handler */
				addYieldCurveItemName(argv[i-1], RSSL_TRUE);
				ycItemReq = RSSL_TRUE;
			}
			else if(strcmp("-runtime", argv[i]) == 0)
			{
				i += 2;
				timeToRun = atoi(argv[i-1]);
			}
			else
			{
				printf("Error: Unrecognized option: %s\n\n", argv[i]);
				printf("Usage: %s or\n%s [-uname <LoginUsername>] [-h <SrvrHostname>] [-p <SrvrPortNo>] [-c <ConnType>] [-s <ServiceName>] [-view] [-post] [-offpost] [-snapshot] [-sl [<SymbolList Name>]] [-mp|-mpps <MarketPrice ItemName>] [-mbo|-mbops <MarketByOrder ItemName>] [-mbp|-mbpps <MarketByPrice ItemName>] [-runtime <seconds>] [-td]\n", argv[0], argv[0]);
				printf("\n -mp or -mpps For each occurance, requests item using Market Price domain. (-mpps for private stream)\n");
				printf("\n -mbo or -mbops For each occurance, requests item using Market By Order domain. (-mbops for private stream)\n");
				printf("\n -mbp or -mbpps For each occurance, requests item using Market By Price domain. (-mbpps for private stream)\n");
				printf("\n -yc or -ycps For each occurance, requests item using Yield Curve domain. (-ycps for private stream)\n");
				printf("\n -view specifies each request using a basic dynamic view.\n");
				printf("\n -post specifies that the application should attempt to send post messages on the first requested Market Price item (i.e., on-stream)\n");
				printf("\n -offpost specifies that the application should attempt to send post messages on the login stream (i.e., off-stream)\n");
				printf("\n -snapshot specifies each request using non-streaming.\n");
				printf("\n -sl requests symbol list using Symbol List domain. (symbol list name optional)\n");
				printf("\n -td prints out additional transport details from rsslReadEx() and rsslWriteEx() function calls \n");
				printf("\n -x provides an XML trace of messages.\n");
				printf("\n -at Specifies the Authentication Token. If this is present, the login user name type will be RDM_LOGIN_USER_AUTHN_TOKEN.\n");
				printf("\n -ax Specifies the Authentication Extended information.\n");
				printf("\n -aid Specifies the Application ID.\n");
				printf("\n -runtime adjusts the time the application runs.\n");
				//APIQA
				printf("-sendGenericMsgOnLogin\n");
				printf("-sendGenericMsgOnDirectory\n");
				printf("-requestDict <verbosity>\n");
				printf("-requestDir <filters>\n");
				printf("-reissueServiceId <service ID>\n");
				printf("-reissueDir <initial filter> <reissue filter>\n");
				printf("-reissueDict <initial filter> <reissue filter>\n");
				printf("-reissueQos <rate> <timeliness>\n");
				printf("-reissueQosAndWorstQos <rate> <timeliness> <worstRate> <worstTimeliness>\n");

				printf("\nRate value definition\n\t- rate == 0 then RSSL_QOS_RATE_TICK_BY_TICK\n\t- rate == -1 then RSSL_QOS_RATE_JIT_CONFLATED\n\t- if 0 < rate <= 65535, RSSL_QOS_RATE_TIME_CONFLATED using the rate for rateInfo\n");
				printf("\nTimeliness value definition\n\t- timeliness == 0 then RSSL_QOS_TIME_REALTIME\n\t- timeliness == -1 then RSSL_QOS_TIME_DELAYED_UNKNOWN\n\t- if 0 < timeliness <= 65535, RSSL_QOS_TIME_DELAYED using the timelines for timeInfo");
				//END APIQA
#ifdef _WIN32
				/* WINDOWS: wait for user to enter something before exiting  */
				printf("\nPress Enter or Return key to exit application:");
				getchar();
#endif
				exit(RSSL_RET_FAILURE);

			}


		}
		//APIQA
		setDirectoryFilter(_initialDirFilter, _reissueDirFilter);
		setDictionaryFilter(_initialDictFilter, _reissueDictFilter);
		//END APIQA
		printf("Proxy host: %s\n", proxyHostname);
		printf("Proxy port: %s\n", proxyPort);
		
		printf("\nInput arguments...\n\n");
		printf("Using Connection Type = %d\n", connType);
		printf("srvrHostname: %s\n", srvrHostname);
		printf("srvrPortNo: %s\n", srvrPortNo);
			

		printf("serviceName: %s\n", serviceName);

		/* if no items were requested but a command line was specified, use the default item */
		if (!mpItemReq && !mboItemReq && !mbpItemReq && !slReq && !ycItemReq)
		{
			snprintf(itemName, 128, "%s", defaultItemName);
			/* add item name in market price handler */
			addMarketPriceItemName(itemName, RSSL_FALSE);
			mpItemReq = RSSL_TRUE;
		}

		/* this application requires at least one market price item to be requested
		   for on-stream posting to be performed */
		if (onPostEnabled && !mpItemReq)
		{
			printf("\nPosting will not be performed as no Market Price items were requested\n");
			onPostEnabled = RSSL_FALSE;
		}
	}

	/* set service name in directory handler */
	setServiceName(serviceName);

	/* load dictionary */
	//APIQA
	//loadDictionary();
	if (_loadDictFromFile)
	{
		loadDictionary();
	}
	//APIQA
	/* Initialize RSSL */
	/* RSSL_LOCK_NONE is used since this is a single threaded application. */
	if (rsslInitializeEx(&initOpts, &error) != RSSL_RET_SUCCESS)
	{
		printf("rsslInitialize(): failed <%s>\n", error.text);
		/* WINDOWS: wait for user to enter something before exiting  */
#ifdef _WIN32
		printf("\nPress Enter or Return key to exit application:");
		getchar();
#endif
		exit(RSSL_RET_FAILURE);
	}

	FD_ZERO(&readfds);
	FD_ZERO(&exceptfds);
	FD_ZERO(&wrtfds);

	/* Initialize run-time */
	initRuntime();

	/* this is the main loop */
	while(1)
	{
		/* this is the connection recovery loop */
		while(shouldRecoverConnection)
		{
			/* Connect to RSSL server */
			printf("\nAttempting to connect to server %s:%s...\n", srvrHostname, srvrPortNo);
			if ((rsslConsumerChannel = connectToRsslServer(connType, &error)) == NULL)
			{
				printf("Unable to connect to RSSL server: <%s>\n",error.text);
			}
			else
			{
				FD_SET(rsslConsumerChannel->socketId, &readfds);
				FD_SET(rsslConsumerChannel->socketId, &wrtfds);
				FD_SET(rsslConsumerChannel->socketId, &exceptfds);
			}

			if (rsslConsumerChannel != NULL && rsslConsumerChannel->state == RSSL_CH_STATE_ACTIVE)
				shouldRecoverConnection = RSSL_FALSE;

			/* Wait for channel to become active.  This finalizes the three-way handshake. */
			while (rsslConsumerChannel != NULL && rsslConsumerChannel->state != RSSL_CH_STATE_ACTIVE)
			{
				useRead = readfds;
				useWrt = wrtfds;
				useExcept = exceptfds;

				/* Set a timeout value if the provider accepts the connection, but does not initialize it */
				time_interval.tv_sec = 60;
				time_interval.tv_usec = 0;

				selRet = select(FD_SETSIZE, &useRead, &useWrt, &useExcept, &time_interval);

				/* select has timed out, close the channel and attempt to reconnect */
				if(selRet == 0)
				{
					printf("\nChannel initialization has timed out, attempting to reconnect...\n");

					FD_CLR(rsslConsumerChannel->socketId, &readfds);
					FD_CLR(rsslConsumerChannel->socketId, &exceptfds);
					if (FD_ISSET(rsslConsumerChannel->socketId, &wrtfds))
						FD_CLR(rsslConsumerChannel->socketId, &wrtfds);
					
					recoverConnection();
				}
				else
				/* Received a response from the provider. */
				if(selRet > 0 && (FD_ISSET(rsslConsumerChannel->socketId, &useRead) || FD_ISSET(rsslConsumerChannel->socketId, &useWrt) || FD_ISSET(rsslConsumerChannel->socketId, &useExcept)))
				{
					if (rsslConsumerChannel->state == RSSL_CH_STATE_INITIALIZING)
					{
						FD_CLR(rsslConsumerChannel->socketId,&wrtfds);
						if ((retval = rsslInitChannel(rsslConsumerChannel, &inProg, &error)) < RSSL_RET_SUCCESS)
						{
							printf("\nchannelInactive fd="SOCKET_PRINT_TYPE" <%s>\n",	
								rsslConsumerChannel->socketId,error.text);
							recoverConnection();
							break; 
						}
						else 
						{
			  				switch (retval)
							{
							case RSSL_RET_CHAN_INIT_IN_PROGRESS:
								if (inProg.flags & RSSL_IP_FD_CHANGE)
								{
									printf("\nChannel In Progress - New FD: "SOCKET_PRINT_TYPE"  Old FD: "SOCKET_PRINT_TYPE"\n",rsslConsumerChannel->socketId, inProg.oldSocket );	

									FD_CLR(inProg.oldSocket,&readfds);
									FD_CLR(inProg.oldSocket,&exceptfds);
									FD_SET(rsslConsumerChannel->socketId,&readfds);
									FD_SET(rsslConsumerChannel->socketId,&exceptfds);
									FD_SET(rsslConsumerChannel->socketId,&wrtfds);
								}
								else
								{
									printf("\nChannel "SOCKET_PRINT_TYPE" In Progress...\n", rsslConsumerChannel->socketId);	
									//Sleep(1000);
								}
								break;
							case RSSL_RET_SUCCESS:
								{
									RsslChannelInfo chanInfo;
									
									printf("\nChannel "SOCKET_PRINT_TYPE" Is Active\n" ,rsslConsumerChannel->socketId);	
									/* reset should recover connection flag */
									shouldRecoverConnection = RSSL_FALSE;
									/* if device we connect to supports connected component versioning, 
									 * also display the product version of what this connection is to */
									if ((retval = rsslGetChannelInfo(rsslConsumerChannel, &chanInfo, &error)) >= RSSL_RET_SUCCESS)
									{
										RsslUInt32 i;
										for (i = 0; i < chanInfo.componentInfoCount; i++)
										{
											printf("Connected to %s device.\n", chanInfo.componentInfo[i]->componentVersion.data);
										}
									}
										
								}
								break;
							default:
									printf("\nBad return value fd="SOCKET_PRINT_TYPE" <%s>\n",	
									   rsslConsumerChannel->socketId,error.text);
								cleanUpAndExit();
								break;
							}
						}
					}
				}
				else
				if(selRet < 0)
				{
					printf("\nSelect error.\n");
					cleanUpAndExit();
				}

				handleRuntime();
			}

			/* sleep before trying again */
			if (shouldRecoverConnection)
			{
				for(i = 0; i < CONSUMER_CONNECTION_RETRY_TIME; ++i)
				{
#ifdef _WIN32
					Sleep(1000);
#else
					sleep(1);
#endif
					handleRuntime();

				}
			}

		}

		/* WINDOWS: change size of send/receive buffer since it's small by default */
#ifdef _WIN32
		if (rsslIoctl(rsslConsumerChannel, RSSL_SYSTEM_WRITE_BUFFERS, &sendBfrSize, &error) != RSSL_RET_SUCCESS)
		{
			printf("rsslIoctl(): failed <%s>\n", error.text);
		}
		if (rsslIoctl(rsslConsumerChannel, RSSL_SYSTEM_READ_BUFFERS, &rcvBfrSize, &error) != RSSL_RET_SUCCESS)
		{
			printf("rsslIoctl(): failed <%s>\n", error.text);
		}
#endif

		/* Initialize ping handler */
		initPingHandler(rsslConsumerChannel);

		/* Send login request message */
		isLoginReissue = RSSL_FALSE;
		//APIQA
		/*if (sendLoginRequest(rsslConsumerChannel, "rsslConsumer", RSSL_CONSUMER, &loginSuccessCallBack) != RSSL_RET_SUCCESS)
		{
			cleanUpAndExit();
		}*/
		if (!_sendDirReqWithoutLogin && !_sendDictReqWithoutLogin && !_sendItemReqWithoutLogin)
		{
			if (sendLoginRequest(rsslConsumerChannel, "rsslConsumer", RSSL_CONSUMER, &loginSuccessCallBack) != RSSL_RET_SUCCESS)
			{
				cleanUpAndExit();
			}
                }
		else
		{
                               
				        printf("FALSE\n");
				if (_sendDirReqWithoutLogin)
				{
					sendSourceDirectoryRequest(rsslConsumerChannel, _sendGenMsgOnDirectory);
				}
				else if (_sendDictReqWithoutLogin)
				{
					sendDictionaryRequest(rsslConsumerChannel, "RWFFld", FIELD_DICTIONARY_STREAM_ID, _initialDictFilter);

					sendDictionaryRequest(rsslConsumerChannel, "RWFEnum", ENUM_TYPE_DICTIONARY_STREAM_ID, _initialDictFilter);
				}
				else if (_sendItemReqWithoutLogin)
				{
				        printf("Sending MP REQUEST\n");
					sendMarketPriceItemRequests(rsslConsumerChannel);
				}
		}
		//END APIQA
	
		/* this is the message processing loop */
		while(1)
		{
			useRead = readfds;
			useExcept = exceptfds;
			useWrt = wrtfds;
			time_interval.tv_sec = 1;
			time_interval.tv_usec = 0;

			/* Call select() to check for any messages */
			selRet = select(FD_SETSIZE,&useRead,
				&useWrt,&useExcept,&time_interval);

			if (selRet < 0) /* no messages received, continue */
			{
#ifdef _WIN32
				if (WSAGetLastError() == WSAEINTR)
					continue;
#else
				if (errno == EINTR)
				{
					continue;
				}
#endif
			}
			else if (selRet > 0) /* messages received, read from channel */
			{
				if ((rsslConsumerChannel != NULL) && (rsslConsumerChannel->socketId != -1))
				{
					if ((FD_ISSET(rsslConsumerChannel->socketId, &useRead)) ||
						(FD_ISSET(rsslConsumerChannel->socketId, &useExcept)))
					{
						if (readFromChannel(rsslConsumerChannel) != RSSL_RET_SUCCESS)
							recoverConnection();
					}

					/* flush for write file descriptor and active state */
					if (rsslConsumerChannel != NULL &&
						FD_ISSET(rsslConsumerChannel->socketId, &useWrt) &&
						rsslConsumerChannel->state == RSSL_CH_STATE_ACTIVE)
					{
						if ((retval = rsslFlush(rsslConsumerChannel, &error)) < RSSL_RET_SUCCESS)
						{
							printf("rsslFlush() failed with return code %d - <%s>\n", retval, error.text);
						}
						else if (retval == RSSL_RET_SUCCESS)
						{
							/* clear write fd */
							FD_CLR(rsslConsumerChannel->socketId, &wrtfds);
						}
					}
				}
			}

			/* break out of message processing loop if should recover connection */
			if (shouldRecoverConnection == RSSL_TRUE)
			{
				printf("Recovering connection in 5 seconds\n");
				connectionRecovery = RSSL_TRUE;
				#ifdef _WIN32
					Sleep(5000);
#else
					sleep(5);
#endif
				break;
			}

			/* Handle pings */
			handlePings(rsslConsumerChannel);

			/* Handle run-time */
			handleRuntime();

			if (onPostEnabled || offPostEnabled)
			{
				/* if configured to post, send post messages if its time */
				/* Handle Post */
				if (handlePosts(rsslConsumerChannel, connectionRecovery) != RSSL_RET_SUCCESS)
					recoverConnection();
				connectionRecovery = RSSL_FALSE;
			}

			if ((currentTime = time(NULL)) < 0)
			{
				printf("time() failed.\n");
			}

			// send login reissue if login reissue time has passed
			if (canSendLoginReissue == RSSL_TRUE &&
				currentTime >= (RsslInt)loginReissueTime)
			{
				isLoginReissue = RSSL_TRUE;
				if (sendLoginRequest(rsslConsumerChannel, "rsslConsumer", RSSL_CONSUMER, &loginSuccessCallBack) != RSSL_RET_SUCCESS)
				{
					printf("Login reissue failed\n");
				}
				else
				{
					printf("Login reissue sent\n");
				}
				canSendLoginReissue = RSSL_FALSE;
			}
		}
	}
}
Beispiel #4
0
void UPAConsumer::Run()
{
   RsslError error;
   struct timeval time_interval;
   RsslRet	retval = 0;

   fd_set useRead;
   fd_set useExcept;
   fd_set useWrt;

   // get hold of the statistics logger
   statsLogger_ = StatisticsLogger::GetStatisticsLogger();

   // todo might want to make these configurable
#ifdef _WIN32
   int rcvBfrSize = 65535;
   int sendBfrSize = 65535;
#endif

   int selRet;

   FD_ZERO(&readfds_);
   FD_ZERO(&exceptfds_);
   FD_ZERO(&wrtfds_);

   // The outer thread loop attempts to make / remake a connection to the rssl server
   //
   // Inner loop dispatches requests from the mama queue and reads the socket for incoming responses
   while (runThread_)
   {
      // attempt to make connection
      while(shouldRecoverConnection_ && runThread_)
      {
         login_->UPAChannel(0);
         sourceDirectory_->UPAChannel(0);
         upaDictionary_->UPAChannel(0);
         // connect to server
         t42log_info("Attempting to connect to server %s:%s...\n", connectionConfig_.Host().c_str(), connectionConfig_.Port().c_str());

         if ((rsslConsumerChannel_ = ConnectToRsslServer(connectionConfig_.Host(), connectionConfig_.Port(), interfaceName_, connType_, &error)) == NULL)
         {
            t42log_error("Unable to connect to RSSL server: <%s>\n",error.text);
         }
         else
         {
            if (rsslConsumerChannel_)
            {
               // connected - set up socket fds
               RsslSocket s = rsslConsumerChannel_->socketId;
               FD_SET(rsslConsumerChannel_->socketId, &readfds_);
               FD_SET(rsslConsumerChannel_->socketId, &wrtfds_);
               FD_SET(rsslConsumerChannel_->socketId, &exceptfds_);
            }
         }

         if (rsslConsumerChannel_ != NULL && rsslConsumerChannel_->state == RSSL_CH_STATE_ACTIVE)
            shouldRecoverConnection_ = RSSL_FALSE;

         //Wait for channel to become active. 
         while (rsslConsumerChannel_ != NULL && rsslConsumerChannel_->state != RSSL_CH_STATE_ACTIVE && runThread_)
         {
            useRead = readfds_;
            useWrt = wrtfds_;
            useExcept = exceptfds_;

            /* Set a timeout value if the provider accepts the connection, but does not initialize it */
            time_interval.tv_sec = 60;
            time_interval.tv_usec = 0;

            selRet = select(FD_SETSIZE, &useRead, &useWrt, &useExcept, &time_interval);

            // select has timed out, close the channel and attempt to reconnect 
            if (selRet == 0)
            {
               t42log_warn("Channel initialization has timed out, attempting to reconnect...\n");

               if (rsslConsumerChannel_)
               {
                  FD_CLR(rsslConsumerChannel_->socketId, &readfds_);
                  FD_CLR(rsslConsumerChannel_->socketId, &exceptfds_);
                  if (FD_ISSET(rsslConsumerChannel_->socketId, &wrtfds_))
                     FD_CLR(rsslConsumerChannel_->socketId, &wrtfds_);
               }
               RecoverConnection();
            }
            else
               // Received a response from the provider. 
               if (rsslConsumerChannel_ && selRet > 0 && (FD_ISSET(rsslConsumerChannel_->socketId, &useRead) || FD_ISSET(rsslConsumerChannel_->socketId, &useWrt) || FD_ISSET(rsslConsumerChannel_->socketId, &useExcept)))
               {
                  if (rsslConsumerChannel_->state == RSSL_CH_STATE_INITIALIZING)
                  {
                     RsslInProgInfo inProg = RSSL_INIT_IN_PROG_INFO;
                     FD_CLR(rsslConsumerChannel_->socketId,&wrtfds_);
                     if ((retval = rsslInitChannel(rsslConsumerChannel_, &inProg, &error)) < RSSL_RET_SUCCESS)
                     {
                        // channel init failed, try again
                        t42log_warn("channelInactive fd=%d <%s>\n",
                           rsslConsumerChannel_->socketId,error.text);
                        RecoverConnection();
                        break; 
                     }
                     else 
                     {
                        switch ((int)retval)
                        {
                        case RSSL_RET_CHAN_INIT_IN_PROGRESS:
                           if (inProg.flags & RSSL_IP_FD_CHANGE)
                           {
                              t42log_info("Channel In Progress - New FD: %d  Old FD: %d\n",rsslConsumerChannel_->socketId, inProg.oldSocket );

                              FD_CLR(inProg.oldSocket,&readfds_);
                              FD_CLR(inProg.oldSocket,&exceptfds_);
                              FD_SET(rsslConsumerChannel_->socketId,&readfds_);
                              FD_SET(rsslConsumerChannel_->socketId,&exceptfds_);
                              FD_SET(rsslConsumerChannel_->socketId,&wrtfds_);
                           }
                           else
                           {
                              t42log_info("Channel %d In Progress...\n", rsslConsumerChannel_->socketId);
                           }
                           break;
                        case RSSL_RET_SUCCESS:
                           {
                              // connected
                              t42log_info("Channel %d Is Active\n" ,rsslConsumerChannel_->socketId);
                              shouldRecoverConnection_ = RSSL_FALSE;
                              RsslChannelInfo chanInfo;

                              // log channel info
                              if ((retval = rsslGetChannelInfo(rsslConsumerChannel_, &chanInfo, &error)) >= RSSL_RET_SUCCESS)
                              {
                                 RsslUInt32 i;
                                 for (i = 0; i < chanInfo.componentInfoCount; i++)
                                 {
                                    t42log_info("Connected to %s device.\n", chanInfo.componentInfo[i]->componentVersion.data);
                                 }
                              }


                              login_->UPAChannel(rsslConsumerChannel_);
                              sourceDirectory_->UPAChannel(rsslConsumerChannel_);
                              upaDictionary_->UPAChannel(rsslConsumerChannel_);
                              mama_log (MAMA_LOG_LEVEL_FINEST, "Provider returned \"Connection Successful\"");
                              NotifyListeners(true, "Provider returned \"Connection Successful\"");

                           }
                           break;
                        default:
                           {
                              // Connection has failed
                              char buff[256]={0};
                              memset(buff,0,sizeof(buff));
                              sprintf(buff, "Bad return value on connection  fd=%d <%s>\n", rsslConsumerChannel_->socketId,error.text);
                              t42log_error("%s\n", buff);
                              NotifyListeners(false, buff);
                              runThread_ = false;
                           }
                           break;
                        }
                     }
                  }
               }
               else
                  if (selRet < 0)
                  {
                     t42log_error("Select error.\n");
                     runThread_ = false;
                     break;
                  }

         }

         // wait a while before retry
         if (shouldRecoverConnection_)
         {
            LogReconnection();
            WaitReconnectionDelay();

         }
      }

      //  WINDOWS: change size of send/receive buffer since it's small by default 
#ifdef _WIN32
      if (rsslConsumerChannel_ && rsslIoctl(rsslConsumerChannel_, RSSL_SYSTEM_WRITE_BUFFERS, &sendBfrSize, &error) != RSSL_RET_SUCCESS)
      {
         t42log_error("rsslIoctl(): failed <%s>\n", error.text);
      }
      if (rsslConsumerChannel_ && rsslIoctl(rsslConsumerChannel_, RSSL_SYSTEM_READ_BUFFERS, &rcvBfrSize, &error) != RSSL_RET_SUCCESS)
      {
         t42log_error("rsslIoctl(): failed <%s>\n", error.text);
      }
#endif

      /* Initialize ping handler */
      if (rsslConsumerChannel_) 
         InitPingHandler(rsslConsumerChannel_);

      int64_t queueCount = 0;
      /* this is the message processing loop */
      while (runThread_)
      {

         // first dispatch some events off the event queue
         if (!PumpQueueEvents())
         {
            break;
         }

		 if ((rsslConsumerChannel_ != NULL) && (rsslConsumerChannel_->socketId != -1))
		 {
			 // if we have a connection
			 useRead = readfds_;
			 useExcept = exceptfds_;
			 useWrt = wrtfds_;
			 time_interval.tv_sec = 0;
			 time_interval.tv_usec = 100000;

			 // look at the socket state

			 selRet = select(FD_SETSIZE, &useRead, &useWrt, &useExcept, &time_interval);
		 }
		 else
		 {
			 // no connection, just sleep for 1s

#ifdef _WIN32
			 Sleep(1000);
#else
			 sleep(1);
#endif
			 continue;
		 }


         if (!runThread_)
         {
			 // thread is stopped
            break;
         }

         if (selRet < 0) // no messages received, continue 
         {
#ifdef _WIN32
            if (WSAGetLastError() == WSAEINTR)
               continue;
#else
            if (errno == EINTR)
            {
               continue;
            }
#endif
         }
         else if (selRet > 0) // messages received
         {
            if ((rsslConsumerChannel_ != NULL) && (rsslConsumerChannel_->socketId != -1))
            {
               if ((FD_ISSET(rsslConsumerChannel_->socketId, &useRead)) ||
                  (FD_ISSET(rsslConsumerChannel_->socketId, &useExcept)))
               {
				   // This will empty the read buffer and dispatch incoming events
                  if (ReadFromChannel(rsslConsumerChannel_) != RSSL_RET_SUCCESS)
                  {
                     // the read failed so attempt to recover if required
					 if(RSSL_TRUE == shouldRecoverConnection_)
					 {
						RecoverConnection();
					 }
					 else
					 {
						 // otherwise just run out of the thread
						 runThread_ = false;
					 }
                  }
               }

               // If there's anything to be written flush the write socket
               if (rsslConsumerChannel_ != NULL &&
                  FD_ISSET(rsslConsumerChannel_->socketId, &useWrt) &&
                  rsslConsumerChannel_->state == RSSL_CH_STATE_ACTIVE)
               {
                  if ((retval = rsslFlush(rsslConsumerChannel_, &error)) < RSSL_RET_SUCCESS)
                  {
                     t42log_error("rsslFlush() failed with return code %d - <%s>\n", retval, error.text);
                  }
                  else if (retval == RSSL_RET_SUCCESS)
                  {
                     // and clear the fd
                     FD_CLR(rsslConsumerChannel_->socketId, &wrtfds_);
                  }
               }
            }
         }

         // break out of message processing loop if should recover connection 
         if (shouldRecoverConnection_ == RSSL_TRUE)
         {
            LogReconnection();
            WaitReconnectionDelay();
            break;
         }

         // check if its time to process pings
         if (rsslConsumerChannel_)
         {
            ProcessPings(rsslConsumerChannel_);
         }
      }
   }

   	  // thread has stopped
   RemoveChannel(rsslConsumerChannel_);

   t42log_debug("Exit UPAConsumer thread\n");
}
Beispiel #5
0
RsslRet processActiveChannel(ChannelHandler *pChanHandler, ChannelInfo *pChannelInfo)
{
	ProviderThread *pProvThread = (ProviderThread*)pChanHandler->pUserSpec;
	ProviderSession *pProvSession = (ProviderSession*)pChannelInfo->pUserSpec;
	RsslError error;
	RsslRet ret;
	RsslChannelInfo channelInfo;
	RsslUInt32 count;

#ifdef ENABLE_XML_TRACE
	RsslTraceOptions traceOptions;
	rsslClearTraceOptions(&traceOptions);
	traceOptions.traceMsgFileName = "upacProvPerf";
	traceOptions.traceMsgMaxFileSize = 1000000000;
	traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_WRITE | RSSL_TRACE_READ;
	rsslIoctl(pChannelInfo->pChannel, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, &error);
#endif

	if (provPerfConfig.highWaterMark > 0)
	{
		if (rsslIoctl(pChannelInfo->pChannel, RSSL_HIGH_WATER_MARK, &provPerfConfig.highWaterMark, &error) != RSSL_RET_SUCCESS)
		{
			printf("rsslIoctl() of RSSL_HIGH_WATER_MARK failed <%s>\n", error.text);
			exit(-1);
		}
	}

	if ((ret = rsslGetChannelInfo(pChannelInfo->pChannel, &channelInfo, &error)) != RSSL_RET_SUCCESS)
	{
		printf("rsslGetChannelInfo() failed: %d\n", ret);
		return 0;
	} 

	printf( "Channel %d active. Channel Info:\n"
			"  maxFragmentSize: %u\n"
			"  maxOutputBuffers: %u\n"
			"  guaranteedOutputBuffers: %u\n"
			"  numInputBuffers: %u\n"
			"  pingTimeout: %u\n"
			"  clientToServerPings: %s\n"
			"  serverToClientPings: %s\n"
			"  sysSendBufSize: %u\n"
			"  sysSendBufSize: %u\n"			
			"  compressionType: %s\n"
			"  compressionThreshold: %u\n"			
			"  ComponentInfo: ", 
			pChannelInfo->pChannel->socketId,
			channelInfo.maxFragmentSize,
			channelInfo.maxOutputBuffers, channelInfo.guaranteedOutputBuffers,
			channelInfo.numInputBuffers,
			channelInfo.pingTimeout,
			channelInfo.clientToServerPings == RSSL_TRUE ? "true" : "false",
			channelInfo.serverToClientPings == RSSL_TRUE ? "true" : "false",
			channelInfo.sysSendBufSize, channelInfo.sysRecvBufSize,			
			channelInfo.compressionType == RSSL_COMP_ZLIB ? "zlib" : "none",
			channelInfo.compressionThreshold			
			);

	if (channelInfo.componentInfoCount == 0)
		printf("(No component info)");
	else
		for(count = 0; count < channelInfo.componentInfoCount; ++count)
		{
			printf("%.*s", 
					channelInfo.componentInfo[count]->componentVersion.length,
					channelInfo.componentInfo[count]->componentVersion.data);
			if (count < channelInfo.componentInfoCount - 1)
				printf(", ");
		}
	printf ("\n\n");

	/* Check that we can successfully pack, if packing messages. */
	if (providerThreadConfig.totalBuffersPerPack > 1
			&& providerThreadConfig.packingBufferLength > channelInfo.maxFragmentSize)
	{
		printf("Error(Channel %d): MaxFragmentSize %u is too small for packing buffer size %u\n",
				pChannelInfo->pChannel->socketId, channelInfo.maxFragmentSize, 
				providerThreadConfig.packingBufferLength);
		exit(-1);
	}



	if (ret = (printEstimatedMsgSizes(pProvThread, pProvSession)) != RSSL_RET_SUCCESS)
		return RSSL_RET_FAILURE;

	pProvSession->timeActivated = getTimeNano();

	return RSSL_RET_SUCCESS;
}
Beispiel #6
0
RsslReactorCallbackRet channelEventCallback(RsslReactor *pReactor, RsslReactorChannel *pReactorChannel, RsslReactorChannelEvent *pChannelEvent)
{
	ProviderSession *pProvSession = (ProviderSession *)pReactorChannel->userSpecPtr;
	ProviderThread *pProviderThread = pProvSession->pProviderThread;
	RsslErrorInfo rsslErrorInfo;
	RsslReactorChannelInfo reactorChannelInfo;
	RsslUInt32 count;
	RsslRet ret;

	switch(pChannelEvent->channelEventType)
	{
		case RSSL_RC_CET_CHANNEL_UP:
		{
			/* A channel that we have requested via rsslReactorAccept() has come up.  Set our
			 * file descriptor sets so we can be notified to start calling rsslReactorDispatch() for
			 * this channel. */
			FD_SET(pReactorChannel->socketId, &pProviderThread->readfds);
			FD_SET(pReactorChannel->socketId, &pProviderThread->exceptfds);

#ifdef ENABLE_XML_TRACE
			RsslTraceOptions traceOptions;
			rsslClearTraceOptions(&traceOptions);
			traceOptions.traceMsgFileName = "upacProvPerf";
			traceOptions.traceMsgMaxFileSize = 1000000000;
			traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_WRITE | RSSL_TRACE_READ;
			rsslIoctl(pChannelInfo->pChannel, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, &error);
#endif

			if (provPerfConfig.highWaterMark > 0)
			{
				if (rsslReactorChannelIoctl(pReactorChannel, RSSL_HIGH_WATER_MARK, &provPerfConfig.highWaterMark, &rsslErrorInfo) != RSSL_RET_SUCCESS)
                {
					printf("rsslReactorChannelIoctl() of RSSL_HIGH_WATER_MARK failed <%s>\n", rsslErrorInfo.rsslError.text);
					exit(-1);
                }
			}

			if ((ret = rsslReactorGetChannelInfo(pReactorChannel, &reactorChannelInfo, &rsslErrorInfo)) != RSSL_RET_SUCCESS)
			{
				printf("rsslReactorGetChannelInfo() failed: %d\n", ret);
				return RSSL_RC_CRET_SUCCESS;
			} 

			printf( "Channel %d active. Channel Info:\n"
					"  maxFragmentSize: %u\n"
					"  maxOutputBuffers: %u\n"
					"  guaranteedOutputBuffers: %u\n"
					"  numInputBuffers: %u\n"
					"  pingTimeout: %u\n"
					"  clientToServerPings: %s\n"
					"  serverToClientPings: %s\n"
					"  sysSendBufSize: %u\n"
					"  sysSendBufSize: %u\n"			
					"  compressionType: %s\n"
					"  compressionThreshold: %u\n"			
					"  ComponentInfo: ", 
					pReactorChannel->socketId,
					reactorChannelInfo.rsslChannelInfo.maxFragmentSize,
					reactorChannelInfo.rsslChannelInfo.maxOutputBuffers, reactorChannelInfo.rsslChannelInfo.guaranteedOutputBuffers,
					reactorChannelInfo.rsslChannelInfo.numInputBuffers,
					reactorChannelInfo.rsslChannelInfo.pingTimeout,
					reactorChannelInfo.rsslChannelInfo.clientToServerPings == RSSL_TRUE ? "true" : "false",
					reactorChannelInfo.rsslChannelInfo.serverToClientPings == RSSL_TRUE ? "true" : "false",
					reactorChannelInfo.rsslChannelInfo.sysSendBufSize, reactorChannelInfo.rsslChannelInfo.sysRecvBufSize,			
					reactorChannelInfo.rsslChannelInfo.compressionType == RSSL_COMP_ZLIB ? "zlib" : "none",
					reactorChannelInfo.rsslChannelInfo.compressionThreshold			
					);

			if (reactorChannelInfo.rsslChannelInfo.componentInfoCount == 0)
				printf("(No component info)");
			else
				for(count = 0; count < reactorChannelInfo.rsslChannelInfo.componentInfoCount; ++count)
				{
					printf("%.*s", 
							reactorChannelInfo.rsslChannelInfo.componentInfo[count]->componentVersion.length,
							reactorChannelInfo.rsslChannelInfo.componentInfo[count]->componentVersion.data);
					if (count < reactorChannelInfo.rsslChannelInfo.componentInfoCount - 1)
						printf(", ");
				}
			printf ("\n\n");

			/* Check that we can successfully pack, if packing messages. */
			if (providerThreadConfig.totalBuffersPerPack > 1
					&& providerThreadConfig.packingBufferLength > reactorChannelInfo.rsslChannelInfo.maxFragmentSize)
			{
				printf("Error(Channel %d): MaxFragmentSize %u is too small for packing buffer size %u\n",
						pReactorChannel->socketId, reactorChannelInfo.rsslChannelInfo.maxFragmentSize, 
						providerThreadConfig.packingBufferLength);
				exit(-1);
			}


			pProvSession->pChannelInfo->pChannel = pReactorChannel->pRsslChannel;
			pProvSession->pChannelInfo->pReactorChannel = pReactorChannel;
			pProvSession->pChannelInfo->pReactor = pReactor;
			rsslQueueAddLinkToBack(&pProviderThread->channelHandler.activeChannelList, &pProvSession->pChannelInfo->queueLink);
			pProvSession->timeActivated = getTimeNano();

			return RSSL_RC_CRET_SUCCESS;
		}
		case RSSL_RC_CET_CHANNEL_READY:
		{
			if (ret = (printEstimatedMsgSizes(pProviderThread, pProvSession)) != RSSL_RET_SUCCESS)
			{
				printf("printEstimatedMsgSizes() failed: %d\n", ret);
				return RSSL_RC_CRET_SUCCESS;
			}

			return RSSL_RC_CRET_SUCCESS;
		}
		case RSSL_RC_CET_FD_CHANGE:
		{
			/* The file descriptor representing the RsslReactorChannel has been changed.
			 * Update our file descriptor sets. */
			printf("Fd change: %d to %d\n", pReactorChannel->oldSocketId, pReactorChannel->socketId);
			FD_CLR(pReactorChannel->oldSocketId, &pProviderThread->readfds);
			FD_CLR(pReactorChannel->oldSocketId, &pProviderThread->exceptfds);
			FD_SET(pReactorChannel->socketId, &pProviderThread->readfds);
			FD_SET(pReactorChannel->socketId, &pProviderThread->exceptfds);

			return RSSL_RC_CRET_SUCCESS;
		}
		case RSSL_RC_CET_WARNING:
		{
			/* We have received a warning event for this channel. Print the information and continue. */
			printf("Received warning for Channel fd=%d.\n", pReactorChannel->socketId);
			printf("	Error text: %s\n", pChannelEvent->pError->rsslError.text);

			return RSSL_RC_CRET_SUCCESS;
		}
		case RSSL_RC_CET_CHANNEL_DOWN:
		{
			pProviderThread->stats.inactiveTime = getTimeNano();

			printf("Channel Closed.\n");

			FD_CLR(pReactorChannel->socketId, &pProviderThread->readfds);
			FD_CLR(pReactorChannel->socketId, &pProviderThread->exceptfds);

			--pProviderThread->clientSessionsCount;
			if (pProvSession->pChannelInfo->pReactorChannel && rsslQueueGetElementCount(&pProviderThread->channelHandler.activeChannelList) > 0)
			{
				rsslQueueRemoveLink(&pProviderThread->channelHandler.activeChannelList, &pProvSession->pChannelInfo->queueLink);
			}
	
			if (pProvSession)
			{
				free(pProvSession->pChannelInfo);
				providerSessionDestroy(pProviderThread, pProvSession);
			}

			if (rsslReactorCloseChannel(pReactor, pReactorChannel, &rsslErrorInfo) != RSSL_RET_SUCCESS)
			{
				printf("rsslReactorCloseChannel() failed: %s\n", rsslErrorInfo.rsslError.text);
				cleanUpAndExit();
			}

			return RSSL_RC_CRET_SUCCESS;
		}
		default:
			printf("Unknown channel event!\n");
			cleanUpAndExit();
	}

	return RSSL_RC_CRET_SUCCESS;
}
RsslRet processActiveChannel(ChannelHandler *pChanHandler, ChannelInfo *pChannelInfo)
{
	ProviderThread *pProviderThread = (ProviderThread*)pChanHandler->pUserSpec;
	ProviderSession *pProvSession = (ProviderSession*)pChannelInfo->pUserSpec;
	RsslRet ret;
	RsslError error;
	RsslChannelInfo channelInfo;
	RsslUInt32 count;

	if (niProvPerfConfig.highWaterMark > 0)
	{
		if (rsslIoctl(pChannelInfo->pChannel, RSSL_HIGH_WATER_MARK, &niProvPerfConfig.highWaterMark, &error) != RSSL_RET_SUCCESS)
		{
			printf("rsslIoctl() of RSSL_HIGH_WATER_MARK failed <%s>\n", error.text);
			exit(-1);
		}
	}

	if ((ret = rsslGetChannelInfo(pChannelInfo->pChannel, &channelInfo, &error)) != RSSL_RET_SUCCESS)
	{
		printf("rsslGetChannelInfo() failed: %d\n", ret);
		return 0;
	} 

	printf( "Channel %d active. Channel Info:\n"
			"  maxFragmentSize: %u\n"
			"  maxOutputBuffers: %u\n"
			"  guaranteedOutputBuffers: %u\n"
			"  numInputBuffers: %u\n"
			"  pingTimeout: %u\n"
			"  clientToServerPings: %s\n"
			"  serverToClientPings: %s\n"
			"  sysSendBufSize: %u\n"
			"  sysSendBufSize: %u\n"			
			"  compressionType: %s\n"
			"  compressionThreshold: %u\n"			
			"  ComponentInfo: ", 
			pChannelInfo->pChannel->socketId,
			channelInfo.maxFragmentSize,
			channelInfo.maxOutputBuffers, channelInfo.guaranteedOutputBuffers,
			channelInfo.numInputBuffers,
			channelInfo.pingTimeout,
			channelInfo.clientToServerPings == RSSL_TRUE ? "true" : "false",
			channelInfo.serverToClientPings == RSSL_TRUE ? "true" : "false",
			channelInfo.sysSendBufSize, channelInfo.sysRecvBufSize,			
			channelInfo.compressionType == RSSL_COMP_ZLIB ? "zlib" : "none",
			channelInfo.compressionThreshold			
			);

	if (channelInfo.componentInfoCount == 0)
		printf("(No component info)");
	else
		for(count = 0; count < channelInfo.componentInfoCount; ++count)
		{
			printf("%.*s", 
					channelInfo.componentInfo[count]->componentVersion.length,
					channelInfo.componentInfo[count]->componentVersion.data);
			if (count < channelInfo.componentInfoCount - 1)
				printf(", ");
		}
	printf ("\n\n");

	/* Check that we can successfully pack, if packing messages. */
	if (providerThreadConfig.totalBuffersPerPack > 1
			&& providerThreadConfig.packingBufferLength > channelInfo.maxFragmentSize)
	{
		printf("Error(Channel %d): MaxFragmentSize %u is too small for packing buffer size %u\n",
				pChannelInfo->pChannel->socketId, channelInfo.maxFragmentSize, 
				providerThreadConfig.packingBufferLength);
		exit(-1);
	}

	if (ret = (printEstimatedMsgSizes(pProviderThread, pProvSession)) != RSSL_RET_SUCCESS)
		return RSSL_RET_FAILURE;

	pProvSession->timeActivated = getTimeNano();

	/* Send Login Request */
	ret = sendLoginRequest(pChanHandler, pChannelInfo, 1, &error);
	if (ret < RSSL_RET_SUCCESS)
	{
		printf("sendLoginRequest() failed: %d\n", ret);
		exit(-1);
	}
	else if (ret > RSSL_RET_SUCCESS)
	{
		/* Need to flush */
		providerThreadRequestChannelFlush(pProviderThread, pChannelInfo);
	}


	return RSSL_RET_SUCCESS;
}
Beispiel #8
0
void UPAProvider::ReadFromChannel(RsslChannel* chnl)
{
    // first, handle state change
    int			retval;
    RsslError	error;

    if (chnl->socketId != -1 && chnl->state == RSSL_CH_STATE_INITIALIZING)
    {
        RsslInProgInfo inProg = RSSL_INIT_IN_PROG_INFO;
        // its initialising
        if ((retval = rsslInitChannel(chnl, &inProg, &error)) < RSSL_RET_SUCCESS)
        {
            // we fail to init the channel so just shut it down
            t42log_warn("sessionInactive fd=%d <%s>\n", chnl->socketId,error.text);
            RemoveChannelConnection(chnl);
        }
        else 
        {
            switch (retval)
            {
            case RSSL_RET_CHAN_INIT_IN_PROGRESS:
                if (inProg.flags & RSSL_IP_FD_CHANGE)
                {
                    // the FDs have changed
                    t42log_info("Channel In Progress - New FD: %d  Old FD: %d\n",chnl->socketId, inProg.oldSocket );

                    FD_CLR(inProg.oldSocket,&readfds_);
                    FD_CLR(inProg.oldSocket,&exceptfds_);
                    FD_SET(chnl->socketId,&readfds_);
                    FD_SET(chnl->socketId,&exceptfds_);
                }
                else
                {
                    t42log_debug("Channel %d connection in progress\n", chnl->socketId);
                }
                break;

            case RSSL_RET_SUCCESS:
                {
                    // initialization is complete

                    t42log_info("Client Channel fd=%d is now ACTIVE\n" ,chnl->socketId);
#ifdef _WIN32
                    // WINDOWS: change size of send/receive buffer since it's small by default 
                    int rcvBfrSize = 65535;
                    int sendBfrSize = 65535;

                    if (rsslIoctl(chnl, RSSL_SYSTEM_WRITE_BUFFERS, &sendBfrSize, &error) != RSSL_RET_SUCCESS)
                    {
                        t42log_warn("rsslIoctl(): failed <%s>\n", error.text);
                    }
                    if (rsslIoctl(chnl, RSSL_SYSTEM_READ_BUFFERS, &rcvBfrSize, &error) != RSSL_RET_SUCCESS)
                    {
                        t42log_warn("rsslIoctl(): failed <%s>\n", error.text);
                    }
#endif

                    /* if device we connect to supports connected component versioning, 
                    * also display the product version of what this connection is to */
                    RsslChannelInfo chanInfo;	
                    if ((retval = rsslGetChannelInfo(chnl, &chanInfo, &error)) >= RSSL_RET_SUCCESS)
                    {
                        RsslUInt32 i;
                        for (i = 0; i < chanInfo.componentInfoCount; i++)
                        {
                            t42log_info("Connection is from %s device.\n", chanInfo.componentInfo[i]->componentVersion.data);
                        }
                    }
                }
                break;

            default:
                t42log_error("Bad return value fd=%d <%s>\n", chnl->socketId,error.text);
                RemoveChannelConnection(chnl);
                break;
            }
        }
    }

    // the channel is active so read whatver there is to read
    if (chnl->socketId != -1 && chnl->state == RSSL_CH_STATE_ACTIVE)
    {
        RsslRet	readret = 1;

        while (readret > 0) /* read until no more to read */
        {
            RsslBuffer *msgBuf = 0 ;
            if ((msgBuf = rsslRead(chnl,&readret,&error)) != 0)
            {
                if (ProcessRequest(chnl, msgBuf) == RSSL_RET_SUCCESS)
                {
                    /* set flag for client message received */
                    SetChannelReceivedClientMsg(chnl);
                }
            }
            if (msgBuf == 0)
            {
                switch (readret)
                {
                case RSSL_RET_CONGESTION_DETECTED:
                case RSSL_RET_SLOW_READER:
                case RSSL_RET_PACKET_GAP_DETECTED:
                    if (chnl->state != RSSL_CH_STATE_CLOSED)
                    {
                        // disconnectOnGaps must be false.  Connection is not closed 
                        t42log_warn("Read Error: %s <%d>\n", error.text, readret);
                        /* break out of switch */
                        break;
                    }
                    /// if channel is closed, we want to fall through 
                case RSSL_RET_FAILURE:
                    {
                        t42log_info("channelInactive fd=%d <%s>\n",
                            chnl->socketId,error.text);
                        RemoveChannelConnection(chnl);

                    }
                    break;
                case RSSL_RET_READ_FD_CHANGE:
                    {
                        t42log_info("rsslRead() FD Change - Old FD: %d New FD: %d\n", chnl->oldSocketId, chnl->socketId);
                        FD_CLR(chnl->oldSocketId, &readfds_);
                        FD_CLR(chnl->oldSocketId, &exceptfds_);
                        FD_SET(chnl->socketId, &readfds_);
                        FD_SET(chnl->socketId, &exceptfds_);
                    }
                    break;
                case RSSL_RET_READ_PING: 
                    {
                        /* set flag for client message received */
                        SetChannelReceivedClientMsg(chnl);
                    }
                    break;
                default:
                    if (readret < 0 && readret != RSSL_RET_READ_WOULD_BLOCK)
                    {
                        t42log_warn("Read Error: %s <%d>\n", error.text, readret);

                    }
                    break;
                }
            }
        }
    }
    else if (chnl->state == RSSL_CH_STATE_CLOSED)
    {
        t42log_info("Channel fd=%d Closed.\n", chnl->socketId);
        RemoveChannelConnection(chnl);
    }



}