/*
 * Reads from a channel.
 * chnl - The channel to be read from
 */
static RsslRet readFromChannel(RsslChannel* chnl)
{
	RsslError		error;
	RsslBuffer *msgBuf=0;
	RsslRet	readret;
	RsslReadInArgs	readInArgs;

	if(chnl->socketId != -1 && chnl->state == RSSL_CH_STATE_ACTIVE)
	{
		readret = 1;
		while (readret > 0) /* read until no more to read */
		{
			rsslClearReadInArgs(&readInArgs);
			if ((msgBuf = rsslReadEx(chnl, &readInArgs, &readOutArgs, &readret,&error)) != 0)
			{
				if (showTransportDetails)
				{
					printf("\nMessage Details:\n");
					printf("Cumulative bytesRead=%d\n", readOutArgs.bytesRead);
					printf("Cumulative uncompressedBytesRead=%d\n", readOutArgs.uncompressedBytesRead);
				}
				if (processResponse(chnl, msgBuf) == RSSL_RET_SUCCESS)	
				{
					/* set flag for server message received */
					receivedServerMsg = RSSL_TRUE;
				}
				else
					return RSSL_RET_FAILURE;
			}
			else
			{
				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 */
							printf("\nRead 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:
					{
						printf("\nchannelInactive fd="SOCKET_PRINT_TYPE" <%s>\n",	
					    chnl->socketId,error.text);
						recoverConnection();
					}
					break;
					case RSSL_RET_READ_FD_CHANGE:
					{
						printf("\nrsslRead() FD Change - Old FD: "SOCKET_PRINT_TYPE" New FD: "SOCKET_PRINT_TYPE"\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 server message received */
						receivedServerMsg = RSSL_TRUE;
					}
					break;
					default:
						if (readret < 0 && readret != RSSL_RET_READ_WOULD_BLOCK)
						{
							printf("\nRead Error: %s <%d>\n", error.text, readret);
						
						}
					break;
				}
			}
		}
	}
	else if (chnl->state == RSSL_CH_STATE_CLOSED)
	{
		printf("Channel fd="SOCKET_PRINT_TYPE" Closed.\n", chnl->socketId);	
		recoverConnection();
	}

	return RSSL_RET_SUCCESS;
}
RsslRet snapshotSessionProcessReadReady(SnapshotSession *pSession)
{
	RsslRet readRet;
	RsslRet ret = RSSL_RET_FAILURE;
	RsslError rsslError;


	RsslBuffer *pBuffer;
	RsslReadInArgs readInArgs;
	RsslReadOutArgs readOutArgs;

	switch(pSession->pRsslChannel->state)
	{
		case RSSL_CH_STATE_ACTIVE:

			rsslClearReadInArgs(&readInArgs);
			rsslClearReadOutArgs(&readOutArgs);

			pBuffer = rsslReadEx(pSession->pRsslChannel, &readInArgs, &readOutArgs, &readRet, 
					&rsslError);

			if (pBuffer)
			{
				if ((ret = snapshotSessionProcessMessage(pSession, pBuffer)) != RSSL_RET_SUCCESS)
					return ret;
			}

			if (readRet >= RSSL_RET_SUCCESS)
				return readRet;

			/* Read values less than RSSL_RET_SUCCESS are codes to handle. */
			switch (readRet)
			{
				case RSSL_RET_READ_FD_CHANGE:
					/* Channel's file descriptor was changed. */
					printf("<%s> Channel FD changed while reading (from %d to %d).\n\n",
							pSession->name, pSession->pRsslChannel->oldSocketId,
							pSession->pRsslChannel->socketId);
					return RSSL_RET_SUCCESS;

				case RSSL_RET_READ_PING:
					/* Received a ping message. */
					printf("<%s> Received ping.\n\n", pSession->name);
					return RSSL_RET_SUCCESS;

				case RSSL_RET_READ_WOULD_BLOCK:
					/* Nothing to read. */
					return RSSL_RET_SUCCESS;

				case RSSL_RET_FAILURE:
				default:
					/* Channel failed or unhandled code; close the channel. */
					printf("<%s> rsslReadEx() failed: %d(%s -- %s).\n\n", pSession->name,
							readRet, rsslRetCodeToString(readRet), rsslError.text);
					rsslCloseChannel(pSession->pRsslChannel, &rsslError);
					pSession->pRsslChannel = NULL;
					return readRet;
			}

		case RSSL_CH_STATE_INITIALIZING:
			return snapshotSessionInitializeChannel(pSession);

		default:
			printf("<%s> Unhandled channel state %u.\n\n", pSession->name,
					ret, rsslRetCodeToString(ret));
			exit(-1);
			return RSSL_RET_FAILURE;


	}

}