FIX Antenna ANSI C  2.18.0
 All Data Structures Variables Pages
Quick Start

These chapters describe the creation of a simple application step-by step with samples.

Follow these instructions to get it to work:

Engine initialization

Execute the following instruction to initialize FIX engine.

// Initializes engine.
B2BITS_FixEngine_Init("",-1, "","");

The engine.properties file is required to read the engine configuration parameters. It must, by default, be present in the current directory. If the file is located elsewhere or has a different name specify the properties file name and path explicitly.

// Initializes engine.
B2BITS_FixEngine_Init("engine.properties", -1, "", "");

If an error occurs during initialization (the properties file is not found, a required property is missing etc.) function returns B2BITS_FALSE. Use B2BITS_GetLastErrorDescription to get description.

// Initializes engine.
if( B2BITS_FixEngine_Init("",-1, "","") == B2BITS_FALSE )
{
printf("ERROR: %s", B2BITS_GetLastErrorDescription());
}

Session acceptor creation

You can create a session acceptor in three steps:

// Create Application instance - FIX session observer
// init function pointers with call-back functions.
app.Process = &App_Process;
app.OnLogonEvent = &App_OnLogonEvent;
app.OnLogoutEvent = &App_OnLogoutEvent;
app.OnHeartbeatWithTestReqIDEvent = &App_OnHeartbeatWithTestReqIDEvent;
// Create FIX session instance
pSA = B2BITS_FixEngine_CreateSession(
&app,
&acceptorCtx,
"Sender",
"Target",
B2BITS_FIX44,
0,
B2BITS_transient_storageType,
B2BITS_FIX_TCP);
if(!pSA)
{
printf( "Error: %s\n", B2BITS_GetLastErrorDescription() );
return 1;
}
// Connect session as acceptor
B2BITS_Session_ConnectAcceptor(pSA, B2BITS_EM_NONE);

Session initiator creation

You can create a session initiator in three steps:

// Create Application instance - FIX session observer
// init function pointers with call-back functions.
app.Process = &App_Process;
app.OnLogonEvent = &App_OnLogonEvent;
app.OnLogoutEvent = &App_OnLogoutEvent;
app.OnHeartbeatWithTestReqIDEvent = &App_OnHeartbeatWithTestReqIDEvent;
// Create FIX session instance
pSI = B2BITS_FixEngine_CreateSession(
&app,
&initiatorCtx,
"Target",
"Sender",
B2BITS_FIX44,
0,
B2BITS_transient_storageType,
B2BITS_FIX_TCP
);
if(!pSI)
{
printf( "Error: %s\n", B2BITS_GetLastErrorDescription() );
return 1;
}
// Connect session as initiator
B2BITS_Session_ConnectInitiator(pSI,30, "127.0.0.1", 9105, B2BITS_EM_NONE, 0, B2BITS_AC_PRIMARY_CONNECTION);

Creating new order

FIX Antenna provides interface for FIX messages manipulations:

// create FIX 4.4 New Order Single
order = B2BITS_FIXMsgFactory_NewSkel(B2BITS_FIX44, "D", B2BITS_NA);
B2BITS_FIXMessage_SetAsCString(order, B2BITS_FIXField_ClOrdID, "USR20000101");

Sending order

A message is sent asynchronously by calling the B2BITS_Session_Put function. Consequently the message is scheduled for sending in the internal queue and sent in a separate thread. This means that if the method returns "controld" the message is not necessarily already sent.

// Send order to session initiator
B2BITS_Session_Put(pSI, order, 0);
// Send order to session acceptor
B2BITS_Session_Put(pSA, order, 0);

Processing incoming message

The Application type is responsible for:

Create an instance of the B2BITS_Application type, and init the B2BITS_Application::Process function pointer to process incoming messages. If an incoming message is successfully processed, the method will return "true", if the message cannot be processed at the moment, it will return "false".

If the B2BITS_Application::Process method does not return "true", the FIX engine will try to deliver the first unprocessed message a specified number of times (DelayedProcessing.MaxDeliveryTries) in the interval, specified in the FE configuration (DelayedProcessing.DeliveryTriesInterval). If the number of unsuccessful attempts exceeds the MaxDeliveryTries, a Logout message with "Application is not available" cause indication will be sent back.

It is also necessary to init the OnLogonEvent, OnLogoutEvent, OnSequenceGapEvent, OnSessionLevelRejectEvent and other function pointers. These are the call-back methods called to notify about the corresponding session-level events.

The B2BITS_Application::Process method is called only when an incoming application-level message or a Reject message is delivered. All other session-level messages are handled inside the FE.

For example:

int __stdcall App_Process(void* context, B2BITS_FIXMessage msg, B2BITS_Session sn, char const** rejectText)
{
return 1;
}
void __stdcall App_OnLogonEvent(void* context, const B2BITS_LogonEvent* event, B2BITS_Session sn)
{
return;
}
void __stdcall App_OnLogoutEvent(void* context, const B2BITS_LogoutEvent* event, B2BITS_Session sn)
{
return;
}
void __stdcall App_OnHeartbeatWithTestReqIDEvent(void* context, const B2BITS_HeartbeatWithTestReqIDEvent* event, B2BITS_Session sn)
{
return;
}
// Create Application instance
memset(&app, 0, sizeof(app));
app.Process = &App_Process;
app.OnLogonEvent = &App_OnLogonEvent;
app.OnLogoutEvent = &App_OnLogoutEvent;
app.OnHeartbeatWithTestReqIDEvent = &App_OnHeartbeatWithTestReqIDEvent;

Note: The B2BITS_Application::Process method must not be dead-locked or perform time-demanding operations.

Note: If a pointer to the same B2BITS_Application is transmitted to several sessions, being established, synchronize the B2BITS_Application::Process() method.

Warning: Do not delete the registered Application until you unregister it.

Closing session

Use the following method to close the session:

Sample application

The sample below illustrates all abovementioned instructions combined in one application.

#include <stdio.h>
#include <string.h>
#include "B2BITS_C_FixEngine.h"
typedef struct tagSessionContext
{
volatile int processEvent;
volatile int logoutEvent;
char const* name_;
} SessionContext;
int __stdcall App_Process(void* context, B2BITS_FIXMessage msg, B2BITS_Session sn, char const** rejectText)
{
int size;
const char* str;
printf( "%s: App_Process\n", ((SessionContext*)context)->name_ );
str = B2BITS_FIXMessage_ToRaw(msg, &size);
printf("%.*s", size, str);
((SessionContext*)context)->processEvent = 1;
return 0;
}
void __stdcall App_OnLogonEvent(void* context, const B2BITS_LogonEvent* event, B2BITS_Session sn)
{
printf( "%s: App_OnLogonEvent\n", ((SessionContext*)context)->name_ );
return;
}
void __stdcall App_OnLogoutEvent(void* context, const B2BITS_LogoutEvent* event, B2BITS_Session sn)
{
printf( "%s: App_OnLogoutEvent\n", ((SessionContext*)context)->name_ );
((SessionContext*)context)->logoutEvent = 1;
return;
}
void __stdcall App_OnHeartbeatWithTestReqIDEvent(void* context, const B2BITS_HeartbeatWithTestReqIDEvent* event, B2BITS_Session sn)
{
printf( "App_OnHeartbeatWithTestReqIDEvent\n" );
return;
}
int main(int argc, char* argv[])
{
SessionContext acceptorCtx;
SessionContext initiatorCtx;
// Initialize engine.
if( B2BITS_TRUE != B2BITS_FixEngine_Init("",-1,"","") )
{
printf( "Error: %s\n", B2BITS_GetLastErrorDescription() );
return 1;
}
// Create Application instance
memset(&app, 0, sizeof(app));
app.Process = &App_Process;
app.OnLogonEvent = &App_OnLogonEvent;
app.OnLogoutEvent = &App_OnLogoutEvent;
app.OnHeartbeatWithTestReqIDEvent = &App_OnHeartbeatWithTestReqIDEvent;
memset(&acceptorCtx, 0, sizeof(acceptorCtx));
acceptorCtx.name_ = "Acceptor";
memset(&initiatorCtx, 0, sizeof(initiatorCtx));
initiatorCtx.name_ = "Initiator";
// Create FIX session instance
pSA = B2BITS_FixEngine_CreateSession(
&app,
&acceptorCtx,
"Sender",
"Target",
B2BITS_FIX44,
0,
B2BITS_transient_storageType,
B2BITS_FIX_TCP);
if(!pSA)
{
printf( "Error: %s\n", B2BITS_GetLastErrorDescription() );
return 1;
}
// Connect session as acceptor
B2BITS_Session_ConnectAcceptor(pSA, B2BITS_EM_NONE);
// Create FIX session instance
pSI = B2BITS_FixEngine_CreateSession(
&app,
&initiatorCtx,
"Target",
"Sender",
B2BITS_FIX44,
0,
B2BITS_transient_storageType,
B2BITS_FIX_TCP
);
if(!pSI)
{
printf( "Error: %s\n", B2BITS_GetLastErrorDescription() );
return 1;
}
// Connect session as initiator
B2BITS_Session_ConnectInitiator(pSI,30, "127.0.0.1", 9105, B2BITS_EM_NONE, 0, B2BITS_AC_PRIMARY_CONNECTION);
// create FIX 4.4 New Order Single
order = B2BITS_FIXMsgFactory_NewSkel(B2BITS_FIX44, "D", B2BITS_NA);
B2BITS_FIXMessage_SetAsCString(order, B2BITS_FIXField_ClOrdID, "USR20000101");
B2BITS_FIXMessage_SetAsCString(order, B2BITS_FIXField_HandlInst, "2");
B2BITS_FIXMessage_SetAsCString(order, B2BITS_FIXField_Symbol, "IBM");
B2BITS_FIXMessage_SetAsCString(order, B2BITS_FIXField_OrderQty, "200");
B2BITS_FIXMessage_SetAsCString(order, B2BITS_FIXField_Side, "1");
B2BITS_FIXMessage_SetAsCString(order, B2BITS_FIXField_OrdType, "5");
B2BITS_FIXMessage_SetAsCString(order, B2BITS_FIXField_TimeInForce, "0");
// Send order to session initiator
B2BITS_Session_Put(pSI, order, 0);
while(0 == acceptorCtx.processEvent);
// release resources
B2BITS_FIXMessage_Release(order);
// Close sessions
B2BITS_Session_Disconnect(pSI, 0);
while(0 == initiatorCtx.logoutEvent);
while(0 == acceptorCtx.logoutEvent);
B2BITS_Session_RegisterApplication(pSI, NULL, NULL, 1, 0);
B2BITS_Session_Release(pSI);
B2BITS_Session_RegisterApplication(pSA, NULL, NULL, 1, 0);
B2BITS_Session_Release(pSA);
B2BITS_FixEngine_Destroy();
printf("Application shutdown.");
return 0;
}