Adding a conversation module

To add a new conversation module, create a new instance of the conversation module interface (asr_conversation_if), which provides the communication mechanism between your new module and ASR. You must implement the following callback functions, which ASR invokes via the conversation module interface:

Modules are loaded as DLLs at runtime. You must define a constructor function (designated with the ((constructor)) compiler attribute) that is called when ASR loads your module. This constructor function must call asrm_connect() to connect to io-asr and obtain your module's handle. The following code fragment illustrates this procedure for the dialer module:
typedef struct CarDialer_data_s {
    asr_module_hdl_t*    handle ;
    ...
}CarDialer_data _dialer_data ;

static const asr_conversation_if_t
CarDialer_interface = {
    .name           = "dialer",
    .asr_version    = ASR_VERSION,
    .init           = CarDialer_init,
    .destroy        = CarDialer_destroy,
    .on_asr_step    = CarDialer_step,
    .select_result  = CarDialer_selectResult,
    .on_result      = CarDialer_onResult,
} ;

__attribute__((constructor))
static void
CarDialer_register( void )
{
    CarDialer_data* self = &_dialer_data ;
    asr_module_hdl_t* module_handle ;

    memset( self, 0, sizeof( *self ) ) ;
    module_handle = asrm_connect( &CarDialer_interface, sizeof( CarDialer_interface ), self ) ;
    if ( self && module_handle ) {
            self->handle = module_handle ;
}
}
Note: In this example, the self data pointer is associated with the module. The io-asr service passes this pointer to all the module's callbacks as void* arguments. The pointer is then cast to the proper structure type to provide access to the module-specific data.

When ASR unloads the conversation module, it calls the module's destroy() callback function. This function should clean up any resources that were allocated in the init() function.