void Run () {
		int nAttempt = 0;
		CNamedPipe *poPipe;
		do {
			if (nAttempt) {
				Sleep (TIMEOUT / 10);
			}
			poPipe = CNamedPipe::ClientWrite (m_pszPipeName);
		} while (!poPipe && (GetLastError () == ENOENT) && (++nAttempt < 10));
		if (poPipe) {
			LOGDEBUG (TEXT ("Client connected"));
			ClientConnect cc;
			memset (&cc, 0, sizeof (cc));
			cc._userName = TEST_USERNAME;
			cc._CPPToJavaPipe = TEST_CPP2JAVA;
			cc._JavaToCPPPipe = TEST_JAVA2CPP;
			cc._languageID = TEST_LANGUAGE;
			cc._debug = TEST_DEBUG;
			FudgeMsg msg;
			ASSERT (ClientConnect_toFudgeMsg (&cc, &msg) == FUDGE_OK);
			FudgeMsgEnvelope env;
			ASSERT (FudgeMsgEnvelope_create (&env, 0, 0, 0, msg) == FUDGE_OK);
			fudge_byte *ptrBuffer;
			fudge_i32 cbBuffer;
			ASSERT (FudgeCodec_encodeMsg (env, &ptrBuffer, &cbBuffer) == FUDGE_OK);
			FudgeMsgEnvelope_release (env);
			FudgeMsg_release (msg);
			ASSERT (poPipe->Write (ptrBuffer, cbBuffer, TIMEOUT) == cbBuffer);
			delete ptrBuffer;
		} else {
			LOGWARN (TEXT ("Couldn't open client pipe, error ") << GetLastError ());
		}
	}
Example #2
0
/* For the most basic example of Fudge-C use, see the "simple.c" file that
   should be in the same directory as this one.

   This is a basic "pretty printer" for Fudge-C encoded message files. It
   takes the filename of the message to display and dumps the contents, in
   human readable form, to the standard output.

   Rather than assume a Unicode compatible console, all strings are
   converted in to 7bit ASCII before being output.
*/
int main ( int argc, char * argv [ ] )
{
    FudgeStatus status;
    FudgeMsgEnvelope envelope;
    const char * filename;
    fudge_byte * bytes;
    fudge_i32 numbytes;

    /* Get the filename from the command-line arguments */
    if ( argc != 2 )
        displayUsage ( );
    filename = argv [ 1 ];

    /* Initialise the Fudge library */
    if ( ( status = Fudge_init ( ) ) )
        fatalFudgeError ( status, "Failed to initialise Fudge library" );

    /* Load in the file and attempt to decode it */
    loadFile ( &bytes, &numbytes, filename );
    if ( ( status = FudgeCodec_decodeMsg ( &envelope, bytes, numbytes ) ) )
        fatalFudgeError ( status, "Failed to decode file" );
    free ( bytes );

    /* Output the file contents */
    outputEnvelope ( envelope );
    FudgeMsgEnvelope_release ( envelope );
    return 0;
}
	void Run () {
		CSettings settings;
		ASSERT (settings.GetConnectionPipe ());
		LOGDEBUG (TEXT ("Connecting to ") << settings.GetConnectionPipe ());
		CNamedPipe *poPipe = CNamedPipe::ClientWrite (settings.GetConnectionPipe ());
		ASSERT (poPipe);
		LOGDEBUG (TEXT ("Client connected"));
		ClientConnect cc;
		memset (&cc, 0, sizeof (cc));
		cc._userName = TEST_USERNAME;
		cc._CPPToJavaPipe = TEST_CPP2JAVA;
		cc._JavaToCPPPipe = TEST_JAVA2CPP;
		cc._languageID = TEST_LANGUAGE;
#ifdef _DEBUG
		cc._debug = FUDGE_TRUE;
#endif /* ifdef _DEBUG */
		FudgeMsg msg;
		ASSERT (ClientConnect_toFudgeMsg (&cc, &msg) == FUDGE_OK);
		FudgeMsgEnvelope env;
		ASSERT (FudgeMsgEnvelope_create (&env, 0, 0, 0, msg) == FUDGE_OK);
		fudge_byte *ptrBuffer;
		fudge_i32 cbBuffer;
		ASSERT (FudgeCodec_encodeMsg (env, &ptrBuffer, &cbBuffer) == FUDGE_OK);
		FudgeMsgEnvelope_release (env);
		FudgeMsg_release (msg);
		LOGDEBUG (TEXT ("Writing connection packet"));
		ASSERT (poPipe->Write (ptrBuffer, cbBuffer, TIMEOUT_CONNECT) == (size_t)cbBuffer);
		LOGDEBUG (TEXT ("Connection packet written"));
		delete ptrBuffer;
		LOGDEBUG (TEXT ("Disconnecting"));
		delete poPipe;
	}
Example #4
0
// This must only be called from the thread that creates and connects the pipes. This then
// doesn't need to acquire the pipe semaphore as the object won't be modified concurrently.
// Another thread might be sending, but that's it.
bool CClientService::DispatchAndRelease (FudgeMsgEnvelope env) {
	FudgeMsg msg = FudgeMsgEnvelope_getMessage (env);
	switch (FudgeMsgEnvelope_getDirectives (env)) {
	case MESSAGE_DIRECTIVES_CLIENT : {
		Operation op;
		if (ConnectorMessage_getOperation (msg, &op) == FUDGE_OK) {
			switch (op) {
			case HEARTBEAT :
				LOGDEBUG (TEXT ("Heartbeat received"));
				break;
			case POISON :
				// This shouldn't be sent by the Java stack
				LOGFATAL (TEXT ("Received poison from Java framework"));
				assert (0);
				break;
			case STASH : {
				FudgeMsg msgStash;
				if (ConnectorMessage_getStash (msg, &msgStash) == FUDGE_OK) {
					LOGDEBUG (TEXT ("Storing stash message"));
					m_oStateMutex.Enter ();
					if (m_poRunner) {
						m_poRunner->SetStash (msgStash);
					} else {
						LOGWARN (TEXT ("No runner thread"));
					}
					m_oStateMutex.Leave ();
					FudgeMsg_release (msgStash);
				} else {
					LOGWARN (TEXT ("No stash message attached"));
				}
				break;
						 }
			default :
				LOGWARN (TEXT ("Invalid client message - operation ") << op);
				break;
			}
		} else {
			LOGWARN (TEXT ("Invalid client message"));
		}
		break;
										}
	case MESSAGE_DIRECTIVES_USER :
		m_oMessageReceivedMutex.Enter ();
		if (m_poMessageReceivedCallback) {
			m_poMessageReceivedCallback->OnMessageReceived (msg);
		}
		m_oMessageReceivedMutex.Leave ();
		break;
	default :
		LOGWARN (TEXT ("Unknown message delivery directive ") << FudgeMsgEnvelope_getDirectives (env));
		break;
	}
	FudgeMsgEnvelope_release (env);
	return m_poPipes->IsConnected ();
}
Example #5
0
/// Creates a Fudge message from a binary encoding.
///
/// @param[in] pData the encoded message data
/// @param[in] cbData the length of the encoded data in bytes
/// @return the message, or NULL if there is a problem
static FudgeMsg _DecodeFudgeMsg (const void *pData, size_t cbData) {
	FudgeMsgEnvelope env;
	FudgeMsg msg = NULL;
	if (FudgeCodec_decodeMsg (&env, (fudge_byte*)pData, cbData) == FUDGE_OK) {
		msg = FudgeMsgEnvelope_getMessage (env);
		FudgeMsg_retain (msg);
		FudgeMsgEnvelope_release (env);
	} else {
		LOGWARN (TEXT ("Couldn't decode Fudge message"));
	}
	return msg;
}
Example #6
0
/// Creates a binary encoding of a Fudge message.
///
/// @param[in] msg the message to encode
/// @param[out] pcbData receives the length of the allocated encoding
/// @return the encoded form
static void *_EncodeFudgeMsg (FudgeMsg msg, size_t *pcbData) {
	FudgeStatus status;
	FudgeMsgEnvelope env;
	void *pData;
	if ((status = FudgeMsgEnvelope_create (&env, 0, 0, 0, msg)) != FUDGE_OK) {
		LOGWARN ("Couldn't create message envelope, error " << FudgeStatus_strerror (status));
		return NULL;
	}
	fudge_i32 cbData;
	status = FudgeCodec_encodeMsg (env, (fudge_byte**)&pData, &cbData);
	FudgeMsgEnvelope_release (env);
	if (status != FUDGE_OK) {
		LOGWARN ("Couldn't encode Fudge message, error " << FudgeStatus_strerror (status));
		return NULL;
	}
	*pcbData = cbData;
	return pData;
}
Example #7
0
FudgeStatus FudgeCodec_decodeMsg ( FudgeMsgEnvelope * envelope, const fudge_byte * bytes, fudge_i32 numbytes )
{
    FudgeStatus status;
    FudgeMsgHeader header;
    FudgeMsg message;

    if ( ! envelope )
        return FUDGE_NULL_POINTER;

    /* Get the message header and use it to create the envelope and the message */
    if ( ( status = FudgeHeader_decodeMsgHeader ( &header, bytes, numbytes ) ) != FUDGE_OK )
        return status;
    if ( numbytes < header.numbytes )
        return FUDGE_OUT_OF_BYTES;
    if ( ( status = FudgeMsg_create ( &message ) ) != FUDGE_OK )
        return status;

    if ( ( status = FudgeMsgEnvelope_create ( envelope,
                                              header.directives,
                                              header.schemaversion,
                                              header.taxonomy,
                                              message ) ) != FUDGE_OK )
        goto release_message_and_fail;

    /* Envelope now has a message reference */
    FudgeMsg_release ( message );

    /* Advance to the end of the header */
    bytes += sizeof ( FudgeMsgHeader );
    numbytes -= sizeof ( FudgeMsgHeader );

    /* Consume fields */
    if ( ( status = FudgeCodec_decodeMsgFields ( message, bytes, numbytes ) ) != FUDGE_OK )
        goto release_envelope_and_fail;

    return status;

release_envelope_and_fail:
    FudgeMsgEnvelope_release ( *envelope );

release_message_and_fail:
    FudgeMsg_release ( message );
    return status;
}
Example #8
0
int main ( int argc, char * argv [ ] )
{
    FudgeStatus status;
    FudgeMsg message;
    FudgeMsgEnvelope envelope;
    AddressDetails * details [ 2 ];
    fudge_i16 ordinal;
    fudge_byte * encoded;
    fudge_i32 encodedsize;

    /* Initialise the Fudge library */
    if ( ( status = Fudge_init ( ) ) )
        fatalFudgeError ( status, "Failed to initialise Fudge library" );

    /* Register the AddressDetails type */
    if ( ( status = FudgeRegistry_registerType ( FUDGE_TYPE_ADDRESSDETAILS,
                    FUDGE_TYPE_PAYLOAD_BYTES,
                    FudgeCodec_decodeFieldAddressDetails,
                    FudgeCodec_encodeFieldAddressDetails,
                    FudgeType_coerceAddressDetails ) ) )
        fatalFudgeError ( status, "Failed to register AddressDetails type" );

    /* Construct and encode two address details */
    details [ 0 ] = constructAddressDetails ( Status_Past, 123, "Fake St.", "Some City", "P05 T4L" );
    details [ 1 ] = constructAddressDetails ( Status_Active, 45, "Faux Road", "Some Town", "FUD 63C" );

    /* Create a message and add the two details */
    if ( ( status = FudgeMsg_create ( &message ) ) )
        fatalFudgeError ( status, "Failed to create Fudge message" );

    for ( ordinal = 0; ordinal < 2; ++ordinal )
        FudgeMsg_addFieldAddressDetails ( message, 0, &ordinal, details [ ordinal ] );

    /* Encode the message */
    if ( ( status = FudgeMsgEnvelope_create ( &envelope, 0, 0, 0, message ) ) )
        fatalFudgeError ( status, "Failed to create Fudge messag envelope" );

    if ( ( status = FudgeCodec_encodeMsg ( envelope, &encoded, &encodedsize ) ) )
        fatalFudgeError ( status, "Failed to encode Fudge message" );

    /* Clean up source details and messge */
    free ( details [ 0 ] );
    free ( details [ 1 ] );
    FudgeMsgEnvelope_release ( envelope );
    FudgeMsg_release ( message );

    /* Decode the message and release the encoded bytes array */
    if ( ( status = FudgeCodec_decodeMsg ( &envelope, encoded, encodedsize ) ) )
        fatalFudgeError ( status, "Failed to decode Fudge message" );
    free ( encoded );

    /* Retrieve, convert and display the fields */
    for ( ordinal = 0; ordinal < 2; ++ordinal )
    {
        FudgeField field;
        FudgeFieldData data;
        FudgeTypePayload payload;
        fudge_i32 datasize;
        char * ascii;

        if ( ( status = FudgeMsg_getFieldByOrdinal ( &field, FudgeMsgEnvelope_getMessage ( envelope ), ordinal ) ) )
            fatalFudgeError ( status, "Failed to find field" );

        /* Convert the field in to a string */
        if ( ( status = FudgeMsg_getFieldAs ( &field, FUDGE_TYPE_STRING, &data, &payload, &datasize ) ) )
            fatalFudgeError ( status, "Failed to convert field to string" );

        /* This is a bit paranoid, but it's checking that the string
           conversion actually resulted in string payload */
        if ( payload != FUDGE_TYPE_PAYLOAD_STRING )
        {
            fprintf ( stderr, "FATAL ERROR: Retrieving field %d as a string returned a non-string!\n", ordinal );
            exit ( 1 );
        }

        FudgeString_convertToASCIIZ ( &ascii, data.string );
        printf ( "Field %d: %s\n", ordinal, ascii );
        free ( ascii );
        FudgeString_release ( data.string );
    }

    /* Clean up */
    FudgeMsgEnvelope_release ( envelope );
    return 0;
}
Example #9
0
bool CClientService::Send (int cProcessingDirectives, FudgeMsg msg) const {
	FudgeStatus status;
	FudgeMsgEnvelope env;
	fudge_byte *ptrBuffer;
	fudge_i32 cbBuffer;
	if ((status = FudgeMsgEnvelope_create (&env, cProcessingDirectives, 0, 0, msg)) != FUDGE_OK) {
		LOGWARN (TEXT ("Couldn't create message envelope, status ") << status);
		return false;
	}
	status = FudgeCodec_encodeMsg (env, &ptrBuffer, &cbBuffer);
	FudgeMsgEnvelope_release (env);
	if (status != FUDGE_OK) {
		LOGWARN (TEXT ("Couldn't encode message, status ") << status);
		return false;
	}
	bool bResult;
	if (m_oPipesSemaphore.Wait (m_lSendTimeout)) {
		if (m_poPipes && m_poPipes->IsConnected ()) {
			int nPoll = 0;
			long lStartTime = GetTickCount ();
retrySend:
			if (m_poPipes->Write (ptrBuffer, cbBuffer, m_lSendTimeout)) {
				bResult = true;
			} else {
				int ec = GetLastError ();
#ifdef _WIN32
				if (ec == ERROR_PIPE_LISTENING) {
					// No process at the other end of the pipe
#else
				if (ec == EPIPE) {
					// Broken pipe -- they start off broken the way we create them
#endif
					if (GetTickCount () - lStartTime >= m_lSendTimeout) {
						LOGWARN (TEXT ("Timeout exceeded waiting for other end of the pipe"));
						ec = ETIMEDOUT;
					} else if (IsFirstConnection ()) {
						LOGDEBUG (TEXT ("No process at the other end of the pipe"));
						if (m_poJVM->IsAlive ()) {
							LOGDEBUG (TEXT ("Waiting for JVM"));
							if (!nPoll) {
								CSettings oSettings;
								nPoll = oSettings.GetServicePoll ();
							}
							CThread::Sleep (nPoll);
							goto retrySend;
						} else {
							LOGERROR (TEXT ("JVM service terminated before connecting to pipes, error ") << ec);
						}
					} else {
#ifdef _WIN32
						LOGFATAL (TEXT ("Not first connection but ERROR_PIPE_LISTENING returned"));
						assert (0);
#endif /* ifdef _WIN32 */
						LOGWARN (TEXT ("Couldn't write message, error ") << ec << TEXT (", rewritten to ENOTCONN"));
						ec = ENOTCONN;
					}
				} else {
					LOGWARN (TEXT ("Couldn't write message, error ") << ec);
				}
				SetLastError (ec);
				m_poPipes->Disconnected ();
				bResult = false;
			}
		} else {
			LOGWARN (TEXT ("Pipes not available for message"));
			bResult = false;
			SetLastError (ENOTCONN);
		}
		m_oPipesSemaphore.Signal ();
	} else {